From ba2197182d05c8376df58e430cc8dd2d60edef7a Mon Sep 17 00:00:00 2001 From: dloughlin Date: Tue, 14 Mar 2023 20:24:21 +0100 Subject: [PATCH 001/119] Implement delete visit --- .../rumbledb/compiler/TranslationVisitor.java | 47 +++++++++++++++++++ .../expressions/update/DeleteExpression.java | 4 ++ src/main/java/org/rumbledb/parser/Jsoniq.g4 | 21 +++++++++ 3 files changed, 72 insertions(+) create mode 100644 src/main/java/org/rumbledb/expressions/update/DeleteExpression.java diff --git a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java index a9a9799115..20c53696bf 100644 --- a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java @@ -1119,6 +1119,53 @@ public Node visitValidateExpr(JsoniqParser.ValidateExprContext ctx) { } // endregion + // region update + + @Override + public Node visitInsertExpr(JsoniqParser.InsertExprContext ctx) { + return super.visitInsertExpr(ctx); + } + + @Override + public Node visitDeleteExpr(JsoniqParser.DeleteExprContext ctx) { + Expression mainExpression = (Expression) this.visitPrimaryExpr(ctx.main_expr); + Expression finalExpr = (Expression) this.visitExprSingle(ctx.exprSingle(ctx.exprSingle().size() - 1)); + List locExprs = new ArrayList<>(); + for (int i = 0; i < ctx.exprSingle().size() - 1; i++) { + JsoniqParser.ExprSingleContext locExprCtx = ctx.exprSingle(i); + Expression locExpr = (Expression) this.visitExprSingle(locExprCtx); + locExprs.add(locExpr); + } + mainExpression = new DynamicFunctionCallExpression( + mainExpression, + locExprs, + createMetadataFromContext(ctx) + ); + return super.visitDeleteExpr(ctx); + } + + @Override + public Node visitRenameExpr(JsoniqParser.RenameExprContext ctx) { + return super.visitRenameExpr(ctx); + } + + @Override + public Node visitReplaceExpr(JsoniqParser.ReplaceExprContext ctx) { + return super.visitReplaceExpr(ctx); + } + + @Override + public Node visitTransformExpr(JsoniqParser.TransformExprContext ctx) { + return super.visitTransformExpr(ctx); + } + + @Override + public Node visitAppendExpr(JsoniqParser.AppendExprContext ctx) { + return super.visitAppendExpr(ctx); + } + + // endregion + // region postfix @Override public Node visitPostFixExpr(JsoniqParser.PostFixExprContext ctx) { diff --git a/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java b/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java new file mode 100644 index 0000000000..b19b10441b --- /dev/null +++ b/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java @@ -0,0 +1,4 @@ +package org.rumbledb.expressions.update; + +public class DeleteExpression { +} diff --git a/src/main/java/org/rumbledb/parser/Jsoniq.g4 b/src/main/java/org/rumbledb/parser/Jsoniq.g4 index fb072ec619..57959cf756 100644 --- a/src/main/java/org/rumbledb/parser/Jsoniq.g4 +++ b/src/main/java/org/rumbledb/parser/Jsoniq.g4 @@ -83,6 +83,12 @@ exprSingle : flowrExpr | typeSwitchExpr | ifExpr | tryCatchExpr + | insertExpr + | deleteExpr + | renameExpr + | replaceExpr + | transformExpr + | appendExpr | orExpr; flowrExpr : (start_for=forClause| start_let=letClause) @@ -234,6 +240,21 @@ inlineFunctionExpr : 'function' '(' paramList? ')' (Kas return_type=sequenceType)? ('{' (fn_body=expr)? '}'); +///////////////////////// Updating Expressions + +insertExpr : 'insert' 'json' exprSingle 'into' exprSingle ('at' 'position' exprSingle)? + | 'insert' 'json' pairConstructor ( ',' pairConstructor )* 'into' exprSingle; + +deleteExpr : 'delete' 'json' main_expr=primaryExpr ( '(' exprSingle ')' )+; + +renameExpr : 'rename' 'json' main_expr=primaryExpr ( '(' exprSingle ')' )+ 'as' exprSingle; + +replaceExpr : 'replace' 'json' 'value' 'of' main_expr=primaryExpr ( '(' exprSingle ')' )+ 'with' exprSingle; + +transformExpr : 'transform'; + +appendExpr : 'append' 'json' exprSingle 'into' exprSingle; + ///////////////////////// Types sequenceType : '(' ')' From 3133a92308ba212d080b579166b87275201cc31f Mon Sep 17 00:00:00 2001 From: dloughlin Date: Wed, 15 Mar 2023 00:06:24 +0100 Subject: [PATCH 002/119] Implement simple delete visitor and expression class --- .../rumbledb/compiler/TranslationVisitor.java | 20 ++++++- .../expressions/AbstractNodeVisitor.java | 9 +++ .../expressions/update/DeleteExpression.java | 55 ++++++++++++++++++- src/main/java/org/rumbledb/parser/Jsoniq.g4 | 12 ++-- 4 files changed, 87 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java index 20c53696bf..4482db7e07 100644 --- a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java @@ -123,6 +123,7 @@ import org.rumbledb.expressions.typing.IsStaticallyExpression; import org.rumbledb.expressions.typing.TreatExpression; import org.rumbledb.expressions.typing.ValidateTypeExpression; +import org.rumbledb.expressions.update.DeleteExpression; import org.rumbledb.items.parsing.ItemParser; import org.rumbledb.parser.JsoniqParser; import org.rumbledb.parser.JsoniqParser.DefaultCollationDeclContext; @@ -561,6 +562,21 @@ public Node visitExprSingle(JsoniqParser.ExprSingleContext ctx) { if (content instanceof JsoniqParser.TryCatchExprContext) { return this.visitTryCatchExpr((JsoniqParser.TryCatchExprContext) content); } + if (content instanceof JsoniqParser.DeleteExprContext) { + return this.visitDeleteExpr((JsoniqParser.DeleteExprContext) content); + } + if (content instanceof JsoniqParser.InsertExprContext) { + return this.visitInsertExpr((JsoniqParser.InsertExprContext) content); + } + if (content instanceof JsoniqParser.ReplaceExprContext) { + return this.visitReplaceExpr((JsoniqParser.ReplaceExprContext) content); + } + if (content instanceof JsoniqParser.RenameExprContext) { + return this.visitRenameExpr((JsoniqParser.RenameExprContext) content); + } + if (content instanceof JsoniqParser.AppendExprContext) { + return this.visitAppendExpr((JsoniqParser.AppendExprContext) content); + } throw new OurBadException("Unrecognized ExprSingle."); } // endregion @@ -1129,7 +1145,7 @@ public Node visitInsertExpr(JsoniqParser.InsertExprContext ctx) { @Override public Node visitDeleteExpr(JsoniqParser.DeleteExprContext ctx) { Expression mainExpression = (Expression) this.visitPrimaryExpr(ctx.main_expr); - Expression finalExpr = (Expression) this.visitExprSingle(ctx.exprSingle(ctx.exprSingle().size() - 1)); + Expression finalExpression = (Expression) this.visitExprSingle(ctx.exprSingle(ctx.exprSingle().size() - 1)); List locExprs = new ArrayList<>(); for (int i = 0; i < ctx.exprSingle().size() - 1; i++) { JsoniqParser.ExprSingleContext locExprCtx = ctx.exprSingle(i); @@ -1141,7 +1157,7 @@ public Node visitDeleteExpr(JsoniqParser.DeleteExprContext ctx) { locExprs, createMetadataFromContext(ctx) ); - return super.visitDeleteExpr(ctx); + return new DeleteExpression(mainExpression, finalExpression, createMetadataFromContext(ctx)); } @Override diff --git a/src/main/java/org/rumbledb/expressions/AbstractNodeVisitor.java b/src/main/java/org/rumbledb/expressions/AbstractNodeVisitor.java index 8b0ea5894d..5835f6c46a 100644 --- a/src/main/java/org/rumbledb/expressions/AbstractNodeVisitor.java +++ b/src/main/java/org/rumbledb/expressions/AbstractNodeVisitor.java @@ -67,6 +67,7 @@ import org.rumbledb.expressions.primary.StringLiteralExpression; import org.rumbledb.expressions.primary.VariableReferenceExpression; import org.rumbledb.expressions.typing.*; +import org.rumbledb.expressions.update.DeleteExpression; public abstract class AbstractNodeVisitor { @@ -279,6 +280,14 @@ public T visitCastExpression(CastExpression expression, T argument) { } // endregion + // region update + + public T visitDeleteExpression(DeleteExpression expression, T argument) { + return defaultAction(expression, argument); + } + + // endregion + // region control public T visitConditionalExpression(ConditionalExpression expression, T argument) { return defaultAction(expression, argument); diff --git a/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java b/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java index b19b10441b..876882a888 100644 --- a/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java @@ -1,4 +1,57 @@ package org.rumbledb.expressions.update; -public class DeleteExpression { +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.exceptions.OurBadException; +import org.rumbledb.expressions.AbstractNodeVisitor; +import org.rumbledb.expressions.Expression; +import org.rumbledb.expressions.Node; + +import java.util.Arrays; +import java.util.List; + +public class DeleteExpression extends Expression { + + private Expression mainExpression; + private Expression finalExpression; + public DeleteExpression(Expression mainExpression, + Expression finalExpression, + ExceptionMetadata metadata + ) { + super(metadata); + if (mainExpression == null) { + throw new OurBadException("Main expression cannot be null in a delete expression."); + } + if (finalExpression == null) { + throw new OurBadException("Final expression cannot be null in a delete expression."); + } + this.mainExpression = mainExpression; + this.finalExpression = finalExpression; + } + + @Override + public List getChildren() { + return Arrays.asList(this.mainExpression, this.finalExpression); + } + + public Expression getMainExpression() { + return mainExpression; + } + + public Expression getFinalExpression() { + return finalExpression; + } + + @Override + public T accept(AbstractNodeVisitor visitor, T argument) { + return visitor.visitDeleteExpression(this, argument); + } + + @Override + public void serializeToJSONiq(StringBuffer sb, int indent) { + indentIt(sb, indent); + this.mainExpression.serializeToJSONiq(sb, 0); + sb.append("("); + this.finalExpression.serializeToJSONiq(sb,0); + sb.append(")\n"); + } } diff --git a/src/main/java/org/rumbledb/parser/Jsoniq.g4 b/src/main/java/org/rumbledb/parser/Jsoniq.g4 index 57959cf756..8bead6a307 100644 --- a/src/main/java/org/rumbledb/parser/Jsoniq.g4 +++ b/src/main/java/org/rumbledb/parser/Jsoniq.g4 @@ -242,18 +242,18 @@ inlineFunctionExpr : 'function' '(' paramList? ')' ///////////////////////// Updating Expressions -insertExpr : 'insert' 'json' exprSingle 'into' exprSingle ('at' 'position' exprSingle)? - | 'insert' 'json' pairConstructor ( ',' pairConstructor )* 'into' exprSingle; +insertExpr : 'insert' exprSingle 'into' exprSingle ('at' 'position' exprSingle)? + | 'insert' pairConstructor ( ',' pairConstructor )* 'into' exprSingle; -deleteExpr : 'delete' 'json' main_expr=primaryExpr ( '(' exprSingle ')' )+; +deleteExpr : 'delete' main_expr=primaryExpr ( '(' exprSingle ')' )+; -renameExpr : 'rename' 'json' main_expr=primaryExpr ( '(' exprSingle ')' )+ 'as' exprSingle; +renameExpr : 'rename' main_expr=primaryExpr ( '(' exprSingle ')' )+ 'as' exprSingle; -replaceExpr : 'replace' 'json' 'value' 'of' main_expr=primaryExpr ( '(' exprSingle ')' )+ 'with' exprSingle; +replaceExpr : 'replace' 'value' 'of' main_expr=primaryExpr ( '(' exprSingle ')' )+ 'with' exprSingle; transformExpr : 'transform'; -appendExpr : 'append' 'json' exprSingle 'into' exprSingle; +appendExpr : 'append' exprSingle 'into' exprSingle; ///////////////////////// Types From 9062cfeb49cffb68155196c419c36a7917162fbc Mon Sep 17 00:00:00 2001 From: dloughlin Date: Wed, 15 Mar 2023 00:26:18 +0100 Subject: [PATCH 003/119] Refactor common update locator grammar and visitor --- .../rumbledb/compiler/TranslationVisitor.java | 37 ++++++++++++------- .../expressions/update/AppendExpression.java | 2 + .../expressions/update/InsertExpression.java | 2 + .../expressions/update/RenameExpression.java | 2 + .../expressions/update/ReplaceExpression.java | 2 + src/main/java/org/rumbledb/parser/Jsoniq.g4 | 8 ++-- 6 files changed, 37 insertions(+), 16 deletions(-) create mode 100644 src/main/java/org/rumbledb/expressions/update/AppendExpression.java create mode 100644 src/main/java/org/rumbledb/expressions/update/InsertExpression.java create mode 100644 src/main/java/org/rumbledb/expressions/update/RenameExpression.java create mode 100644 src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java diff --git a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java index 4482db7e07..46b617f0a2 100644 --- a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java @@ -1144,24 +1144,15 @@ public Node visitInsertExpr(JsoniqParser.InsertExprContext ctx) { @Override public Node visitDeleteExpr(JsoniqParser.DeleteExprContext ctx) { - Expression mainExpression = (Expression) this.visitPrimaryExpr(ctx.main_expr); - Expression finalExpression = (Expression) this.visitExprSingle(ctx.exprSingle(ctx.exprSingle().size() - 1)); - List locExprs = new ArrayList<>(); - for (int i = 0; i < ctx.exprSingle().size() - 1; i++) { - JsoniqParser.ExprSingleContext locExprCtx = ctx.exprSingle(i); - Expression locExpr = (Expression) this.visitExprSingle(locExprCtx); - locExprs.add(locExpr); - } - mainExpression = new DynamicFunctionCallExpression( - mainExpression, - locExprs, - createMetadataFromContext(ctx) - ); + Expression mainExpression = getMainExpressionFromUpdateLocatorContext(ctx.updateLocator()); + Expression finalExpression = getFinalExpressionFromUpdateLocatorContext(ctx.updateLocator()); return new DeleteExpression(mainExpression, finalExpression, createMetadataFromContext(ctx)); } @Override public Node visitRenameExpr(JsoniqParser.RenameExprContext ctx) { + Expression mainExpression = getMainExpressionFromUpdateLocatorContext(ctx.updateLocator()); + Expression finalExpression = getFinalExpressionFromUpdateLocatorContext(ctx.updateLocator()); return super.visitRenameExpr(ctx); } @@ -1180,6 +1171,26 @@ public Node visitAppendExpr(JsoniqParser.AppendExprContext ctx) { return super.visitAppendExpr(ctx); } + public Expression getMainExpressionFromUpdateLocatorContext(JsoniqParser.UpdateLocatorContext ctx) { + Expression mainExpression = (Expression) this.visitPrimaryExpr(ctx.main_expr); + List locExprs = new ArrayList<>(); + for (int i = 0; i < ctx.exprSingle().size() - 1; i++) { + JsoniqParser.ExprSingleContext locExprCtx = ctx.exprSingle(i); + Expression locExpr = (Expression) this.visitExprSingle(locExprCtx); + locExprs.add(locExpr); + } + mainExpression = new DynamicFunctionCallExpression( + mainExpression, + locExprs, + createMetadataFromContext(ctx) + ); + return mainExpression; + } + + public Expression getFinalExpressionFromUpdateLocatorContext(JsoniqParser.UpdateLocatorContext ctx) { + return (Expression) this.visitExprSingle(ctx.exprSingle(ctx.exprSingle().size() - 1)); + } + // endregion // region postfix diff --git a/src/main/java/org/rumbledb/expressions/update/AppendExpression.java b/src/main/java/org/rumbledb/expressions/update/AppendExpression.java new file mode 100644 index 0000000000..775ccbc8b9 --- /dev/null +++ b/src/main/java/org/rumbledb/expressions/update/AppendExpression.java @@ -0,0 +1,2 @@ +package org.rumbledb.expressions.update;public class AppendExpression { +} diff --git a/src/main/java/org/rumbledb/expressions/update/InsertExpression.java b/src/main/java/org/rumbledb/expressions/update/InsertExpression.java new file mode 100644 index 0000000000..8e9991f4f7 --- /dev/null +++ b/src/main/java/org/rumbledb/expressions/update/InsertExpression.java @@ -0,0 +1,2 @@ +package org.rumbledb.expressions.update;public class InsertExpression { +} diff --git a/src/main/java/org/rumbledb/expressions/update/RenameExpression.java b/src/main/java/org/rumbledb/expressions/update/RenameExpression.java new file mode 100644 index 0000000000..b2fdada9d8 --- /dev/null +++ b/src/main/java/org/rumbledb/expressions/update/RenameExpression.java @@ -0,0 +1,2 @@ +package org.rumbledb.expressions.update;public class RenameExpression { +} diff --git a/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java b/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java new file mode 100644 index 0000000000..b923593d1f --- /dev/null +++ b/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java @@ -0,0 +1,2 @@ +package org.rumbledb.expressions.update;public class ReplaceExpression { +} diff --git a/src/main/java/org/rumbledb/parser/Jsoniq.g4 b/src/main/java/org/rumbledb/parser/Jsoniq.g4 index 8bead6a307..f4ef07d3b5 100644 --- a/src/main/java/org/rumbledb/parser/Jsoniq.g4 +++ b/src/main/java/org/rumbledb/parser/Jsoniq.g4 @@ -245,16 +245,18 @@ inlineFunctionExpr : 'function' '(' paramList? ')' insertExpr : 'insert' exprSingle 'into' exprSingle ('at' 'position' exprSingle)? | 'insert' pairConstructor ( ',' pairConstructor )* 'into' exprSingle; -deleteExpr : 'delete' main_expr=primaryExpr ( '(' exprSingle ')' )+; +deleteExpr : 'delete' updateLocator; -renameExpr : 'rename' main_expr=primaryExpr ( '(' exprSingle ')' )+ 'as' exprSingle; +renameExpr : 'rename' updateLocator 'as' name_expr=exprSingle; -replaceExpr : 'replace' 'value' 'of' main_expr=primaryExpr ( '(' exprSingle ')' )+ 'with' exprSingle; +replaceExpr : 'replace' 'value' 'of' updateLocator 'with' new_expr=exprSingle; transformExpr : 'transform'; appendExpr : 'append' exprSingle 'into' exprSingle; +updateLocator : main_expr=primaryExpr ( '(' exprSingle ')' )+; + ///////////////////////// Types sequenceType : '(' ')' From fc4038ec7ffbf79e6fb337bab63abf9d7c1a62e2 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Wed, 15 Mar 2023 00:39:28 +0100 Subject: [PATCH 004/119] Set up update expression classes and defaultAction method in AbstractNodeVisitor --- .../rumbledb/compiler/TranslationVisitor.java | 4 ++ .../expressions/AbstractNodeVisitor.java | 18 ++++++- .../expressions/update/AppendExpression.java | 29 ++++++++++- .../expressions/update/InsertExpression.java | 29 ++++++++++- .../expressions/update/RenameExpression.java | 50 ++++++++++++++++++- .../expressions/update/ReplaceExpression.java | 29 ++++++++++- 6 files changed, 154 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java index 46b617f0a2..63debeb29d 100644 --- a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java @@ -1153,11 +1153,15 @@ public Node visitDeleteExpr(JsoniqParser.DeleteExprContext ctx) { public Node visitRenameExpr(JsoniqParser.RenameExprContext ctx) { Expression mainExpression = getMainExpressionFromUpdateLocatorContext(ctx.updateLocator()); Expression finalExpression = getFinalExpressionFromUpdateLocatorContext(ctx.updateLocator()); + Expression nameExpression = (Expression) this.visitExprSingle(ctx.name_expr); return super.visitRenameExpr(ctx); } @Override public Node visitReplaceExpr(JsoniqParser.ReplaceExprContext ctx) { + Expression mainExpression = getMainExpressionFromUpdateLocatorContext(ctx.updateLocator()); + Expression finalExpression = getFinalExpressionFromUpdateLocatorContext(ctx.updateLocator()); + Expression newExpression = (Expression) this.visitExprSingle(ctx.new_expr); return super.visitReplaceExpr(ctx); } diff --git a/src/main/java/org/rumbledb/expressions/AbstractNodeVisitor.java b/src/main/java/org/rumbledb/expressions/AbstractNodeVisitor.java index 5835f6c46a..a57410d901 100644 --- a/src/main/java/org/rumbledb/expressions/AbstractNodeVisitor.java +++ b/src/main/java/org/rumbledb/expressions/AbstractNodeVisitor.java @@ -67,7 +67,7 @@ import org.rumbledb.expressions.primary.StringLiteralExpression; import org.rumbledb.expressions.primary.VariableReferenceExpression; import org.rumbledb.expressions.typing.*; -import org.rumbledb.expressions.update.DeleteExpression; +import org.rumbledb.expressions.update.*; public abstract class AbstractNodeVisitor { @@ -286,6 +286,22 @@ public T visitDeleteExpression(DeleteExpression expression, T argument) { return defaultAction(expression, argument); } + public T visitRenameExpression(RenameExpression expression, T argument) { + return defaultAction(expression, argument); + } + + public T visitReplaceExpression(ReplaceExpression expression, T argument) { + return defaultAction(expression, argument); + } + + public T visitInsertExpression(InsertExpression expression, T argument) { + return defaultAction(expression, argument); + } + + public T visitAppendExpression(AppendExpression expression, T argument) { + return defaultAction(expression, argument); + } + // endregion // region control diff --git a/src/main/java/org/rumbledb/expressions/update/AppendExpression.java b/src/main/java/org/rumbledb/expressions/update/AppendExpression.java index 775ccbc8b9..e4bb2e1428 100644 --- a/src/main/java/org/rumbledb/expressions/update/AppendExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/AppendExpression.java @@ -1,2 +1,29 @@ -package org.rumbledb.expressions.update;public class AppendExpression { +package org.rumbledb.expressions.update; + +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.expressions.AbstractNodeVisitor; +import org.rumbledb.expressions.Expression; +import org.rumbledb.expressions.Node; + +import java.util.List; + +public class AppendExpression extends Expression { + protected AppendExpression(ExceptionMetadata metadata) { + super(metadata); + } + + @Override + public T accept(AbstractNodeVisitor visitor, T argument) { + return null; + } + + @Override + public List getChildren() { + return null; + } + + @Override + public void serializeToJSONiq(StringBuffer sb, int indent) { + + } } diff --git a/src/main/java/org/rumbledb/expressions/update/InsertExpression.java b/src/main/java/org/rumbledb/expressions/update/InsertExpression.java index 8e9991f4f7..e10bcfb35b 100644 --- a/src/main/java/org/rumbledb/expressions/update/InsertExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/InsertExpression.java @@ -1,2 +1,29 @@ -package org.rumbledb.expressions.update;public class InsertExpression { +package org.rumbledb.expressions.update; + +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.expressions.AbstractNodeVisitor; +import org.rumbledb.expressions.Expression; +import org.rumbledb.expressions.Node; + +import java.util.List; + +public class InsertExpression extends Expression { + protected InsertExpression(ExceptionMetadata metadata) { + super(metadata); + } + + @Override + public T accept(AbstractNodeVisitor visitor, T argument) { + return null; + } + + @Override + public List getChildren() { + return null; + } + + @Override + public void serializeToJSONiq(StringBuffer sb, int indent) { + + } } diff --git a/src/main/java/org/rumbledb/expressions/update/RenameExpression.java b/src/main/java/org/rumbledb/expressions/update/RenameExpression.java index b2fdada9d8..a066406282 100644 --- a/src/main/java/org/rumbledb/expressions/update/RenameExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/RenameExpression.java @@ -1,2 +1,50 @@ -package org.rumbledb.expressions.update;public class RenameExpression { +package org.rumbledb.expressions.update; + +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.exceptions.OurBadException; +import org.rumbledb.expressions.AbstractNodeVisitor; +import org.rumbledb.expressions.Expression; +import org.rumbledb.expressions.Node; + +import java.util.List; + +public class RenameExpression extends Expression { + + private Expression mainExpression; + private Expression finalExpression; + private Expression nameExpression; + protected RenameExpression(Expression mainExpression, + Expression finalExpression, + Expression nameExpression, + ExceptionMetadata metadata + ) { + super(metadata); + if (mainExpression == null) { + throw new OurBadException("Main expression cannot be null in a rename expression."); + } + if (finalExpression == null) { + throw new OurBadException("Final expression cannot be null in a rename expression."); + } + if (nameExpression == null) { + throw new OurBadException("Name expression cannot be null in a rename expression."); + } + this.mainExpression = mainExpression; + this.finalExpression = finalExpression; + this.nameExpression = nameExpression; + } + + @Override + public T accept(AbstractNodeVisitor visitor, T argument) { + return null; + } + + @Override + public List getChildren() { + return null; + } + + @Override + public void serializeToJSONiq(StringBuffer sb, int indent) { + + } } diff --git a/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java b/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java index b923593d1f..87ce149efc 100644 --- a/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java @@ -1,2 +1,29 @@ -package org.rumbledb.expressions.update;public class ReplaceExpression { +package org.rumbledb.expressions.update; + +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.expressions.AbstractNodeVisitor; +import org.rumbledb.expressions.Expression; +import org.rumbledb.expressions.Node; + +import java.util.List; + +public class ReplaceExpression extends Expression { + protected ReplaceExpression(ExceptionMetadata metadata) { + super(metadata); + } + + @Override + public T accept(AbstractNodeVisitor visitor, T argument) { + return null; + } + + @Override + public List getChildren() { + return null; + } + + @Override + public void serializeToJSONiq(StringBuffer sb, int indent) { + + } } From ed5ea75b982bb24346ff05711ebf55407e279b01 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Wed, 15 Mar 2023 00:48:43 +0100 Subject: [PATCH 005/119] Implement simple rename expr class and make update classes public --- .../expressions/update/AppendExpression.java | 2 +- .../expressions/update/DeleteExpression.java | 1 + .../expressions/update/InsertExpression.java | 2 +- .../expressions/update/RenameExpression.java | 15 ++++++++++++--- .../expressions/update/ReplaceExpression.java | 2 +- 5 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/rumbledb/expressions/update/AppendExpression.java b/src/main/java/org/rumbledb/expressions/update/AppendExpression.java index e4bb2e1428..236db48e57 100644 --- a/src/main/java/org/rumbledb/expressions/update/AppendExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/AppendExpression.java @@ -8,7 +8,7 @@ import java.util.List; public class AppendExpression extends Expression { - protected AppendExpression(ExceptionMetadata metadata) { + public AppendExpression(ExceptionMetadata metadata) { super(metadata); } diff --git a/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java b/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java index 876882a888..ee20189dcb 100644 --- a/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java @@ -49,6 +49,7 @@ public T accept(AbstractNodeVisitor visitor, T argument) { @Override public void serializeToJSONiq(StringBuffer sb, int indent) { indentIt(sb, indent); + sb.append("delete "); this.mainExpression.serializeToJSONiq(sb, 0); sb.append("("); this.finalExpression.serializeToJSONiq(sb,0); diff --git a/src/main/java/org/rumbledb/expressions/update/InsertExpression.java b/src/main/java/org/rumbledb/expressions/update/InsertExpression.java index e10bcfb35b..38484a45a9 100644 --- a/src/main/java/org/rumbledb/expressions/update/InsertExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/InsertExpression.java @@ -8,7 +8,7 @@ import java.util.List; public class InsertExpression extends Expression { - protected InsertExpression(ExceptionMetadata metadata) { + public InsertExpression(ExceptionMetadata metadata) { super(metadata); } diff --git a/src/main/java/org/rumbledb/expressions/update/RenameExpression.java b/src/main/java/org/rumbledb/expressions/update/RenameExpression.java index a066406282..7a0c464bd0 100644 --- a/src/main/java/org/rumbledb/expressions/update/RenameExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/RenameExpression.java @@ -6,6 +6,7 @@ import org.rumbledb.expressions.Expression; import org.rumbledb.expressions.Node; +import java.util.Arrays; import java.util.List; public class RenameExpression extends Expression { @@ -13,7 +14,7 @@ public class RenameExpression extends Expression { private Expression mainExpression; private Expression finalExpression; private Expression nameExpression; - protected RenameExpression(Expression mainExpression, + public RenameExpression(Expression mainExpression, Expression finalExpression, Expression nameExpression, ExceptionMetadata metadata @@ -35,16 +36,24 @@ protected RenameExpression(Expression mainExpression, @Override public T accept(AbstractNodeVisitor visitor, T argument) { - return null; + return visitor.visitRenameExpression(this, argument); } @Override public List getChildren() { - return null; + return Arrays.asList(this.mainExpression, this.finalExpression, this,nameExpression); } @Override public void serializeToJSONiq(StringBuffer sb, int indent) { + indentIt(sb, indent); + sb.append("rename "); + this.mainExpression.serializeToJSONiq(sb, 0); + sb.append("("); + this.finalExpression.serializeToJSONiq(sb,0); + sb.append(") as "); + this.nameExpression.serializeToJSONiq(sb,0); + sb.append("\n"); } } diff --git a/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java b/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java index 87ce149efc..1c934d8453 100644 --- a/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java @@ -8,7 +8,7 @@ import java.util.List; public class ReplaceExpression extends Expression { - protected ReplaceExpression(ExceptionMetadata metadata) { + public ReplaceExpression(ExceptionMetadata metadata) { super(metadata); } From 93d962bfedeedecfa873cdd1c0a107005ffb10fd Mon Sep 17 00:00:00 2001 From: dloughlin Date: Wed, 15 Mar 2023 00:49:14 +0100 Subject: [PATCH 006/119] Return RenameExpression from visitRenameExpr --- src/main/java/org/rumbledb/compiler/TranslationVisitor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java index 63debeb29d..3ec728b269 100644 --- a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java @@ -124,6 +124,7 @@ import org.rumbledb.expressions.typing.TreatExpression; import org.rumbledb.expressions.typing.ValidateTypeExpression; import org.rumbledb.expressions.update.DeleteExpression; +import org.rumbledb.expressions.update.RenameExpression; import org.rumbledb.items.parsing.ItemParser; import org.rumbledb.parser.JsoniqParser; import org.rumbledb.parser.JsoniqParser.DefaultCollationDeclContext; @@ -1154,7 +1155,7 @@ public Node visitRenameExpr(JsoniqParser.RenameExprContext ctx) { Expression mainExpression = getMainExpressionFromUpdateLocatorContext(ctx.updateLocator()); Expression finalExpression = getFinalExpressionFromUpdateLocatorContext(ctx.updateLocator()); Expression nameExpression = (Expression) this.visitExprSingle(ctx.name_expr); - return super.visitRenameExpr(ctx); + return new RenameExpression(mainExpression, finalExpression, nameExpression, createMetadataFromContext(ctx)); } @Override From 673a1a2e1bcd717f0489c94069678d0d25488f8b Mon Sep 17 00:00:00 2001 From: dloughlin Date: Wed, 15 Mar 2023 09:04:37 +0100 Subject: [PATCH 007/119] Fix stackoverflow bug on visit --- src/main/java/org/rumbledb/compiler/TranslationVisitor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java index 3ec728b269..f015cafcb5 100644 --- a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java @@ -125,6 +125,7 @@ import org.rumbledb.expressions.typing.ValidateTypeExpression; import org.rumbledb.expressions.update.DeleteExpression; import org.rumbledb.expressions.update.RenameExpression; +import org.rumbledb.expressions.update.ReplaceExpression; import org.rumbledb.items.parsing.ItemParser; import org.rumbledb.parser.JsoniqParser; import org.rumbledb.parser.JsoniqParser.DefaultCollationDeclContext; @@ -1163,7 +1164,7 @@ public Node visitReplaceExpr(JsoniqParser.ReplaceExprContext ctx) { Expression mainExpression = getMainExpressionFromUpdateLocatorContext(ctx.updateLocator()); Expression finalExpression = getFinalExpressionFromUpdateLocatorContext(ctx.updateLocator()); Expression newExpression = (Expression) this.visitExprSingle(ctx.new_expr); - return super.visitReplaceExpr(ctx); + return new ReplaceExpression(mainExpression, finalExpression, newExpression, createMetadataFromContext(ctx)); } @Override From 794ccabcbae88c0d38b0c7b8a3d2c91e0d1df4e6 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sat, 18 Mar 2023 23:01:10 +0100 Subject: [PATCH 008/119] Update rename and replace to account for fix --- .../expressions/update/RenameExpression.java | 20 +++++-- .../expressions/update/ReplaceExpression.java | 53 ++++++++++++++++--- 2 files changed, 63 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/rumbledb/expressions/update/RenameExpression.java b/src/main/java/org/rumbledb/expressions/update/RenameExpression.java index 7a0c464bd0..2190069a8c 100644 --- a/src/main/java/org/rumbledb/expressions/update/RenameExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/RenameExpression.java @@ -35,13 +35,25 @@ public RenameExpression(Expression mainExpression, } @Override - public T accept(AbstractNodeVisitor visitor, T argument) { - return visitor.visitRenameExpression(this, argument); + public List getChildren() { + return Arrays.asList(this.mainExpression, this.finalExpression, this.nameExpression); + } + + public Expression getMainExpression() { + return mainExpression; + } + + public Expression getFinalExpression() { + return finalExpression; + } + + public Expression getNameExpression() { + return nameExpression; } @Override - public List getChildren() { - return Arrays.asList(this.mainExpression, this.finalExpression, this,nameExpression); + public T accept(AbstractNodeVisitor visitor, T argument) { + return visitor.visitRenameExpression(this, argument); } @Override diff --git a/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java b/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java index 1c934d8453..6c58b9cb1e 100644 --- a/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java @@ -1,29 +1,70 @@ package org.rumbledb.expressions.update; import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.exceptions.OurBadException; import org.rumbledb.expressions.AbstractNodeVisitor; import org.rumbledb.expressions.Expression; import org.rumbledb.expressions.Node; +import java.util.Arrays; import java.util.List; public class ReplaceExpression extends Expression { - public ReplaceExpression(ExceptionMetadata metadata) { + + private Expression mainExpression; + private Expression finalExpression; + private Expression newExpression; + public ReplaceExpression(Expression mainExpression, + Expression finalExpression, + Expression newExpression, + ExceptionMetadata metadata + ) { super(metadata); + if (mainExpression == null) { + throw new OurBadException("Main expression cannot be null in a replace expression."); + } + if (finalExpression == null) { + throw new OurBadException("Final expression cannot be null in a replace expression."); + } + if (newExpression == null) { + throw new OurBadException("New expression cannot be null in a replace expression."); + } + this.mainExpression = mainExpression; + this.finalExpression = finalExpression; + this.newExpression = newExpression; } @Override - public T accept(AbstractNodeVisitor visitor, T argument) { - return null; + public List getChildren() { + return Arrays.asList(this.mainExpression, this.finalExpression, this.newExpression); + } + + public Expression getMainExpression() { + return mainExpression; + } + + public Expression getFinalExpression() { + return finalExpression; + } + + public Expression getNewExpression() { + return newExpression; } @Override - public List getChildren() { - return null; + public T accept(AbstractNodeVisitor visitor, T argument) { + return visitor.visitReplaceExpression(this, argument); } @Override public void serializeToJSONiq(StringBuffer sb, int indent) { - + indentIt(sb, indent); + sb.append("replace value of "); + this.mainExpression.serializeToJSONiq(sb, 0); + sb.append("("); + this.finalExpression.serializeToJSONiq(sb,0); + sb.append(") with "); + this.newExpression.serializeToJSONiq(sb,0); + sb.append("\n"); } } From a241b123c8871854c5d2419720ed2aaeb884fb9d Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sun, 19 Mar 2023 22:14:55 +0100 Subject: [PATCH 009/119] Refactor locator expressions to only be array or object lookups --- .../rumbledb/compiler/TranslationVisitor.java | 72 ++++++++++++++----- .../expressions/update/DeleteExpression.java | 35 +++++---- .../expressions/update/RenameExpression.java | 32 +++++---- .../expressions/update/ReplaceExpression.java | 33 +++++---- .../expressions/update/UpdateLocatorKind.java | 24 +++++++ src/main/java/org/rumbledb/parser/Jsoniq.g4 | 16 ++--- 6 files changed, 149 insertions(+), 63 deletions(-) create mode 100644 src/main/java/org/rumbledb/expressions/update/UpdateLocatorKind.java diff --git a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java index f015cafcb5..43303eb6c4 100644 --- a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java @@ -126,6 +126,7 @@ import org.rumbledb.expressions.update.DeleteExpression; import org.rumbledb.expressions.update.RenameExpression; import org.rumbledb.expressions.update.ReplaceExpression; +import org.rumbledb.expressions.update.UpdateLocatorKind; import org.rumbledb.items.parsing.ItemParser; import org.rumbledb.parser.JsoniqParser; import org.rumbledb.parser.JsoniqParser.DefaultCollationDeclContext; @@ -1147,24 +1148,27 @@ public Node visitInsertExpr(JsoniqParser.InsertExprContext ctx) { @Override public Node visitDeleteExpr(JsoniqParser.DeleteExprContext ctx) { Expression mainExpression = getMainExpressionFromUpdateLocatorContext(ctx.updateLocator()); - Expression finalExpression = getFinalExpressionFromUpdateLocatorContext(ctx.updateLocator()); - return new DeleteExpression(mainExpression, finalExpression, createMetadataFromContext(ctx)); + Expression locatorExpression = getLocatorExpressionFromUpdateLocatorContext(ctx.updateLocator()); + UpdateLocatorKind locatorKind = getLocatorKindFromUpdateLocatorContext(ctx.updateLocator()); + return new DeleteExpression(mainExpression, locatorExpression, locatorKind, createMetadataFromContext(ctx)); } @Override public Node visitRenameExpr(JsoniqParser.RenameExprContext ctx) { Expression mainExpression = getMainExpressionFromUpdateLocatorContext(ctx.updateLocator()); - Expression finalExpression = getFinalExpressionFromUpdateLocatorContext(ctx.updateLocator()); + Expression locatorExpression = getLocatorExpressionFromUpdateLocatorContext(ctx.updateLocator()); + UpdateLocatorKind locatorKind = getLocatorKindFromUpdateLocatorContext(ctx.updateLocator()); Expression nameExpression = (Expression) this.visitExprSingle(ctx.name_expr); - return new RenameExpression(mainExpression, finalExpression, nameExpression, createMetadataFromContext(ctx)); + return new RenameExpression(mainExpression, locatorExpression, nameExpression, locatorKind, createMetadataFromContext(ctx)); } @Override public Node visitReplaceExpr(JsoniqParser.ReplaceExprContext ctx) { Expression mainExpression = getMainExpressionFromUpdateLocatorContext(ctx.updateLocator()); - Expression finalExpression = getFinalExpressionFromUpdateLocatorContext(ctx.updateLocator()); + Expression locatorExpression = getLocatorExpressionFromUpdateLocatorContext(ctx.updateLocator()); + UpdateLocatorKind locatorKind = getLocatorKindFromUpdateLocatorContext(ctx.updateLocator()); Expression newExpression = (Expression) this.visitExprSingle(ctx.new_expr); - return new ReplaceExpression(mainExpression, finalExpression, newExpression, createMetadataFromContext(ctx)); + return new ReplaceExpression(mainExpression, locatorExpression, newExpression, locatorKind, createMetadataFromContext(ctx)); } @Override @@ -1179,22 +1183,54 @@ public Node visitAppendExpr(JsoniqParser.AppendExprContext ctx) { public Expression getMainExpressionFromUpdateLocatorContext(JsoniqParser.UpdateLocatorContext ctx) { Expression mainExpression = (Expression) this.visitPrimaryExpr(ctx.main_expr); - List locExprs = new ArrayList<>(); - for (int i = 0; i < ctx.exprSingle().size() - 1; i++) { - JsoniqParser.ExprSingleContext locExprCtx = ctx.exprSingle(i); - Expression locExpr = (Expression) this.visitExprSingle(locExprCtx); - locExprs.add(locExpr); + for (ParseTree child : ctx.children.subList(1, ctx.children.size() - 1)) { + if (child instanceof JsoniqParser.ObjectLookupContext) { + Expression expr = (Expression) this.visitObjectLookup((JsoniqParser.ObjectLookupContext) child); + mainExpression = new ObjectLookupExpression( + mainExpression, + expr, + createMetadataFromContext(ctx) + ); + } + else if (child instanceof JsoniqParser.ArrayLookupContext) { + Expression expr = (Expression) this.visitArrayLookup((JsoniqParser.ArrayLookupContext) child); + mainExpression = new ArrayLookupExpression( + mainExpression, + expr, + createMetadataFromContext(ctx) + ); + } + else { + throw new OurBadException("Unrecognized locator expression found in update expression."); + } } - mainExpression = new DynamicFunctionCallExpression( - mainExpression, - locExprs, - createMetadataFromContext(ctx) - ); return mainExpression; } - public Expression getFinalExpressionFromUpdateLocatorContext(JsoniqParser.UpdateLocatorContext ctx) { - return (Expression) this.visitExprSingle(ctx.exprSingle(ctx.exprSingle().size() - 1)); + public UpdateLocatorKind getLocatorKindFromUpdateLocatorContext(JsoniqParser.UpdateLocatorContext ctx) { + ParseTree locatorExprCtx = ctx.getChild(ctx.getChildCount() - 1); + if (locatorExprCtx instanceof JsoniqParser.ObjectLookupContext) { + return UpdateLocatorKind.OBJECT_LOOKUP; + } + if (locatorExprCtx instanceof JsoniqParser.ArrayLookupContext) { + return UpdateLocatorKind.ARRAY_LOOKUP; + } + else { + throw new OurBadException("Unrecognized locator found in update expression."); + } + } + + public Expression getLocatorExpressionFromUpdateLocatorContext(JsoniqParser.UpdateLocatorContext ctx) { + ParseTree locatorExprCtx = ctx.getChild(ctx.getChildCount() - 1); + if (locatorExprCtx instanceof JsoniqParser.ObjectLookupContext) { + return (Expression) this.visitObjectLookup((JsoniqParser.ObjectLookupContext) locatorExprCtx); + } + if (locatorExprCtx instanceof JsoniqParser.ArrayLookupContext) { + return (Expression) this.visitArrayLookup((JsoniqParser.ArrayLookupContext) locatorExprCtx); + } + else { + throw new OurBadException("Unrecognized locator found in update expression."); + } } // endregion diff --git a/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java b/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java index ee20189dcb..22947bbd32 100644 --- a/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java @@ -12,33 +12,43 @@ public class DeleteExpression extends Expression { private Expression mainExpression; - private Expression finalExpression; + private Expression locatorExpression; + private UpdateLocatorKind locatorKind; public DeleteExpression(Expression mainExpression, - Expression finalExpression, - ExceptionMetadata metadata + Expression locatorExpression, + UpdateLocatorKind locatorKind, + ExceptionMetadata metadata ) { super(metadata); if (mainExpression == null) { throw new OurBadException("Main expression cannot be null in a delete expression."); } - if (finalExpression == null) { - throw new OurBadException("Final expression cannot be null in a delete expression."); + if (locatorExpression == null) { + throw new OurBadException("Locator expression cannot be null in a delete expression."); + } + if (locatorKind == null) { + throw new OurBadException("Locator kind cannot be null in a delete expression."); } this.mainExpression = mainExpression; - this.finalExpression = finalExpression; + this.locatorExpression = locatorExpression; + this.locatorKind = locatorKind; } @Override public List getChildren() { - return Arrays.asList(this.mainExpression, this.finalExpression); + return Arrays.asList(this.mainExpression, this.locatorExpression); } public Expression getMainExpression() { return mainExpression; } - public Expression getFinalExpression() { - return finalExpression; + public Expression getLocatorExpression() { + return locatorExpression; + } + + public UpdateLocatorKind getLocatorKind() { + return locatorKind; } @Override @@ -49,10 +59,9 @@ public T accept(AbstractNodeVisitor visitor, T argument) { @Override public void serializeToJSONiq(StringBuffer sb, int indent) { indentIt(sb, indent); - sb.append("delete "); + sb.append("delete json "); this.mainExpression.serializeToJSONiq(sb, 0); - sb.append("("); - this.finalExpression.serializeToJSONiq(sb,0); - sb.append(")\n"); + this.locatorExpression.serializeToJSONiq(sb,0); + sb.append("\n"); } } diff --git a/src/main/java/org/rumbledb/expressions/update/RenameExpression.java b/src/main/java/org/rumbledb/expressions/update/RenameExpression.java index 2190069a8c..d55f18021d 100644 --- a/src/main/java/org/rumbledb/expressions/update/RenameExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/RenameExpression.java @@ -12,45 +12,55 @@ public class RenameExpression extends Expression { private Expression mainExpression; - private Expression finalExpression; + private Expression locatorExpression; private Expression nameExpression; + private UpdateLocatorKind locatorKind; public RenameExpression(Expression mainExpression, - Expression finalExpression, + Expression locatorExpression, Expression nameExpression, + UpdateLocatorKind locatorKind, ExceptionMetadata metadata ) { super(metadata); if (mainExpression == null) { throw new OurBadException("Main expression cannot be null in a rename expression."); } - if (finalExpression == null) { - throw new OurBadException("Final expression cannot be null in a rename expression."); + if (locatorExpression == null) { + throw new OurBadException("Locator expression cannot be null in a rename expression."); } if (nameExpression == null) { throw new OurBadException("Name expression cannot be null in a rename expression."); } + if (locatorKind == null) { + throw new OurBadException("Locator kind cannot be null in a rename expression."); + } this.mainExpression = mainExpression; - this.finalExpression = finalExpression; + this.locatorExpression = locatorExpression; this.nameExpression = nameExpression; + this.locatorKind = locatorKind; } @Override public List getChildren() { - return Arrays.asList(this.mainExpression, this.finalExpression, this.nameExpression); + return Arrays.asList(this.mainExpression, this.locatorExpression, this.nameExpression); } public Expression getMainExpression() { return mainExpression; } - public Expression getFinalExpression() { - return finalExpression; + public Expression getLocatorExpression() { + return locatorExpression; } public Expression getNameExpression() { return nameExpression; } + public UpdateLocatorKind getLocatorKind() { + return locatorKind; + } + @Override public T accept(AbstractNodeVisitor visitor, T argument) { return visitor.visitRenameExpression(this, argument); @@ -59,11 +69,9 @@ public T accept(AbstractNodeVisitor visitor, T argument) { @Override public void serializeToJSONiq(StringBuffer sb, int indent) { indentIt(sb, indent); - sb.append("rename "); + sb.append("rename json "); this.mainExpression.serializeToJSONiq(sb, 0); - sb.append("("); - this.finalExpression.serializeToJSONiq(sb,0); - sb.append(") as "); + this.locatorExpression.serializeToJSONiq(sb,0); this.nameExpression.serializeToJSONiq(sb,0); sb.append("\n"); diff --git a/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java b/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java index 6c58b9cb1e..6b41a6859d 100644 --- a/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java @@ -12,45 +12,55 @@ public class ReplaceExpression extends Expression { private Expression mainExpression; - private Expression finalExpression; + private Expression locatorExpression; private Expression newExpression; + private UpdateLocatorKind locatorKind; public ReplaceExpression(Expression mainExpression, - Expression finalExpression, + Expression locatorExpression, Expression newExpression, + UpdateLocatorKind locatorKind, ExceptionMetadata metadata ) { super(metadata); if (mainExpression == null) { throw new OurBadException("Main expression cannot be null in a replace expression."); } - if (finalExpression == null) { - throw new OurBadException("Final expression cannot be null in a replace expression."); + if (locatorExpression == null) { + throw new OurBadException("Locator expression cannot be null in a replace expression."); } if (newExpression == null) { throw new OurBadException("New expression cannot be null in a replace expression."); } + if (locatorKind == null) { + throw new OurBadException("Locator kind cannot be null in a replace expression."); + } this.mainExpression = mainExpression; - this.finalExpression = finalExpression; + this.locatorExpression = locatorExpression; this.newExpression = newExpression; + this.locatorKind = locatorKind; } @Override public List getChildren() { - return Arrays.asList(this.mainExpression, this.finalExpression, this.newExpression); + return Arrays.asList(this.mainExpression, this.locatorExpression, this.newExpression); } public Expression getMainExpression() { return mainExpression; } - public Expression getFinalExpression() { - return finalExpression; + public Expression getLocatorExpression() { + return locatorExpression; } public Expression getNewExpression() { return newExpression; } + public UpdateLocatorKind getLocatorKind() { + return locatorKind; + } + @Override public T accept(AbstractNodeVisitor visitor, T argument) { return visitor.visitReplaceExpression(this, argument); @@ -59,11 +69,10 @@ public T accept(AbstractNodeVisitor visitor, T argument) { @Override public void serializeToJSONiq(StringBuffer sb, int indent) { indentIt(sb, indent); - sb.append("replace value of "); + sb.append("replace json value of "); this.mainExpression.serializeToJSONiq(sb, 0); - sb.append("("); - this.finalExpression.serializeToJSONiq(sb,0); - sb.append(") with "); + this.locatorExpression.serializeToJSONiq(sb,0); + sb.append(" with "); this.newExpression.serializeToJSONiq(sb,0); sb.append("\n"); } diff --git a/src/main/java/org/rumbledb/expressions/update/UpdateLocatorKind.java b/src/main/java/org/rumbledb/expressions/update/UpdateLocatorKind.java new file mode 100644 index 0000000000..c59b1a6e04 --- /dev/null +++ b/src/main/java/org/rumbledb/expressions/update/UpdateLocatorKind.java @@ -0,0 +1,24 @@ +package org.rumbledb.expressions.update; + +public enum UpdateLocatorKind { + OBJECT_LOOKUP, + ARRAY_LOOKUP; + + public boolean isObjectLookup() { + return this == UpdateLocatorKind.OBJECT_LOOKUP; + } + + public boolean isArrayLookup() { + return this == UpdateLocatorKind.ARRAY_LOOKUP; + } + + public String toString() { + switch (this) { + case OBJECT_LOOKUP: + return "object_lookup"; + case ARRAY_LOOKUP: + return "array_lookup"; + } + return null; + } +} diff --git a/src/main/java/org/rumbledb/parser/Jsoniq.g4 b/src/main/java/org/rumbledb/parser/Jsoniq.g4 index f4ef07d3b5..9636b7147b 100644 --- a/src/main/java/org/rumbledb/parser/Jsoniq.g4 +++ b/src/main/java/org/rumbledb/parser/Jsoniq.g4 @@ -242,20 +242,20 @@ inlineFunctionExpr : 'function' '(' paramList? ')' ///////////////////////// Updating Expressions -insertExpr : 'insert' exprSingle 'into' exprSingle ('at' 'position' exprSingle)? - | 'insert' pairConstructor ( ',' pairConstructor )* 'into' exprSingle; +insertExpr : 'insert' 'json' exprSingle 'into' exprSingle ('at' 'position' exprSingle)? + | 'insert' 'json' pairConstructor ( ',' pairConstructor )* 'into' exprSingle; -deleteExpr : 'delete' updateLocator; +deleteExpr : 'delete' 'json' updateLocator; -renameExpr : 'rename' updateLocator 'as' name_expr=exprSingle; +renameExpr : 'rename' 'json' updateLocator 'as' name_expr=exprSingle; -replaceExpr : 'replace' 'value' 'of' updateLocator 'with' new_expr=exprSingle; +replaceExpr : 'replace' 'json' 'value' 'of' updateLocator 'with' new_expr=exprSingle; -transformExpr : 'transform'; +transformExpr : 'copy' varRef ':=' exprSingle ( ',' varRef ':=' exprSingle )* 'modify' exprSingle Kreturn exprSingle; -appendExpr : 'append' exprSingle 'into' exprSingle; +appendExpr : 'append' 'json' exprSingle 'into' exprSingle; -updateLocator : main_expr=primaryExpr ( '(' exprSingle ')' )+; +updateLocator : main_expr=primaryExpr ( arrayLookup | objectLookup )+; ///////////////////////// Types From 70072216a2fe1fc9d71f6771980d37e312055570 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sun, 19 Mar 2023 22:46:39 +0100 Subject: [PATCH 010/119] Rename replace expr vars and implement append compile class --- .../rumbledb/compiler/TranslationVisitor.java | 11 +++-- .../expressions/AbstractNodeVisitor.java | 4 ++ .../expressions/update/AppendExpression.java | 41 ++++++++++++++++--- .../expressions/update/ReplaceExpression.java | 18 ++++---- src/main/java/org/rumbledb/parser/Jsoniq.g4 | 4 +- 5 files changed, 55 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java index 43303eb6c4..73f0374666 100644 --- a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java @@ -123,10 +123,7 @@ import org.rumbledb.expressions.typing.IsStaticallyExpression; import org.rumbledb.expressions.typing.TreatExpression; import org.rumbledb.expressions.typing.ValidateTypeExpression; -import org.rumbledb.expressions.update.DeleteExpression; -import org.rumbledb.expressions.update.RenameExpression; -import org.rumbledb.expressions.update.ReplaceExpression; -import org.rumbledb.expressions.update.UpdateLocatorKind; +import org.rumbledb.expressions.update.*; import org.rumbledb.items.parsing.ItemParser; import org.rumbledb.parser.JsoniqParser; import org.rumbledb.parser.JsoniqParser.DefaultCollationDeclContext; @@ -1167,7 +1164,7 @@ public Node visitReplaceExpr(JsoniqParser.ReplaceExprContext ctx) { Expression mainExpression = getMainExpressionFromUpdateLocatorContext(ctx.updateLocator()); Expression locatorExpression = getLocatorExpressionFromUpdateLocatorContext(ctx.updateLocator()); UpdateLocatorKind locatorKind = getLocatorKindFromUpdateLocatorContext(ctx.updateLocator()); - Expression newExpression = (Expression) this.visitExprSingle(ctx.new_expr); + Expression newExpression = (Expression) this.visitExprSingle(ctx.replacer_expr); return new ReplaceExpression(mainExpression, locatorExpression, newExpression, locatorKind, createMetadataFromContext(ctx)); } @@ -1178,7 +1175,9 @@ public Node visitTransformExpr(JsoniqParser.TransformExprContext ctx) { @Override public Node visitAppendExpr(JsoniqParser.AppendExprContext ctx) { - return super.visitAppendExpr(ctx); + Expression arrayExpression = (Expression) this.visitExprSingle(ctx.array_expr); + Expression toAppendExpression = (Expression) this.visitExprSingle(ctx.to_append_expr); + return new AppendExpression(arrayExpression, toAppendExpression, createMetadataFromContext(ctx)); } public Expression getMainExpressionFromUpdateLocatorContext(JsoniqParser.UpdateLocatorContext ctx) { diff --git a/src/main/java/org/rumbledb/expressions/AbstractNodeVisitor.java b/src/main/java/org/rumbledb/expressions/AbstractNodeVisitor.java index a57410d901..be78e83acb 100644 --- a/src/main/java/org/rumbledb/expressions/AbstractNodeVisitor.java +++ b/src/main/java/org/rumbledb/expressions/AbstractNodeVisitor.java @@ -302,6 +302,10 @@ public T visitAppendExpression(AppendExpression expression, T argument) { return defaultAction(expression, argument); } + public T visitTransformExpression(AppendExpression expression, T argument) { + return defaultAction(expression, argument); + } + // endregion // region control diff --git a/src/main/java/org/rumbledb/expressions/update/AppendExpression.java b/src/main/java/org/rumbledb/expressions/update/AppendExpression.java index 236db48e57..227f24de4e 100644 --- a/src/main/java/org/rumbledb/expressions/update/AppendExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/AppendExpression.java @@ -1,29 +1,58 @@ package org.rumbledb.expressions.update; import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.exceptions.OurBadException; import org.rumbledb.expressions.AbstractNodeVisitor; import org.rumbledb.expressions.Expression; import org.rumbledb.expressions.Node; +import java.util.Arrays; import java.util.List; public class AppendExpression extends Expression { - public AppendExpression(ExceptionMetadata metadata) { + + private Expression arrayExpression; + private Expression toAppendExpression; + public AppendExpression(Expression arrayExpression, + Expression toAppendExpression, + ExceptionMetadata metadata + ) { super(metadata); + if (arrayExpression == null) { + throw new OurBadException("Array expression cannot be null in a append expression."); + } + if (toAppendExpression == null) { + throw new OurBadException("Expression to append cannot be null in a append expression."); + } + this.arrayExpression = arrayExpression; + this.toAppendExpression = toAppendExpression; } - @Override - public T accept(AbstractNodeVisitor visitor, T argument) { - return null; + public Expression getArrayExpression() { + return arrayExpression; + } + + public Expression getToAppendExpression() { + return toAppendExpression; } @Override public List getChildren() { - return null; + return Arrays.asList(this.arrayExpression, this.toAppendExpression); } @Override - public void serializeToJSONiq(StringBuffer sb, int indent) { + public T accept(AbstractNodeVisitor visitor, T argument) { + return visitor.visitAppendExpression(this, argument); + } + @Override + public void serializeToJSONiq(StringBuffer sb, int indent) { + indentIt(sb, indent); + sb.append("append json "); + this.toAppendExpression.serializeToJSONiq(sb, 0); + sb.append(" into "); + this.arrayExpression.serializeToJSONiq(sb,0); + sb.append("\n"); } } diff --git a/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java b/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java index 6b41a6859d..fd26d0c04c 100644 --- a/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java @@ -13,11 +13,11 @@ public class ReplaceExpression extends Expression { private Expression mainExpression; private Expression locatorExpression; - private Expression newExpression; + private Expression replacerExpression; private UpdateLocatorKind locatorKind; public ReplaceExpression(Expression mainExpression, Expression locatorExpression, - Expression newExpression, + Expression replacerExpression, UpdateLocatorKind locatorKind, ExceptionMetadata metadata ) { @@ -28,21 +28,21 @@ public ReplaceExpression(Expression mainExpression, if (locatorExpression == null) { throw new OurBadException("Locator expression cannot be null in a replace expression."); } - if (newExpression == null) { - throw new OurBadException("New expression cannot be null in a replace expression."); + if (replacerExpression == null) { + throw new OurBadException("New replacer expression cannot be null in a replace expression."); } if (locatorKind == null) { throw new OurBadException("Locator kind cannot be null in a replace expression."); } this.mainExpression = mainExpression; this.locatorExpression = locatorExpression; - this.newExpression = newExpression; + this.replacerExpression = replacerExpression; this.locatorKind = locatorKind; } @Override public List getChildren() { - return Arrays.asList(this.mainExpression, this.locatorExpression, this.newExpression); + return Arrays.asList(this.mainExpression, this.locatorExpression, this.replacerExpression); } public Expression getMainExpression() { @@ -53,8 +53,8 @@ public Expression getLocatorExpression() { return locatorExpression; } - public Expression getNewExpression() { - return newExpression; + public Expression getReplacerExpression() { + return replacerExpression; } public UpdateLocatorKind getLocatorKind() { @@ -73,7 +73,7 @@ public void serializeToJSONiq(StringBuffer sb, int indent) { this.mainExpression.serializeToJSONiq(sb, 0); this.locatorExpression.serializeToJSONiq(sb,0); sb.append(" with "); - this.newExpression.serializeToJSONiq(sb,0); + this.replacerExpression.serializeToJSONiq(sb,0); sb.append("\n"); } } diff --git a/src/main/java/org/rumbledb/parser/Jsoniq.g4 b/src/main/java/org/rumbledb/parser/Jsoniq.g4 index 9636b7147b..a7aef15b61 100644 --- a/src/main/java/org/rumbledb/parser/Jsoniq.g4 +++ b/src/main/java/org/rumbledb/parser/Jsoniq.g4 @@ -249,11 +249,11 @@ deleteExpr : 'delete' 'json' updateLocator; renameExpr : 'rename' 'json' updateLocator 'as' name_expr=exprSingle; -replaceExpr : 'replace' 'json' 'value' 'of' updateLocator 'with' new_expr=exprSingle; +replaceExpr : 'replace' 'json' 'value' 'of' updateLocator 'with' replacer_expr=exprSingle; transformExpr : 'copy' varRef ':=' exprSingle ( ',' varRef ':=' exprSingle )* 'modify' exprSingle Kreturn exprSingle; -appendExpr : 'append' 'json' exprSingle 'into' exprSingle; +appendExpr : 'append' 'json' to_append_expr=exprSingle 'into' array_expr=exprSingle; updateLocator : main_expr=primaryExpr ( arrayLookup | objectLookup )+; From 020b6393ac312079e5db1bc3adfa7953d2d874aa Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 20 Mar 2023 01:02:58 +0100 Subject: [PATCH 011/119] Implement simple transform expression parser --- .../rumbledb/compiler/TranslationVisitor.java | 12 +++- .../expressions/AbstractNodeVisitor.java | 6 +- .../expressions/update/CopyDeclaration.java | 56 ++++++++++++++++ .../update/TransformExpression.java | 67 +++++++++++++++++++ src/main/java/org/rumbledb/parser/Jsoniq.g4 | 8 ++- 5 files changed, 144 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/rumbledb/expressions/update/CopyDeclaration.java create mode 100644 src/main/java/org/rumbledb/expressions/update/TransformExpression.java diff --git a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java index 73f0374666..7dfc2d1734 100644 --- a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java @@ -1170,7 +1170,10 @@ public Node visitReplaceExpr(JsoniqParser.ReplaceExprContext ctx) { @Override public Node visitTransformExpr(JsoniqParser.TransformExprContext ctx) { - return super.visitTransformExpr(ctx); + List copyDecls = ctx.copyDecl().stream().map(this::visitCopyDecl).collect(Collectors.toList()); + Expression modifyExpression = (Expression) this.visitExprSingle(ctx.mod_expr); + Expression returnExpression = (Expression) this.visitExprSingle(ctx.ret_expr); + return new TransformExpression(copyDecls, modifyExpression, returnExpression, createMetadataFromContext(ctx)); } @Override @@ -1232,6 +1235,13 @@ public Expression getLocatorExpressionFromUpdateLocatorContext(JsoniqParser.Upda } } + @Override + public Node visitCopyDecl(JsoniqParser.CopyDeclContext ctx) { + Name var = ((VariableReferenceExpression) this.visitVarRef(ctx.var_ref)).getVariableName(); + Expression expr = (Expression) this.visitExprSingle(ctx.src_expr); + return new CopyDeclaration(var, expr, createMetadataFromContext(ctx)); + } + // endregion // region postfix diff --git a/src/main/java/org/rumbledb/expressions/AbstractNodeVisitor.java b/src/main/java/org/rumbledb/expressions/AbstractNodeVisitor.java index be78e83acb..c12f1fbae3 100644 --- a/src/main/java/org/rumbledb/expressions/AbstractNodeVisitor.java +++ b/src/main/java/org/rumbledb/expressions/AbstractNodeVisitor.java @@ -302,7 +302,11 @@ public T visitAppendExpression(AppendExpression expression, T argument) { return defaultAction(expression, argument); } - public T visitTransformExpression(AppendExpression expression, T argument) { + public T visitTransformExpression(TransformExpression expression, T argument) { + return defaultAction(expression, argument); + } + + public T visitCopyDeclaration(CopyDeclaration expression, T argument) { return defaultAction(expression, argument); } diff --git a/src/main/java/org/rumbledb/expressions/update/CopyDeclaration.java b/src/main/java/org/rumbledb/expressions/update/CopyDeclaration.java new file mode 100644 index 0000000000..5a0a4d7a37 --- /dev/null +++ b/src/main/java/org/rumbledb/expressions/update/CopyDeclaration.java @@ -0,0 +1,56 @@ +package org.rumbledb.expressions.update; + +import org.rumbledb.context.Name; +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.exceptions.SemanticException; +import org.rumbledb.expressions.AbstractNodeVisitor; +import org.rumbledb.expressions.Expression; +import org.rumbledb.expressions.Node; + +import java.util.Collections; +import java.util.List; + +public class CopyDeclaration extends Node { + + private Name variableName; + private Expression sourceExpression; + + public CopyDeclaration(Name variableName, + Expression sourceExpression, + ExceptionMetadata metadata + ) { + super(metadata); + if (variableName == null) { + throw new SemanticException("Copy clause must have at least one variable", metadata); + } + this.variableName = variableName; + this.sourceExpression = sourceExpression; + } + + public Name getVariableName() { + return variableName; + } + + public Expression getSourceExpression() { + return sourceExpression; + } + + @Override + public List getChildren() { + return Collections.singletonList(this.sourceExpression); + } + + @Override + public T accept(AbstractNodeVisitor visitor, T argument) { + return visitor.visitCopyDeclaration(this, argument); + } + + @Override + public void serializeToJSONiq(StringBuffer sb, int indent) { + indentIt(sb, indent); + sb.append("copy $").append(this.variableName.toString()); + sb.append(" := ("); + this.sourceExpression.serializeToJSONiq(sb, 0); + sb.append(")\n"); + } +} diff --git a/src/main/java/org/rumbledb/expressions/update/TransformExpression.java b/src/main/java/org/rumbledb/expressions/update/TransformExpression.java new file mode 100644 index 0000000000..baec37e0dd --- /dev/null +++ b/src/main/java/org/rumbledb/expressions/update/TransformExpression.java @@ -0,0 +1,67 @@ +package org.rumbledb.expressions.update; + +import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.expressions.AbstractNodeVisitor; +import org.rumbledb.expressions.Expression; +import org.rumbledb.expressions.Node; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +public class TransformExpression extends Expression +{ + + private List copyDeclarations; + private Expression modifyExpression; + private Expression returnExpression; + + public TransformExpression(List copyDeclarations, + Expression modifyExpression, + Expression returnExpression, + ExceptionMetadata metadata + ) { + super(metadata); + this.copyDeclarations = copyDeclarations; + this.modifyExpression = modifyExpression; + this.returnExpression = returnExpression; + } + + public List getCopyDeclarations() { + return copyDeclarations; + } + + public Expression getModifyExpression() { + return modifyExpression; + } + + public Expression getReturnExpression() { + return returnExpression; + } + + @Override + public List getChildren() { + List result = this.copyDeclarations.stream().filter(Objects::nonNull).collect(Collectors.toList()); + result.add(this.modifyExpression); + result.add(this.returnExpression); + return result; + } + + @Override + public T accept(AbstractNodeVisitor visitor, T argument) { + return visitor.visitTransformExpression(this, argument); + } + + @Override + public void serializeToJSONiq(StringBuffer sb, int indent) { + indentIt(sb, indent); + for (Node copyDecl : this.copyDeclarations) { + copyDecl.serializeToJSONiq(sb, 0); + } + sb.append("\n modify "); + this.modifyExpression.serializeToJSONiq(sb, 0); + sb.append("\n return "); + this.returnExpression.serializeToJSONiq(sb, 0); + sb.append("\n"); + } +} diff --git a/src/main/java/org/rumbledb/parser/Jsoniq.g4 b/src/main/java/org/rumbledb/parser/Jsoniq.g4 index a7aef15b61..67ef4db2ff 100644 --- a/src/main/java/org/rumbledb/parser/Jsoniq.g4 +++ b/src/main/java/org/rumbledb/parser/Jsoniq.g4 @@ -242,8 +242,8 @@ inlineFunctionExpr : 'function' '(' paramList? ')' ///////////////////////// Updating Expressions -insertExpr : 'insert' 'json' exprSingle 'into' exprSingle ('at' 'position' exprSingle)? - | 'insert' 'json' pairConstructor ( ',' pairConstructor )* 'into' exprSingle; +insertExpr : 'insert' 'json' to_insert_expr=exprSingle 'into' main_expr=exprSingle ('at' 'position' pos_expr=exprSingle)? + | 'insert' 'json' pairConstructor ( ',' pairConstructor )* 'into' main_expr=exprSingle; deleteExpr : 'delete' 'json' updateLocator; @@ -251,12 +251,14 @@ renameExpr : 'rename' 'json' updateLocator 'as' name_expr=exprSingl replaceExpr : 'replace' 'json' 'value' 'of' updateLocator 'with' replacer_expr=exprSingle; -transformExpr : 'copy' varRef ':=' exprSingle ( ',' varRef ':=' exprSingle )* 'modify' exprSingle Kreturn exprSingle; +transformExpr : 'copy' 'json' copyDecl ( ',' copyDecl )* 'modify' mod_expr=exprSingle Kreturn ret_expr=exprSingle; appendExpr : 'append' 'json' to_append_expr=exprSingle 'into' array_expr=exprSingle; updateLocator : main_expr=primaryExpr ( arrayLookup | objectLookup )+; +copyDecl : var_ref=varRef ':=' src_expr=exprSingle; + ///////////////////////// Types sequenceType : '(' ')' From c7e90608805045e00791aa0a981a088d25de142e Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 20 Mar 2023 01:03:33 +0100 Subject: [PATCH 012/119] Update rename to only work with object lookups --- .../java/org/rumbledb/expressions/update/RenameExpression.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/org/rumbledb/expressions/update/RenameExpression.java b/src/main/java/org/rumbledb/expressions/update/RenameExpression.java index d55f18021d..f876e9ad4d 100644 --- a/src/main/java/org/rumbledb/expressions/update/RenameExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/RenameExpression.java @@ -34,6 +34,9 @@ public RenameExpression(Expression mainExpression, if (locatorKind == null) { throw new OurBadException("Locator kind cannot be null in a rename expression."); } + if (!locatorKind.isObjectLookup()) { + throw new OurBadException("Locator kind must be Object Lookup"); + } this.mainExpression = mainExpression; this.locatorExpression = locatorExpression; this.nameExpression = nameExpression; From 8d8282c1118faaaa7dd9e87f3a8bf813b8abbe25 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 20 Mar 2023 01:38:24 +0100 Subject: [PATCH 013/119] Create ExpressionClassification enum to classify expression as BASIC_UPDATING, UPDATING, SIMPLE, or VACUOUS --- .../org/rumbledb/expressions/Expression.java | 22 +++++++++ .../expressions/ExpressionClassification.java | 48 +++++++++++++++++++ .../expressions/update/AppendExpression.java | 2 + .../expressions/update/DeleteExpression.java | 2 + .../expressions/update/InsertExpression.java | 2 + .../expressions/update/RenameExpression.java | 2 + .../expressions/update/ReplaceExpression.java | 2 + .../update/TransformExpression.java | 2 + 8 files changed, 82 insertions(+) create mode 100644 src/main/java/org/rumbledb/expressions/ExpressionClassification.java diff --git a/src/main/java/org/rumbledb/expressions/Expression.java b/src/main/java/org/rumbledb/expressions/Expression.java index 3d866bbea3..17849285b4 100644 --- a/src/main/java/org/rumbledb/expressions/Expression.java +++ b/src/main/java/org/rumbledb/expressions/Expression.java @@ -35,6 +35,8 @@ * * An expression is associated with a static context containing information such as * the in-scope variables. + * + * An expression has a classification, largely denoting it as UPDATING or SIMPLE. */ public abstract class Expression extends Node { @@ -42,6 +44,8 @@ public abstract class Expression extends Node { protected SequenceType staticSequenceType; + protected ExpressionClassification expressionClassification = ExpressionClassification.SIMPLE; + protected Expression(ExceptionMetadata metadata) { super(metadata); } @@ -98,6 +102,24 @@ public void setStaticSequenceType(SequenceType staticSequenceType) { this.staticSequenceType = staticSequenceType; } + /** + * Gets the inferred expression classification, for use ... + * + * @return Expression Classification of the expression. + */ + public ExpressionClassification getExpressionClassification() { + return expressionClassification; + } + + /** + * Sets the inferred expression classification, for use ... + * + * @param expressionClassification the statically inferred expression classification. + */ + public void setExpressionClassification(ExpressionClassification expressionClassification) { + this.expressionClassification = expressionClassification; + } + @Override public void print(StringBuffer buffer, int indent) { for (int i = 0; i < indent; ++i) { diff --git a/src/main/java/org/rumbledb/expressions/ExpressionClassification.java b/src/main/java/org/rumbledb/expressions/ExpressionClassification.java new file mode 100644 index 0000000000..3b9f1554ec --- /dev/null +++ b/src/main/java/org/rumbledb/expressions/ExpressionClassification.java @@ -0,0 +1,48 @@ +package org.rumbledb.expressions; + +/** + * An ExpressionClassification classifies an expression under 4 possible classifications. + * + * A BASIC_UPDATING expression is classified as 1 of 6 expressions in the update package, that can alter the state of + * an existing node. + * + * An UPDATING expression is classified as a BASIC_EXPRESSION or any expression (excluding a TransformExpression) that + * directly contains an UPDATING expression and that can alter the state of an existing node. + * + * A SIMPLE expression is classified as an expression that is not an updating expression. + * + * A VACUOUS expression follows the definition of the XQuery Update Facility 1.0, but is largely classified as + * an expression that can be determined statically to return an empty sequence or raise an error. + */ +public enum ExpressionClassification { + BASIC_UPDATING, + UPDATING, + SIMPLE, + VACUOUS; + + public boolean isUpdating() { + return this == ExpressionClassification.BASIC_UPDATING || this == ExpressionClassification.UPDATING; + } + + public boolean isSimple() { + return this == ExpressionClassification.SIMPLE; + } + + public boolean isVacuous() { + return this == ExpressionClassification.VACUOUS; + } + + public String toString() { + switch (this) { + case BASIC_UPDATING: + return "basic_updating"; + case UPDATING: + return "updating"; + case SIMPLE: + return "simple"; + case VACUOUS: + return "vacuous"; + } + return null; + } +} diff --git a/src/main/java/org/rumbledb/expressions/update/AppendExpression.java b/src/main/java/org/rumbledb/expressions/update/AppendExpression.java index 227f24de4e..f3ac0de302 100644 --- a/src/main/java/org/rumbledb/expressions/update/AppendExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/AppendExpression.java @@ -4,6 +4,7 @@ import org.rumbledb.exceptions.OurBadException; import org.rumbledb.expressions.AbstractNodeVisitor; import org.rumbledb.expressions.Expression; +import org.rumbledb.expressions.ExpressionClassification; import org.rumbledb.expressions.Node; import java.util.Arrays; @@ -26,6 +27,7 @@ public AppendExpression(Expression arrayExpression, } this.arrayExpression = arrayExpression; this.toAppendExpression = toAppendExpression; + this.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); } public Expression getArrayExpression() { diff --git a/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java b/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java index 22947bbd32..df8f04c020 100644 --- a/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java @@ -4,6 +4,7 @@ import org.rumbledb.exceptions.OurBadException; import org.rumbledb.expressions.AbstractNodeVisitor; import org.rumbledb.expressions.Expression; +import org.rumbledb.expressions.ExpressionClassification; import org.rumbledb.expressions.Node; import java.util.Arrays; @@ -32,6 +33,7 @@ public DeleteExpression(Expression mainExpression, this.mainExpression = mainExpression; this.locatorExpression = locatorExpression; this.locatorKind = locatorKind; + this.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); } @Override diff --git a/src/main/java/org/rumbledb/expressions/update/InsertExpression.java b/src/main/java/org/rumbledb/expressions/update/InsertExpression.java index 38484a45a9..07b37d2bf2 100644 --- a/src/main/java/org/rumbledb/expressions/update/InsertExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/InsertExpression.java @@ -3,6 +3,7 @@ import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.expressions.AbstractNodeVisitor; import org.rumbledb.expressions.Expression; +import org.rumbledb.expressions.ExpressionClassification; import org.rumbledb.expressions.Node; import java.util.List; @@ -10,6 +11,7 @@ public class InsertExpression extends Expression { public InsertExpression(ExceptionMetadata metadata) { super(metadata); + this.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); } @Override diff --git a/src/main/java/org/rumbledb/expressions/update/RenameExpression.java b/src/main/java/org/rumbledb/expressions/update/RenameExpression.java index f876e9ad4d..1224125cb7 100644 --- a/src/main/java/org/rumbledb/expressions/update/RenameExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/RenameExpression.java @@ -4,6 +4,7 @@ import org.rumbledb.exceptions.OurBadException; import org.rumbledb.expressions.AbstractNodeVisitor; import org.rumbledb.expressions.Expression; +import org.rumbledb.expressions.ExpressionClassification; import org.rumbledb.expressions.Node; import java.util.Arrays; @@ -41,6 +42,7 @@ public RenameExpression(Expression mainExpression, this.locatorExpression = locatorExpression; this.nameExpression = nameExpression; this.locatorKind = locatorKind; + this.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); } @Override diff --git a/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java b/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java index fd26d0c04c..d9a0b98259 100644 --- a/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java @@ -4,6 +4,7 @@ import org.rumbledb.exceptions.OurBadException; import org.rumbledb.expressions.AbstractNodeVisitor; import org.rumbledb.expressions.Expression; +import org.rumbledb.expressions.ExpressionClassification; import org.rumbledb.expressions.Node; import java.util.Arrays; @@ -38,6 +39,7 @@ public ReplaceExpression(Expression mainExpression, this.locatorExpression = locatorExpression; this.replacerExpression = replacerExpression; this.locatorKind = locatorKind; + this.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); } @Override diff --git a/src/main/java/org/rumbledb/expressions/update/TransformExpression.java b/src/main/java/org/rumbledb/expressions/update/TransformExpression.java index baec37e0dd..666ea53ea6 100644 --- a/src/main/java/org/rumbledb/expressions/update/TransformExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/TransformExpression.java @@ -3,6 +3,7 @@ import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.expressions.AbstractNodeVisitor; import org.rumbledb.expressions.Expression; +import org.rumbledb.expressions.ExpressionClassification; import org.rumbledb.expressions.Node; import java.util.List; @@ -25,6 +26,7 @@ public TransformExpression(List copyDeclarations, this.copyDeclarations = copyDeclarations; this.modifyExpression = modifyExpression; this.returnExpression = returnExpression; + this.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); } public List getCopyDeclarations() { From ff82e814fbfdb8e9dbc2021181a3d839c6cab1b7 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 20 Mar 2023 17:22:56 +0100 Subject: [PATCH 014/119] Add isUpdating method to Expression class --- src/main/java/org/rumbledb/expressions/Expression.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/org/rumbledb/expressions/Expression.java b/src/main/java/org/rumbledb/expressions/Expression.java index 17849285b4..9cee7f8f63 100644 --- a/src/main/java/org/rumbledb/expressions/Expression.java +++ b/src/main/java/org/rumbledb/expressions/Expression.java @@ -120,6 +120,15 @@ public void setExpressionClassification(ExpressionClassification expressionClass this.expressionClassification = expressionClassification; } + /** + * Tells whether this expression is an updating expression or not. + * + * @return true if yes, false otherwise. + */ + public boolean isUpdating() { + return this.expressionClassification.isUpdating(); + } + @Override public void print(StringBuffer buffer, int indent) { for (int i = 0; i < indent; ++i) { From 624764e6e8406e8ccb6c0ed91f0d7015ca15d69d Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 20 Mar 2023 17:24:05 +0100 Subject: [PATCH 015/119] Implement simple InsertExpression node class and translation --- .../rumbledb/compiler/TranslationVisitor.java | 30 +++++++++- .../expressions/update/InsertExpression.java | 56 +++++++++++++++++-- 2 files changed, 79 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java index 7dfc2d1734..2ca76fed53 100644 --- a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java @@ -577,6 +577,9 @@ public Node visitExprSingle(JsoniqParser.ExprSingleContext ctx) { if (content instanceof JsoniqParser.AppendExprContext) { return this.visitAppendExpr((JsoniqParser.AppendExprContext) content); } + if (content instanceof JsoniqParser.TransformExprContext) { + return this.visitTransformExpr((JsoniqParser.TransformExprContext) content); + } throw new OurBadException("Unrecognized ExprSingle."); } // endregion @@ -1139,7 +1142,32 @@ public Node visitValidateExpr(JsoniqParser.ValidateExprContext ctx) { @Override public Node visitInsertExpr(JsoniqParser.InsertExprContext ctx) { - return super.visitInsertExpr(ctx); + Expression toInsertExpr = null; + Expression posExpr = null; + if (ctx.pairConstructor() != null && !ctx.pairConstructor().isEmpty()) { + List keys = new ArrayList<>(); + List values = new ArrayList<>(); + for (JsoniqParser.PairConstructorContext currentPair : ctx.pairConstructor()) { + if (currentPair.lhs != null) { + keys.add((Expression) this.visitExprSingle(currentPair.lhs)); + } else { + keys.add(new StringLiteralExpression(currentPair.name.getText(), createMetadataFromContext(ctx))); + } + values.add((Expression) this.visitExprSingle(currentPair.rhs)); + } + toInsertExpr = new ObjectConstructorExpression(keys, values, createMetadataFromContext(ctx)); + } else if (ctx.to_insert_expr != null) { + toInsertExpr = (Expression) this.visitExprSingle(ctx.to_insert_expr); + if (ctx.pos_expr != null) { + posExpr = (Expression) this.visitExprSingle(ctx.pos_expr); + } + } + else { + throw new OurBadException("Unrecognised expression to insert in Insert Expression"); + } + Expression mainExpr = (Expression) this.visitExprSingle(ctx.main_expr); + + return new InsertExpression(mainExpr, toInsertExpr, posExpr, createMetadataFromContext(ctx)); } @Override diff --git a/src/main/java/org/rumbledb/expressions/update/InsertExpression.java b/src/main/java/org/rumbledb/expressions/update/InsertExpression.java index 07b37d2bf2..adc1c23dd8 100644 --- a/src/main/java/org/rumbledb/expressions/update/InsertExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/InsertExpression.java @@ -1,31 +1,75 @@ package org.rumbledb.expressions.update; import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.exceptions.OurBadException; import org.rumbledb.expressions.AbstractNodeVisitor; import org.rumbledb.expressions.Expression; import org.rumbledb.expressions.ExpressionClassification; import org.rumbledb.expressions.Node; +import java.util.Arrays; import java.util.List; public class InsertExpression extends Expression { - public InsertExpression(ExceptionMetadata metadata) { + + private Expression mainExpression; + private Expression toInsertExpression; + private Expression positionExpression; + + public InsertExpression(Expression mainExpression, + Expression toInsertExpression, + Expression positionExpression, + ExceptionMetadata metadata + ) { super(metadata); + this.mainExpression = mainExpression; + this.toInsertExpression = toInsertExpression; + this.positionExpression = positionExpression; this.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); } - @Override - public T accept(AbstractNodeVisitor visitor, T argument) { - return null; + public boolean hasPositionExpression() { + return positionExpression != null; + } + + public Expression getMainExpression() { + return mainExpression; + } + + public Expression getToInsertExpression() { + return toInsertExpression; + } + + public Expression getPositionExpression() { + if (positionExpression == null) { + throw new OurBadException("No position expression present in Insert Expression"); + } + return positionExpression; } @Override public List getChildren() { - return null; + return this.positionExpression == null ? + Arrays.asList(mainExpression, toInsertExpression) : + Arrays.asList(mainExpression, toInsertExpression, positionExpression); } @Override - public void serializeToJSONiq(StringBuffer sb, int indent) { + public T accept(AbstractNodeVisitor visitor, T argument) { + return visitor.visitInsertExpression(this, argument); + } + @Override + public void serializeToJSONiq(StringBuffer sb, int indent) { + indentIt(sb, indent); + sb.append("insert json "); + toInsertExpression.serializeToJSONiq(sb, 0); + sb.append(" into "); + mainExpression.serializeToJSONiq(sb, 0); + if (this.hasPositionExpression()) { + sb.append(" at position "); + positionExpression.serializeToJSONiq(sb, 0); + } + sb.append("\n"); } } From 2d834c31d645b19648da55d5b58bf32023339c63 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Tue, 21 Mar 2023 01:17:53 +0100 Subject: [PATCH 016/119] Implement defaultAction and visitDescendants of ExpressionClassificationVisitor using bottom-up recursion --- .../ExpressionClassificationVisitor.java | 38 +++++++++++++++++++ .../rumbledb/compiler/TranslationVisitor.java | 2 +- 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java diff --git a/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java b/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java new file mode 100644 index 0000000000..aeb8f836c2 --- /dev/null +++ b/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java @@ -0,0 +1,38 @@ +package org.rumbledb.compiler; + +import org.rumbledb.context.StaticContext; +import org.rumbledb.expressions.AbstractNodeVisitor; +import org.rumbledb.expressions.Expression; +import org.rumbledb.expressions.ExpressionClassification; +import org.rumbledb.expressions.Node; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class ExpressionClassificationVisitor extends AbstractNodeVisitor { + + public ExpressionClassificationVisitor() { + } + + @Override + protected ExpressionClassification defaultAction(Node node, ExpressionClassification argument) { + ExpressionClassification exprClassification = super.defaultAction(node, argument); + if (node instanceof Expression) { + ((Expression) node).setExpressionClassification(exprClassification); + } + return exprClassification; + } + + @Override + public ExpressionClassification visitDescendants(Node node, ExpressionClassification argument) { + ExpressionClassification result = null; + for (Node child : node.getChildren()) { + ExpressionClassification temp = visit(child, result); + if (result == null && temp.isUpdating()) { + result = temp; + } + } + return result == null ? argument : result; + } +} diff --git a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java index 2ca76fed53..ed3b2017ce 100644 --- a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java @@ -1142,7 +1142,7 @@ public Node visitValidateExpr(JsoniqParser.ValidateExprContext ctx) { @Override public Node visitInsertExpr(JsoniqParser.InsertExprContext ctx) { - Expression toInsertExpr = null; + Expression toInsertExpr; Expression posExpr = null; if (ctx.pairConstructor() != null && !ctx.pairConstructor().isEmpty()) { List keys = new ArrayList<>(); From b6cf31a0f297f6f44a27ec37812522cff824c600 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Tue, 21 Mar 2023 15:30:08 +0100 Subject: [PATCH 017/119] Implement ExpressionClassificationVisitor and add visitor to module parsing --- .../ExpressionClassificationVisitor.java | 70 +++++++++++++------ .../org/rumbledb/compiler/VisitorHelpers.java | 16 +++++ .../org/rumbledb/expressions/Expression.java | 1 + .../expressions/ExpressionClassification.java | 7 ++ .../java/org/rumbledb/expressions/Node.java | 41 +++++++++++ 5 files changed, 115 insertions(+), 20 deletions(-) diff --git a/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java b/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java index aeb8f836c2..788086877d 100644 --- a/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java @@ -1,38 +1,68 @@ package org.rumbledb.compiler; +import org.apache.hadoop.fs.Stat; import org.rumbledb.context.StaticContext; import org.rumbledb.expressions.AbstractNodeVisitor; import org.rumbledb.expressions.Expression; import org.rumbledb.expressions.ExpressionClassification; import org.rumbledb.expressions.Node; +import org.rumbledb.expressions.update.*; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; +public class ExpressionClassificationVisitor extends AbstractNodeVisitor { -public class ExpressionClassificationVisitor extends AbstractNodeVisitor { + @Override + protected StaticContext defaultAction(Node node, StaticContext argument) { + StaticContext staticContext = super.defaultAction(node, argument); + boolean hasUpdatingChild = false; + for (Node child : node.getChildren()) { + if (!hasUpdatingChild && child.isUpdating()) { + hasUpdatingChild = true; + } + } + if (node instanceof Expression && hasUpdatingChild) { + node.setExpressionClassification(ExpressionClassification.UPDATING); + } + return staticContext; + } - public ExpressionClassificationVisitor() { + // Region Basic Updating + + @Override + public StaticContext visitDeleteExpression(DeleteExpression expression, StaticContext argument) { + expression.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); + return super.visitDeleteExpression(expression, argument); } @Override - protected ExpressionClassification defaultAction(Node node, ExpressionClassification argument) { - ExpressionClassification exprClassification = super.defaultAction(node, argument); - if (node instanceof Expression) { - ((Expression) node).setExpressionClassification(exprClassification); - } - return exprClassification; + public StaticContext visitRenameExpression(RenameExpression expression, StaticContext argument) { + expression.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); + return super.visitRenameExpression(expression, argument); } @Override - public ExpressionClassification visitDescendants(Node node, ExpressionClassification argument) { - ExpressionClassification result = null; - for (Node child : node.getChildren()) { - ExpressionClassification temp = visit(child, result); - if (result == null && temp.isUpdating()) { - result = temp; - } - } - return result == null ? argument : result; + public StaticContext visitReplaceExpression(ReplaceExpression expression, StaticContext argument) { + expression.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); + return super.visitReplaceExpression(expression, argument); + } + + @Override + public StaticContext visitInsertExpression(InsertExpression expression, StaticContext argument) { + expression.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); + return super.visitInsertExpression(expression, argument); } + + @Override + public StaticContext visitAppendExpression(AppendExpression expression, StaticContext argument) { + expression.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); + return super.visitAppendExpression(expression, argument); + } + + @Override + public StaticContext visitTransformExpression(TransformExpression expression, StaticContext argument) { + expression.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); + this.visitDescendants(expression, argument); + return this.visitDescendants(expression, argument); + } + + // Endregion } diff --git a/src/main/java/org/rumbledb/compiler/VisitorHelpers.java b/src/main/java/org/rumbledb/compiler/VisitorHelpers.java index 9b4f1eedc5..cca52aca9d 100644 --- a/src/main/java/org/rumbledb/compiler/VisitorHelpers.java +++ b/src/main/java/org/rumbledb/compiler/VisitorHelpers.java @@ -141,6 +141,7 @@ public static MainModule parseJSONiqMainModule( populateStaticContext(mainModule, configuration); inferTypes(mainModule, configuration); populateExecutionModes(mainModule, configuration); + populateExpressionClassifications(mainModule, configuration); return mainModule; } catch (ParseCancellationException ex) { ParsingException e = new ParsingException( @@ -181,6 +182,8 @@ public static MainModule parseXQueryMainModule( populateStaticContext(mainModule, configuration); inferTypes(mainModule, configuration); populateExecutionModes(mainModule, configuration); + // TODO populate expression classifications here? +// populateExpressionClassifications(mainModule, configuration); return mainModule; } catch (ParseCancellationException ex) { ParsingException e = new ParsingException( @@ -359,6 +362,19 @@ private static void populateStaticContext(Module module, RumbleRuntimeConfigurat } } + private static void populateExpressionClassifications(Module module, RumbleRuntimeConfiguration conf) { + if (conf.isPrintIteratorTree()) { + printTree(module, conf); + } + + ExpressionClassificationVisitor visitor = new ExpressionClassificationVisitor(); + 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/expressions/Expression.java b/src/main/java/org/rumbledb/expressions/Expression.java index 9cee7f8f63..6375eadcf7 100644 --- a/src/main/java/org/rumbledb/expressions/Expression.java +++ b/src/main/java/org/rumbledb/expressions/Expression.java @@ -136,6 +136,7 @@ public void print(StringBuffer buffer, int indent) { } buffer.append(getClass().getSimpleName()); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append( " | " + (this.staticSequenceType == null diff --git a/src/main/java/org/rumbledb/expressions/ExpressionClassification.java b/src/main/java/org/rumbledb/expressions/ExpressionClassification.java index 3b9f1554ec..99905461a9 100644 --- a/src/main/java/org/rumbledb/expressions/ExpressionClassification.java +++ b/src/main/java/org/rumbledb/expressions/ExpressionClassification.java @@ -15,11 +15,16 @@ * an expression that can be determined statically to return an empty sequence or raise an error. */ public enum ExpressionClassification { + UNSET, BASIC_UPDATING, UPDATING, SIMPLE, VACUOUS; + public boolean isUnset() { + return this == ExpressionClassification.UNSET; + } + public boolean isUpdating() { return this == ExpressionClassification.BASIC_UPDATING || this == ExpressionClassification.UPDATING; } @@ -34,6 +39,8 @@ public boolean isVacuous() { public String toString() { switch (this) { + case UNSET: + return "unset"; case BASIC_UPDATING: return "basic_updating"; case UPDATING: diff --git a/src/main/java/org/rumbledb/expressions/Node.java b/src/main/java/org/rumbledb/expressions/Node.java index 1ebd4b5ab3..2968a03335 100644 --- a/src/main/java/org/rumbledb/expressions/Node.java +++ b/src/main/java/org/rumbledb/expressions/Node.java @@ -38,6 +38,8 @@ public abstract class Node { protected ExecutionMode highestExecutionMode = ExecutionMode.UNSET; + protected ExpressionClassification expressionClassification = ExpressionClassification.UNSET; + protected Node() { } @@ -112,6 +114,44 @@ public int numberOfUnsetExecutionModes() { return result; } + + /** + * Gets the inferred expression classification of this node, for use ... + * + * @return Expression Classification of the expression. + */ + public ExpressionClassification getExpressionClassification() { + return expressionClassification; + } + + /** + * Sets the inferred expression classification of this node, for use ... + * + * @param expressionClassification the statically inferred expression classification. + */ + public void setExpressionClassification(ExpressionClassification expressionClassification) { + this.expressionClassification = expressionClassification; + } + + /** + * Tells whether this node is an updating expression or not. + * + * @return true if yes, false otherwise. + */ + public boolean isUpdating() { + return this.expressionClassification.isUpdating(); + } + + /** + * Tells whether this node has an unset expression classification. + * + * @return true if yes, false otherwise. + */ + public boolean isUnset() { + return this.expressionClassification.isUnset(); + } + + /** * Accept method for the visitor pattern. * @@ -179,6 +219,7 @@ public void print(StringBuffer buffer, int indent) { } buffer.append(getClass().getSimpleName()); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); From 3092fbf3000de844eb1c841ab80b7ea97efe3ff7 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Tue, 21 Mar 2023 15:31:05 +0100 Subject: [PATCH 018/119] Add expression classification to the iterator tree print of all expressions --- .../org/rumbledb/expressions/arithmetic/AdditiveExpression.java | 1 + .../expressions/arithmetic/MultiplicativeExpression.java | 1 + .../org/rumbledb/expressions/arithmetic/UnaryExpression.java | 1 + .../rumbledb/expressions/comparison/ComparisonExpression.java | 1 + src/main/java/org/rumbledb/expressions/flowr/Clause.java | 1 + src/main/java/org/rumbledb/expressions/flowr/CountClause.java | 1 + src/main/java/org/rumbledb/expressions/flowr/ForClause.java | 1 + src/main/java/org/rumbledb/expressions/flowr/GroupByClause.java | 1 + src/main/java/org/rumbledb/expressions/flowr/LetClause.java | 1 + .../java/org/rumbledb/expressions/flowr/SimpleMapExpression.java | 1 + .../org/rumbledb/expressions/module/FunctionDeclaration.java | 1 + src/main/java/org/rumbledb/expressions/module/LibraryModule.java | 1 + .../org/rumbledb/expressions/module/VariableDeclaration.java | 1 + .../expressions/postfix/DynamicFunctionCallExpression.java | 1 + .../rumbledb/expressions/primary/BooleanLiteralExpression.java | 1 + .../rumbledb/expressions/primary/DecimalLiteralExpression.java | 1 + .../rumbledb/expressions/primary/DoubleLiteralExpression.java | 1 + .../org/rumbledb/expressions/primary/FunctionCallExpression.java | 1 + .../rumbledb/expressions/primary/InlineFunctionExpression.java | 1 + .../rumbledb/expressions/primary/IntegerLiteralExpression.java | 1 + .../rumbledb/expressions/primary/StringLiteralExpression.java | 1 + .../expressions/primary/VariableReferenceExpression.java | 1 + .../java/org/rumbledb/expressions/typing/CastExpression.java | 1 + .../java/org/rumbledb/expressions/typing/CastableExpression.java | 1 + .../org/rumbledb/expressions/typing/InstanceOfExpression.java | 1 + .../org/rumbledb/expressions/typing/IsStaticallyExpression.java | 1 + .../java/org/rumbledb/expressions/typing/TreatExpression.java | 1 + .../org/rumbledb/expressions/typing/ValidateTypeExpression.java | 1 + 28 files changed, 28 insertions(+) diff --git a/src/main/java/org/rumbledb/expressions/arithmetic/AdditiveExpression.java b/src/main/java/org/rumbledb/expressions/arithmetic/AdditiveExpression.java index b8176dbb2b..2b8b4d6195 100644 --- a/src/main/java/org/rumbledb/expressions/arithmetic/AdditiveExpression.java +++ b/src/main/java/org/rumbledb/expressions/arithmetic/AdditiveExpression.java @@ -75,6 +75,7 @@ public void print(StringBuffer buffer, int indent) { buffer.append(getClass().getSimpleName()); buffer.append(" (" + (this.isMinus ? "-" : "+") + ") "); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); for (Node iterator : getChildren()) { diff --git a/src/main/java/org/rumbledb/expressions/arithmetic/MultiplicativeExpression.java b/src/main/java/org/rumbledb/expressions/arithmetic/MultiplicativeExpression.java index 5ea6859317..7cfca410af 100644 --- a/src/main/java/org/rumbledb/expressions/arithmetic/MultiplicativeExpression.java +++ b/src/main/java/org/rumbledb/expressions/arithmetic/MultiplicativeExpression.java @@ -111,6 +111,7 @@ public void print(StringBuffer buffer, int indent) { buffer.append(getClass().getSimpleName()); buffer.append(" (" + (this.multiplicativeOperator) + ") "); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); for (Node iterator : getChildren()) { diff --git a/src/main/java/org/rumbledb/expressions/arithmetic/UnaryExpression.java b/src/main/java/org/rumbledb/expressions/arithmetic/UnaryExpression.java index cf5974b810..88f4fc7720 100644 --- a/src/main/java/org/rumbledb/expressions/arithmetic/UnaryExpression.java +++ b/src/main/java/org/rumbledb/expressions/arithmetic/UnaryExpression.java @@ -70,6 +70,7 @@ public void print(StringBuffer buffer, int indent) { buffer.append(getClass().getSimpleName()); buffer.append(" (" + (this.negated ? "-" : "+") + ") "); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); for (Node iterator : getChildren()) { diff --git a/src/main/java/org/rumbledb/expressions/comparison/ComparisonExpression.java b/src/main/java/org/rumbledb/expressions/comparison/ComparisonExpression.java index ce4bf57f15..1c0c431f35 100644 --- a/src/main/java/org/rumbledb/expressions/comparison/ComparisonExpression.java +++ b/src/main/java/org/rumbledb/expressions/comparison/ComparisonExpression.java @@ -170,6 +170,7 @@ public void print(StringBuffer buffer, int indent) { buffer.append(getClass().getSimpleName()); buffer.append(" (" + (this.comparisonOperator) + ") "); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); for (Node iterator : getChildren()) { diff --git a/src/main/java/org/rumbledb/expressions/flowr/Clause.java b/src/main/java/org/rumbledb/expressions/flowr/Clause.java index 25f6319acc..132ea7ef41 100644 --- a/src/main/java/org/rumbledb/expressions/flowr/Clause.java +++ b/src/main/java/org/rumbledb/expressions/flowr/Clause.java @@ -165,6 +165,7 @@ public void print(StringBuffer buffer, int indent) { } buffer.append(getClass().getSimpleName()); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/flowr/CountClause.java b/src/main/java/org/rumbledb/expressions/flowr/CountClause.java index 3392464788..558200b389 100644 --- a/src/main/java/org/rumbledb/expressions/flowr/CountClause.java +++ b/src/main/java/org/rumbledb/expressions/flowr/CountClause.java @@ -58,6 +58,7 @@ public void print(StringBuffer buffer, int indent) { buffer.append(getClass().getSimpleName()); buffer.append(" (" + (this.countClauseVar) + ") "); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/flowr/ForClause.java b/src/main/java/org/rumbledb/expressions/flowr/ForClause.java index 435c0dadf1..d8c7b47713 100644 --- a/src/main/java/org/rumbledb/expressions/flowr/ForClause.java +++ b/src/main/java/org/rumbledb/expressions/flowr/ForClause.java @@ -139,6 +139,7 @@ public void print(StringBuffer buffer, int indent) { + ") " ); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/flowr/GroupByClause.java b/src/main/java/org/rumbledb/expressions/flowr/GroupByClause.java index d4fb0ccd63..36d1728a77 100644 --- a/src/main/java/org/rumbledb/expressions/flowr/GroupByClause.java +++ b/src/main/java/org/rumbledb/expressions/flowr/GroupByClause.java @@ -79,6 +79,7 @@ public void print(StringBuffer buffer, int indent) { } buffer.append(")"); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/flowr/LetClause.java b/src/main/java/org/rumbledb/expressions/flowr/LetClause.java index b548b22efb..19a50fe9b6 100644 --- a/src/main/java/org/rumbledb/expressions/flowr/LetClause.java +++ b/src/main/java/org/rumbledb/expressions/flowr/LetClause.java @@ -124,6 +124,7 @@ public void print(StringBuffer buffer, int indent) { ); buffer.append(")"); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/flowr/SimpleMapExpression.java b/src/main/java/org/rumbledb/expressions/flowr/SimpleMapExpression.java index b28946da8a..1b8aff3564 100644 --- a/src/main/java/org/rumbledb/expressions/flowr/SimpleMapExpression.java +++ b/src/main/java/org/rumbledb/expressions/flowr/SimpleMapExpression.java @@ -68,6 +68,7 @@ public void print(StringBuffer buffer, int indent) { buffer.append(getClass().getSimpleName()); buffer.append(" (!)"); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); for (Node iterator : getChildren()) { diff --git a/src/main/java/org/rumbledb/expressions/module/FunctionDeclaration.java b/src/main/java/org/rumbledb/expressions/module/FunctionDeclaration.java index 0eace7ff8d..59d9d540eb 100644 --- a/src/main/java/org/rumbledb/expressions/module/FunctionDeclaration.java +++ b/src/main/java/org/rumbledb/expressions/module/FunctionDeclaration.java @@ -79,6 +79,7 @@ public void print(StringBuffer buffer, int indent) { } buffer.append("FunctionDeclaration " + this.getFunctionIdentifier()); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/module/LibraryModule.java b/src/main/java/org/rumbledb/expressions/module/LibraryModule.java index 08c4ca62e2..ada6bf188d 100644 --- a/src/main/java/org/rumbledb/expressions/module/LibraryModule.java +++ b/src/main/java/org/rumbledb/expressions/module/LibraryModule.java @@ -77,6 +77,7 @@ public void print(StringBuffer buffer, int indent) { } buffer.append("Library module " + this.namespace); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); 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 0b8f67be57..2c03f54422 100644 --- a/src/main/java/org/rumbledb/expressions/module/VariableDeclaration.java +++ b/src/main/java/org/rumbledb/expressions/module/VariableDeclaration.java @@ -131,6 +131,7 @@ public void print(StringBuffer buffer, int indent) { + ") " ); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/postfix/DynamicFunctionCallExpression.java b/src/main/java/org/rumbledb/expressions/postfix/DynamicFunctionCallExpression.java index 9bade9093a..92ea884471 100644 --- a/src/main/java/org/rumbledb/expressions/postfix/DynamicFunctionCallExpression.java +++ b/src/main/java/org/rumbledb/expressions/postfix/DynamicFunctionCallExpression.java @@ -86,6 +86,7 @@ public void print(StringBuffer buffer, int indent) { } buffer.append(getClass().getSimpleName()); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append( " | " + (this.staticSequenceType == null diff --git a/src/main/java/org/rumbledb/expressions/primary/BooleanLiteralExpression.java b/src/main/java/org/rumbledb/expressions/primary/BooleanLiteralExpression.java index 62ac22aea8..6255bb31ff 100644 --- a/src/main/java/org/rumbledb/expressions/primary/BooleanLiteralExpression.java +++ b/src/main/java/org/rumbledb/expressions/primary/BooleanLiteralExpression.java @@ -59,6 +59,7 @@ public void print(StringBuffer buffer, int indent) { buffer.append(getClass().getSimpleName()); buffer.append(" (" + (this.value) + ") "); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); for (Node iterator : getChildren()) { diff --git a/src/main/java/org/rumbledb/expressions/primary/DecimalLiteralExpression.java b/src/main/java/org/rumbledb/expressions/primary/DecimalLiteralExpression.java index 5d4eb39bad..08a7b31357 100644 --- a/src/main/java/org/rumbledb/expressions/primary/DecimalLiteralExpression.java +++ b/src/main/java/org/rumbledb/expressions/primary/DecimalLiteralExpression.java @@ -60,6 +60,7 @@ public void print(StringBuffer buffer, int indent) { buffer.append(getClass().getSimpleName()); buffer.append(" (" + (this.value) + ") "); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); for (Node iterator : getChildren()) { diff --git a/src/main/java/org/rumbledb/expressions/primary/DoubleLiteralExpression.java b/src/main/java/org/rumbledb/expressions/primary/DoubleLiteralExpression.java index 0313eb5db7..b4a9bea31b 100644 --- a/src/main/java/org/rumbledb/expressions/primary/DoubleLiteralExpression.java +++ b/src/main/java/org/rumbledb/expressions/primary/DoubleLiteralExpression.java @@ -59,6 +59,7 @@ public void print(StringBuffer buffer, int indent) { buffer.append(getClass().getSimpleName()); buffer.append(" (" + (this.value) + ") "); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); for (Node iterator : getChildren()) { diff --git a/src/main/java/org/rumbledb/expressions/primary/FunctionCallExpression.java b/src/main/java/org/rumbledb/expressions/primary/FunctionCallExpression.java index 1a497038fc..661105b275 100644 --- a/src/main/java/org/rumbledb/expressions/primary/FunctionCallExpression.java +++ b/src/main/java/org/rumbledb/expressions/primary/FunctionCallExpression.java @@ -180,6 +180,7 @@ public void print(StringBuffer buffer, int indent) { } buffer.append(getClass().getSimpleName()); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append( " | " + (this.staticSequenceType == null diff --git a/src/main/java/org/rumbledb/expressions/primary/InlineFunctionExpression.java b/src/main/java/org/rumbledb/expressions/primary/InlineFunctionExpression.java index 31964210ca..5a6e1bb65c 100644 --- a/src/main/java/org/rumbledb/expressions/primary/InlineFunctionExpression.java +++ b/src/main/java/org/rumbledb/expressions/primary/InlineFunctionExpression.java @@ -128,6 +128,7 @@ public void print(StringBuffer buffer, int indent) { ); buffer.append(")"); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append( " | " + (this.staticSequenceType == null diff --git a/src/main/java/org/rumbledb/expressions/primary/IntegerLiteralExpression.java b/src/main/java/org/rumbledb/expressions/primary/IntegerLiteralExpression.java index bd906a343e..a951c13a8e 100644 --- a/src/main/java/org/rumbledb/expressions/primary/IntegerLiteralExpression.java +++ b/src/main/java/org/rumbledb/expressions/primary/IntegerLiteralExpression.java @@ -59,6 +59,7 @@ public void print(StringBuffer buffer, int indent) { buffer.append(getClass().getSimpleName()); buffer.append(" (" + (this.lexicalValue) + ") "); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); for (Node iterator : getChildren()) { diff --git a/src/main/java/org/rumbledb/expressions/primary/StringLiteralExpression.java b/src/main/java/org/rumbledb/expressions/primary/StringLiteralExpression.java index 86d7971592..1464d480d2 100644 --- a/src/main/java/org/rumbledb/expressions/primary/StringLiteralExpression.java +++ b/src/main/java/org/rumbledb/expressions/primary/StringLiteralExpression.java @@ -60,6 +60,7 @@ public void print(StringBuffer buffer, int indent) { buffer.append(getClass().getSimpleName()); buffer.append(" (" + (this.value) + ") "); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); for (Node iterator : getChildren()) { diff --git a/src/main/java/org/rumbledb/expressions/primary/VariableReferenceExpression.java b/src/main/java/org/rumbledb/expressions/primary/VariableReferenceExpression.java index 363a204896..417b28f5b2 100644 --- a/src/main/java/org/rumbledb/expressions/primary/VariableReferenceExpression.java +++ b/src/main/java/org/rumbledb/expressions/primary/VariableReferenceExpression.java @@ -87,6 +87,7 @@ public void print(StringBuffer buffer, int indent) { buffer.append(getClass().getSimpleName()); buffer.append(" ($" + this.name + ") "); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append( " | " + (this.staticSequenceType == null diff --git a/src/main/java/org/rumbledb/expressions/typing/CastExpression.java b/src/main/java/org/rumbledb/expressions/typing/CastExpression.java index b17d62cfb3..3ef27e5b65 100644 --- a/src/main/java/org/rumbledb/expressions/typing/CastExpression.java +++ b/src/main/java/org/rumbledb/expressions/typing/CastExpression.java @@ -60,6 +60,7 @@ public void print(StringBuffer buffer, int indent) { + ") " ); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append( " | " + (this.staticSequenceType == null diff --git a/src/main/java/org/rumbledb/expressions/typing/CastableExpression.java b/src/main/java/org/rumbledb/expressions/typing/CastableExpression.java index d2e05dfbed..ee5e5bfa15 100644 --- a/src/main/java/org/rumbledb/expressions/typing/CastableExpression.java +++ b/src/main/java/org/rumbledb/expressions/typing/CastableExpression.java @@ -60,6 +60,7 @@ public void print(StringBuffer buffer, int indent) { + ") " ); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); for (Node iterator : getChildren()) { diff --git a/src/main/java/org/rumbledb/expressions/typing/InstanceOfExpression.java b/src/main/java/org/rumbledb/expressions/typing/InstanceOfExpression.java index 0805f3dfe8..64b0be373b 100644 --- a/src/main/java/org/rumbledb/expressions/typing/InstanceOfExpression.java +++ b/src/main/java/org/rumbledb/expressions/typing/InstanceOfExpression.java @@ -79,6 +79,7 @@ public void print(StringBuffer buffer, int indent) { + ") " ); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); for (Node iterator : getChildren()) { diff --git a/src/main/java/org/rumbledb/expressions/typing/IsStaticallyExpression.java b/src/main/java/org/rumbledb/expressions/typing/IsStaticallyExpression.java index 99b992642a..377a9e9c1c 100644 --- a/src/main/java/org/rumbledb/expressions/typing/IsStaticallyExpression.java +++ b/src/main/java/org/rumbledb/expressions/typing/IsStaticallyExpression.java @@ -52,6 +52,7 @@ public void print(StringBuffer buffer, int indent) { buffer.append(getClass().getSimpleName()); buffer.append(" (" + (this.sequenceType.toString()) + ") "); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append( " | " + (this.staticSequenceType == null diff --git a/src/main/java/org/rumbledb/expressions/typing/TreatExpression.java b/src/main/java/org/rumbledb/expressions/typing/TreatExpression.java index c7d7c4fd3e..2e43cb0645 100644 --- a/src/main/java/org/rumbledb/expressions/typing/TreatExpression.java +++ b/src/main/java/org/rumbledb/expressions/typing/TreatExpression.java @@ -97,6 +97,7 @@ public void print(StringBuffer buffer, int indent) { + ") " ); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append(" | " + (this.staticSequenceType == null ? "not set" : this.staticSequenceType)); buffer.append("\n"); for (Node iterator : getChildren()) { diff --git a/src/main/java/org/rumbledb/expressions/typing/ValidateTypeExpression.java b/src/main/java/org/rumbledb/expressions/typing/ValidateTypeExpression.java index 4e0484d375..e1de4fbb17 100644 --- a/src/main/java/org/rumbledb/expressions/typing/ValidateTypeExpression.java +++ b/src/main/java/org/rumbledb/expressions/typing/ValidateTypeExpression.java @@ -59,6 +59,7 @@ public void print(StringBuffer buffer, int indent) { + ") " ); buffer.append(" | " + this.highestExecutionMode); + buffer.append(" | " + this.expressionClassification); buffer.append( " | " + (this.staticSequenceType == null From 622639f121d7a4c0e795bfa45e9f65a47acf5462 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Tue, 21 Mar 2023 16:45:13 +0100 Subject: [PATCH 019/119] Implement visit methods in StaticContextVisitor and VariableDependenciesVisitor for CopyDeclaration to account for the variables introduced --- .../org/rumbledb/compiler/StaticContextVisitor.java | 13 +++++++++++++ .../compiler/VariableDependenciesVisitor.java | 8 ++++++++ .../expressions/update/CopyDeclaration.java | 5 +++++ 3 files changed, 26 insertions(+) diff --git a/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java b/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java index be20f6851a..0aeb0e6f57 100644 --- a/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java +++ b/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java @@ -54,6 +54,7 @@ import org.rumbledb.expressions.typing.InstanceOfExpression; import org.rumbledb.expressions.typing.TreatExpression; import org.rumbledb.expressions.typing.ValidateTypeExpression; +import org.rumbledb.expressions.update.CopyDeclaration; import org.rumbledb.types.BuiltinTypesCatalogue; import org.rumbledb.types.FunctionSignature; import org.rumbledb.types.ItemType; @@ -328,6 +329,18 @@ public StaticContext visitVariableDeclaration(VariableDeclaration variableDeclar return argument; } + @Override + public StaticContext visitCopyDeclaration(CopyDeclaration copyDeclaration, StaticContext argument) { + this.visit(copyDeclaration.getSourceExpression(), argument); + // first pass. + argument.addVariable( + copyDeclaration.getVariableName(), + copyDeclaration.getSourceSequenceType(), + copyDeclaration.getMetadata() + ); + return argument; + } + @Override public StaticContext visitTypeDeclaration(TypeDeclaration declaration, StaticContext argument) { ItemType type = declaration.getDefinition(); diff --git a/src/main/java/org/rumbledb/compiler/VariableDependenciesVisitor.java b/src/main/java/org/rumbledb/compiler/VariableDependenciesVisitor.java index 0839359a9f..73d9101375 100644 --- a/src/main/java/org/rumbledb/compiler/VariableDependenciesVisitor.java +++ b/src/main/java/org/rumbledb/compiler/VariableDependenciesVisitor.java @@ -64,6 +64,7 @@ import org.rumbledb.expressions.primary.InlineFunctionExpression; import org.rumbledb.expressions.primary.NamedFunctionReferenceExpression; import org.rumbledb.expressions.primary.VariableReferenceExpression; +import org.rumbledb.expressions.update.CopyDeclaration; /** @@ -513,4 +514,11 @@ public Void visitFunctionDeclaration(FunctionDeclaration expression, Void argume addInputVariableDependencies(expression, getInputVariableDependencies(expression)); return null; } + + @Override + public Void visitCopyDeclaration(CopyDeclaration expression, Void argument) { + visit(expression.getSourceExpression(), null); + addInputVariableDependencies(expression, getInputVariableDependencies(expression.getSourceExpression())); + return null; + } } diff --git a/src/main/java/org/rumbledb/expressions/update/CopyDeclaration.java b/src/main/java/org/rumbledb/expressions/update/CopyDeclaration.java index 5a0a4d7a37..26540e1368 100644 --- a/src/main/java/org/rumbledb/expressions/update/CopyDeclaration.java +++ b/src/main/java/org/rumbledb/expressions/update/CopyDeclaration.java @@ -6,6 +6,7 @@ import org.rumbledb.expressions.AbstractNodeVisitor; import org.rumbledb.expressions.Expression; import org.rumbledb.expressions.Node; +import org.rumbledb.types.SequenceType; import java.util.Collections; import java.util.List; @@ -35,6 +36,10 @@ public Expression getSourceExpression() { return sourceExpression; } + public SequenceType getSourceSequenceType() { + return sourceExpression.getStaticSequenceType(); + } + @Override public List getChildren() { return Collections.singletonList(this.sourceExpression); From cac071226855b64f8cfffa9ede121a60e76adc5d Mon Sep 17 00:00:00 2001 From: dloughlin Date: Tue, 21 Mar 2023 17:04:15 +0100 Subject: [PATCH 020/119] Implement visit method in ExecutionModeVisitor for CopyDeclaration variable --- .../compiler/ExecutionModeVisitor.java | 13 +++++++++++ .../expressions/update/CopyDeclaration.java | 23 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java b/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java index b0bb68dd2f..8d99ed9d00 100644 --- a/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java +++ b/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java @@ -58,6 +58,7 @@ import org.rumbledb.expressions.primary.IntegerLiteralExpression; import org.rumbledb.expressions.primary.VariableReferenceExpression; import org.rumbledb.expressions.typing.ValidateTypeExpression; +import org.rumbledb.expressions.update.CopyDeclaration; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.misc.RangeOperationIterator; import org.rumbledb.types.BuiltinTypesCatalogue; @@ -433,6 +434,18 @@ public StaticContext visitVariableDeclaration(VariableDeclaration variableDeclar return argument; } + @Override + public StaticContext visitCopyDeclaration(CopyDeclaration copyDeclaration, StaticContext argument) { + this.visit(copyDeclaration.getSourceExpression(), null); + copyDeclaration.initHighestExecutionMode(this.visitorConfig); + // first pass. + argument.setVariableStorageMode( + copyDeclaration.getVariableName(), + copyDeclaration.getVariableHighestStorageMode(this.visitorConfig) + ); + return argument; + } + @Override public StaticContext visitProlog(Prolog prolog, StaticContext argument) { visitDescendants(prolog, argument); diff --git a/src/main/java/org/rumbledb/expressions/update/CopyDeclaration.java b/src/main/java/org/rumbledb/expressions/update/CopyDeclaration.java index 26540e1368..6caa7029e4 100644 --- a/src/main/java/org/rumbledb/expressions/update/CopyDeclaration.java +++ b/src/main/java/org/rumbledb/expressions/update/CopyDeclaration.java @@ -1,9 +1,12 @@ package org.rumbledb.expressions.update; +import org.rumbledb.compiler.VisitorConfig; import org.rumbledb.context.Name; import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.exceptions.OurBadException; import org.rumbledb.exceptions.SemanticException; 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; @@ -16,6 +19,9 @@ public class CopyDeclaration extends Node { private Name variableName; private Expression sourceExpression; + protected ExecutionMode variableHighestStorageMode = ExecutionMode.UNSET; + + public CopyDeclaration(Name variableName, Expression sourceExpression, ExceptionMetadata metadata @@ -40,6 +46,23 @@ public SequenceType getSourceSequenceType() { return sourceExpression.getStaticSequenceType(); } + @Override + public void initHighestExecutionMode(VisitorConfig visitorConfig) { + this.highestExecutionMode = ExecutionMode.LOCAL; + this.variableHighestStorageMode = ExecutionMode.LOCAL; + } + + public ExecutionMode getVariableHighestStorageMode(VisitorConfig visitorConfig) { + if ( + !visitorConfig.suppressErrorsForAccessingUnsetExecutionModes() + && this.variableHighestStorageMode == ExecutionMode.UNSET + ) { + throw new OurBadException("A copy variable storage mode is accessed without being set."); + } + return this.variableHighestStorageMode; + } + + @Override public List getChildren() { return Collections.singletonList(this.sourceExpression); From 7daaba1841f0231767b2c5b895ccc8c5cc4723ef Mon Sep 17 00:00:00 2001 From: dloughlin Date: Wed, 22 Mar 2023 12:34:46 +0100 Subject: [PATCH 021/119] Begin to implement static type inference for updating exprs --- .../ExpressionClassificationVisitor.java | 3 +- .../rumbledb/compiler/InferTypeVisitor.java | 72 +++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java b/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java index 788086877d..bcbbed297b 100644 --- a/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java @@ -1,6 +1,5 @@ package org.rumbledb.compiler; -import org.apache.hadoop.fs.Stat; import org.rumbledb.context.StaticContext; import org.rumbledb.expressions.AbstractNodeVisitor; import org.rumbledb.expressions.Expression; @@ -21,6 +20,8 @@ protected StaticContext defaultAction(Node node, StaticContext argument) { } if (node instanceof Expression && hasUpdatingChild) { node.setExpressionClassification(ExpressionClassification.UPDATING); + } else { + node.setExpressionClassification(ExpressionClassification.SIMPLE); } return staticContext; } diff --git a/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java b/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java index 5ea1d85c40..ad479a47bf 100644 --- a/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java +++ b/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java @@ -82,6 +82,7 @@ import org.rumbledb.expressions.typing.IsStaticallyExpression; import org.rumbledb.expressions.typing.TreatExpression; import org.rumbledb.expressions.typing.ValidateTypeExpression; +import org.rumbledb.expressions.update.*; import org.rumbledb.runtime.functions.input.FileSystemUtil; import org.rumbledb.types.BuiltinTypesCatalogue; import org.rumbledb.types.FieldDescriptor; @@ -659,6 +660,77 @@ public StaticContext visitTreatExpression(TreatExpression expression, StaticCont return argument; } + // endregion + + // region updating + + @Override + public StaticContext visitDeleteExpression(DeleteExpression expression, StaticContext argument) { + visitDescendants(expression, argument); + + SequenceType mainExprInferredType = expression.getMainExpression().getStaticSequenceType(); + SequenceType locExprInferredType = expression.getLocatorExpression().getStaticSequenceType(); + + basicChecks( + Arrays.asList(mainExprInferredType, locExprInferredType), + expression.getClass().getSimpleName(), + true, + true, + expression.getMetadata() + ); + + + return super.visitDeleteExpression(expression, argument); + } + + @Override + public StaticContext visitRenameExpression(RenameExpression expression, StaticContext argument) { + return super.visitRenameExpression(expression, argument); + } + + @Override + public StaticContext visitReplaceExpression(ReplaceExpression expression, StaticContext argument) { + return super.visitReplaceExpression(expression, argument); + } + + @Override + public StaticContext visitInsertExpression(InsertExpression expression, StaticContext argument) { + return super.visitInsertExpression(expression, argument); + } + + @Override + public StaticContext visitAppendExpression(AppendExpression expression, StaticContext argument) { + return super.visitAppendExpression(expression, argument); + } + + @Override + public StaticContext visitTransformExpression(TransformExpression expression, StaticContext argument) { + return super.visitTransformExpression(expression, argument); + } + + @Override + public StaticContext visitCopyDeclaration(CopyDeclaration expression, StaticContext argument) { + visitDescendants(expression, argument); + SequenceType declaredType = expression.getSourceSequenceType(); + SequenceType inferredType; + if (declaredType == null) { + inferredType = expression.getSourceExpression().getStaticSequenceType(); + } else { + inferredType = declaredType; + } + checkAndUpdateVariableStaticType( + declaredType, + inferredType, + argument, + expression.getClass().getSimpleName(), + expression.getVariableName(), + expression.getMetadata() + ); + + return argument; + } + + // endregion // region arithmetic From bd4aa8df107eaf8f4159401f7edecf80f6f47092 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Thu, 23 Mar 2023 15:31:29 +0100 Subject: [PATCH 022/119] Add keywords to grammar --- src/main/java/org/rumbledb/parser/Jsoniq.g4 | 50 ++++++++++++++++++--- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/rumbledb/parser/Jsoniq.g4 b/src/main/java/org/rumbledb/parser/Jsoniq.g4 index 67ef4db2ff..123c41c0a1 100644 --- a/src/main/java/org/rumbledb/parser/Jsoniq.g4 +++ b/src/main/java/org/rumbledb/parser/Jsoniq.g4 @@ -242,18 +242,18 @@ inlineFunctionExpr : 'function' '(' paramList? ')' ///////////////////////// Updating Expressions -insertExpr : 'insert' 'json' to_insert_expr=exprSingle 'into' main_expr=exprSingle ('at' 'position' pos_expr=exprSingle)? - | 'insert' 'json' pairConstructor ( ',' pairConstructor )* 'into' main_expr=exprSingle; +insertExpr : Kinsert Kjson to_insert_expr=exprSingle Kinto main_expr=exprSingle (Kat Kposition pos_expr=exprSingle)? + | Kinsert Kjson pairConstructor ( ',' pairConstructor )* Kinto main_expr=exprSingle; -deleteExpr : 'delete' 'json' updateLocator; +deleteExpr : Kdelete Kjson updateLocator; -renameExpr : 'rename' 'json' updateLocator 'as' name_expr=exprSingle; +renameExpr : Krename Kjson updateLocator Kas name_expr=exprSingle; -replaceExpr : 'replace' 'json' 'value' 'of' updateLocator 'with' replacer_expr=exprSingle; +replaceExpr : Kreplace Kjson Kvalue Kof updateLocator Kwith replacer_expr=exprSingle; -transformExpr : 'copy' 'json' copyDecl ( ',' copyDecl )* 'modify' mod_expr=exprSingle Kreturn ret_expr=exprSingle; +transformExpr : Kcopy Kjson copyDecl ( ',' copyDecl )* Kmodify mod_expr=exprSingle Kreturn ret_expr=exprSingle; -appendExpr : 'append' 'json' to_append_expr=exprSingle 'into' array_expr=exprSingle; +appendExpr : Kappend Kjson to_append_expr=exprSingle Kinto array_expr=exprSingle; updateLocator : main_expr=primaryExpr ( arrayLookup | objectLookup )+; @@ -340,6 +340,18 @@ keyWords : Kjsoniq | Ktrue | Kfalse | Ktype + | Kinsert + | Kdelete + | Krename + | Kreplace + | Kappend + | Kcopy + | Kmodify + | Kjson + | Kinto + | Kvalue + | Kwith + | Kposition ; ///////////////////////// literals @@ -448,6 +460,30 @@ Kitem : 'item'; Kvariable : 'variable'; +Kinsert : 'insert'; + +Kdelete : 'delete'; + +Krename : 'rename'; + +Kreplace : 'replace'; + +Kcopy : 'copy'; + +Kmodify : 'modify'; + +Kappend : 'append'; + +Kinto : 'into'; + +Kvalue : 'value'; + +Kjson : 'json'; + +Kwith : 'with'; + +Kposition : 'position'; + STRING : '"' (ESC | ~ ["\\])* '"'; fragment ESC : '\\' (["\\/bfnrt] | UNICODE); From e7f7a2aacd1809f8df23ee47d05da945b252a1f1 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Thu, 23 Mar 2023 20:19:44 +0100 Subject: [PATCH 023/119] Refactor CopyDeclaration to not be a node and move visit responsibilities into TransformExpression --- .../compiler/ExecutionModeVisitor.java | 23 +++++--- .../rumbledb/compiler/InferTypeVisitor.java | 42 +++++++------- .../compiler/StaticContextVisitor.java | 23 +++++--- .../rumbledb/compiler/TranslationVisitor.java | 15 +++-- .../compiler/VariableDependenciesVisitor.java | 12 +++- .../expressions/AbstractNodeVisitor.java | 4 -- .../expressions/update/CopyDeclaration.java | 56 ++----------------- .../update/TransformExpression.java | 48 ++++++++++++---- 8 files changed, 109 insertions(+), 114 deletions(-) diff --git a/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java b/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java index 8d99ed9d00..abc9d7c85c 100644 --- a/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java +++ b/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java @@ -59,6 +59,7 @@ import org.rumbledb.expressions.primary.VariableReferenceExpression; import org.rumbledb.expressions.typing.ValidateTypeExpression; import org.rumbledb.expressions.update.CopyDeclaration; +import org.rumbledb.expressions.update.TransformExpression; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.misc.RangeOperationIterator; import org.rumbledb.types.BuiltinTypesCatalogue; @@ -435,14 +436,20 @@ public StaticContext visitVariableDeclaration(VariableDeclaration variableDeclar } @Override - public StaticContext visitCopyDeclaration(CopyDeclaration copyDeclaration, StaticContext argument) { - this.visit(copyDeclaration.getSourceExpression(), null); - copyDeclaration.initHighestExecutionMode(this.visitorConfig); - // first pass. - argument.setVariableStorageMode( - copyDeclaration.getVariableName(), - copyDeclaration.getVariableHighestStorageMode(this.visitorConfig) - ); + public StaticContext visitTransformExpression(TransformExpression expression, StaticContext argument) { + for (CopyDeclaration copyDecl : expression.getCopyDeclarations()) { + this.visit(copyDecl.getSourceExpression(), null); + // first pass. + argument.setVariableStorageMode( + copyDecl.getVariableName(), + expression.getVariableHighestStorageMode(this.visitorConfig) + ); + } + expression.initHighestExecutionMode(this.visitorConfig); + + this.visit(expression.getModifyExpression(), argument); + this.visit(expression.getReturnExpression(), argument); + return argument; } diff --git a/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java b/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java index ad479a47bf..c5c9873042 100644 --- a/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java +++ b/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java @@ -708,27 +708,27 @@ public StaticContext visitTransformExpression(TransformExpression expression, St return super.visitTransformExpression(expression, argument); } - @Override - public StaticContext visitCopyDeclaration(CopyDeclaration expression, StaticContext argument) { - visitDescendants(expression, argument); - SequenceType declaredType = expression.getSourceSequenceType(); - SequenceType inferredType; - if (declaredType == null) { - inferredType = expression.getSourceExpression().getStaticSequenceType(); - } else { - inferredType = declaredType; - } - checkAndUpdateVariableStaticType( - declaredType, - inferredType, - argument, - expression.getClass().getSimpleName(), - expression.getVariableName(), - expression.getMetadata() - ); - - return argument; - } +// @Override +// public StaticContext visitCopyDeclaration(CopyDeclaration expression, StaticContext argument) { +// visitDescendants(expression, argument); +// SequenceType declaredType = expression.getSourceSequenceType(); +// SequenceType inferredType; +// if (declaredType == null) { +// inferredType = expression.getSourceExpression().getStaticSequenceType(); +// } else { +// inferredType = declaredType; +// } +// checkAndUpdateVariableStaticType( +// declaredType, +// inferredType, +// argument, +// expression.getClass().getSimpleName(), +// expression.getVariableName(), +// expression.getMetadata() +// ); +// +// return argument; +// } // endregion diff --git a/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java b/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java index 0aeb0e6f57..9253564e7d 100644 --- a/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java +++ b/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java @@ -55,6 +55,7 @@ import org.rumbledb.expressions.typing.TreatExpression; import org.rumbledb.expressions.typing.ValidateTypeExpression; import org.rumbledb.expressions.update.CopyDeclaration; +import org.rumbledb.expressions.update.TransformExpression; import org.rumbledb.types.BuiltinTypesCatalogue; import org.rumbledb.types.FunctionSignature; import org.rumbledb.types.ItemType; @@ -330,14 +331,20 @@ public StaticContext visitVariableDeclaration(VariableDeclaration variableDeclar } @Override - public StaticContext visitCopyDeclaration(CopyDeclaration copyDeclaration, StaticContext argument) { - this.visit(copyDeclaration.getSourceExpression(), argument); - // first pass. - argument.addVariable( - copyDeclaration.getVariableName(), - copyDeclaration.getSourceSequenceType(), - copyDeclaration.getMetadata() - ); + public StaticContext visitTransformExpression(TransformExpression expression, StaticContext argument) { + for (CopyDeclaration copyDecl : expression.getCopyDeclarations()) { + this.visit(copyDecl.getSourceExpression(), argument); + // first pass. + argument.addVariable( + copyDecl.getVariableName(), + copyDecl.getSourceSequenceType(), + expression.getMetadata() + ); + } + + this.visit(expression.getModifyExpression(), argument); + this.visit(expression.getReturnExpression(), argument); + return argument; } diff --git a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java index ed3b2017ce..1be368b06e 100644 --- a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java @@ -1198,7 +1198,13 @@ public Node visitReplaceExpr(JsoniqParser.ReplaceExprContext ctx) { @Override public Node visitTransformExpr(JsoniqParser.TransformExprContext ctx) { - List copyDecls = ctx.copyDecl().stream().map(this::visitCopyDecl).collect(Collectors.toList()); + List copyDecls = ctx.copyDecl().stream() + .map(copyDeclCtx -> { + Name var = ((VariableReferenceExpression) this.visitVarRef(copyDeclCtx.var_ref)).getVariableName(); + Expression expr = (Expression) this.visitExprSingle(copyDeclCtx.src_expr); + return new CopyDeclaration(var, expr); + }) + .collect(Collectors.toList()); Expression modifyExpression = (Expression) this.visitExprSingle(ctx.mod_expr); Expression returnExpression = (Expression) this.visitExprSingle(ctx.ret_expr); return new TransformExpression(copyDecls, modifyExpression, returnExpression, createMetadataFromContext(ctx)); @@ -1263,13 +1269,6 @@ public Expression getLocatorExpressionFromUpdateLocatorContext(JsoniqParser.Upda } } - @Override - public Node visitCopyDecl(JsoniqParser.CopyDeclContext ctx) { - Name var = ((VariableReferenceExpression) this.visitVarRef(ctx.var_ref)).getVariableName(); - Expression expr = (Expression) this.visitExprSingle(ctx.src_expr); - return new CopyDeclaration(var, expr, createMetadataFromContext(ctx)); - } - // endregion // region postfix diff --git a/src/main/java/org/rumbledb/compiler/VariableDependenciesVisitor.java b/src/main/java/org/rumbledb/compiler/VariableDependenciesVisitor.java index 73d9101375..f0df2c96c4 100644 --- a/src/main/java/org/rumbledb/compiler/VariableDependenciesVisitor.java +++ b/src/main/java/org/rumbledb/compiler/VariableDependenciesVisitor.java @@ -65,6 +65,7 @@ import org.rumbledb.expressions.primary.NamedFunctionReferenceExpression; import org.rumbledb.expressions.primary.VariableReferenceExpression; import org.rumbledb.expressions.update.CopyDeclaration; +import org.rumbledb.expressions.update.TransformExpression; /** @@ -516,9 +517,14 @@ public Void visitFunctionDeclaration(FunctionDeclaration expression, Void argume } @Override - public Void visitCopyDeclaration(CopyDeclaration expression, Void argument) { - visit(expression.getSourceExpression(), null); - addInputVariableDependencies(expression, getInputVariableDependencies(expression.getSourceExpression())); + public Void visitTransformExpression(TransformExpression expression, Void argument) { + for (CopyDeclaration copyDecl : expression.getCopyDeclarations()) { + visit(copyDecl.getSourceExpression(), null); + addInputVariableDependencies(expression, getInputVariableDependencies(copyDecl.getSourceExpression())); + } + visit(expression.getModifyExpression(), null); + visit(expression.getReturnExpression(), null); + return null; } } diff --git a/src/main/java/org/rumbledb/expressions/AbstractNodeVisitor.java b/src/main/java/org/rumbledb/expressions/AbstractNodeVisitor.java index c12f1fbae3..c402cd71f6 100644 --- a/src/main/java/org/rumbledb/expressions/AbstractNodeVisitor.java +++ b/src/main/java/org/rumbledb/expressions/AbstractNodeVisitor.java @@ -306,10 +306,6 @@ public T visitTransformExpression(TransformExpression expression, T argument) { return defaultAction(expression, argument); } - public T visitCopyDeclaration(CopyDeclaration expression, T argument) { - return defaultAction(expression, argument); - } - // endregion // region control diff --git a/src/main/java/org/rumbledb/expressions/update/CopyDeclaration.java b/src/main/java/org/rumbledb/expressions/update/CopyDeclaration.java index 6caa7029e4..c761021b82 100644 --- a/src/main/java/org/rumbledb/expressions/update/CopyDeclaration.java +++ b/src/main/java/org/rumbledb/expressions/update/CopyDeclaration.java @@ -1,34 +1,21 @@ package org.rumbledb.expressions.update; -import org.rumbledb.compiler.VisitorConfig; import org.rumbledb.context.Name; -import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.OurBadException; -import org.rumbledb.exceptions.SemanticException; -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; -import java.util.Collections; -import java.util.List; - -public class CopyDeclaration extends Node { +public class CopyDeclaration { private Name variableName; private Expression sourceExpression; - - protected ExecutionMode variableHighestStorageMode = ExecutionMode.UNSET; - + private SequenceType sequenceType; public CopyDeclaration(Name variableName, - Expression sourceExpression, - ExceptionMetadata metadata + Expression sourceExpression ) { - super(metadata); if (variableName == null) { - throw new SemanticException("Copy clause must have at least one variable", metadata); + throw new IllegalArgumentException("Copy clause var decls cannot be empty"); } this.variableName = variableName; this.sourceExpression = sourceExpression; @@ -46,39 +33,4 @@ public SequenceType getSourceSequenceType() { return sourceExpression.getStaticSequenceType(); } - @Override - public void initHighestExecutionMode(VisitorConfig visitorConfig) { - this.highestExecutionMode = ExecutionMode.LOCAL; - this.variableHighestStorageMode = ExecutionMode.LOCAL; - } - - public ExecutionMode getVariableHighestStorageMode(VisitorConfig visitorConfig) { - if ( - !visitorConfig.suppressErrorsForAccessingUnsetExecutionModes() - && this.variableHighestStorageMode == ExecutionMode.UNSET - ) { - throw new OurBadException("A copy variable storage mode is accessed without being set."); - } - return this.variableHighestStorageMode; - } - - - @Override - public List getChildren() { - return Collections.singletonList(this.sourceExpression); - } - - @Override - public T accept(AbstractNodeVisitor visitor, T argument) { - return visitor.visitCopyDeclaration(this, argument); - } - - @Override - public void serializeToJSONiq(StringBuffer sb, int indent) { - indentIt(sb, indent); - sb.append("copy $").append(this.variableName.toString()); - sb.append(" := ("); - this.sourceExpression.serializeToJSONiq(sb, 0); - sb.append(")\n"); - } } diff --git a/src/main/java/org/rumbledb/expressions/update/TransformExpression.java b/src/main/java/org/rumbledb/expressions/update/TransformExpression.java index 666ea53ea6..2fd9a94609 100644 --- a/src/main/java/org/rumbledb/expressions/update/TransformExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/TransformExpression.java @@ -1,10 +1,10 @@ package org.rumbledb.expressions.update; +import org.rumbledb.compiler.VisitorConfig; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.expressions.AbstractNodeVisitor; -import org.rumbledb.expressions.Expression; -import org.rumbledb.expressions.ExpressionClassification; -import org.rumbledb.expressions.Node; +import org.rumbledb.exceptions.OurBadException; +import org.rumbledb.exceptions.SemanticException; +import org.rumbledb.expressions.*; import java.util.List; import java.util.Objects; @@ -13,26 +13,35 @@ public class TransformExpression extends Expression { - private List copyDeclarations; + private List copyDeclarations; private Expression modifyExpression; private Expression returnExpression; - public TransformExpression(List copyDeclarations, + protected ExecutionMode variableHighestStorageMode = ExecutionMode.UNSET; + + public TransformExpression(List copyDeclarations, Expression modifyExpression, Expression returnExpression, ExceptionMetadata metadata ) { super(metadata); + if (copyDeclarations == null || copyDeclarations.isEmpty()) { + throw new SemanticException("Transform expression must have at least one variable", metadata); + } this.copyDeclarations = copyDeclarations; this.modifyExpression = modifyExpression; this.returnExpression = returnExpression; this.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); } - public List getCopyDeclarations() { + public List getCopyDeclarations() { return copyDeclarations; } + public List getCopySourceExpressions() { + return this.copyDeclarations.stream().filter(Objects::nonNull).map(CopyDeclaration::getSourceExpression).collect(Collectors.toList()); + } + public Expression getModifyExpression() { return modifyExpression; } @@ -41,9 +50,25 @@ public Expression getReturnExpression() { return returnExpression; } + @Override + public void initHighestExecutionMode(VisitorConfig visitorConfig) { + this.highestExecutionMode = ExecutionMode.LOCAL; + this.variableHighestStorageMode = ExecutionMode.LOCAL; + } + + public ExecutionMode getVariableHighestStorageMode(VisitorConfig visitorConfig) { + if ( + !visitorConfig.suppressErrorsForAccessingUnsetExecutionModes() + && this.variableHighestStorageMode == ExecutionMode.UNSET + ) { + throw new OurBadException("A copy variable storage mode is accessed without being set."); + } + return this.variableHighestStorageMode; + } + @Override public List getChildren() { - List result = this.copyDeclarations.stream().filter(Objects::nonNull).collect(Collectors.toList()); + List result = this.copyDeclarations.stream().filter(Objects::nonNull).map(CopyDeclaration::getSourceExpression).collect(Collectors.toList()); result.add(this.modifyExpression); result.add(this.returnExpression); return result; @@ -57,8 +82,11 @@ public T accept(AbstractNodeVisitor visitor, T argument) { @Override public void serializeToJSONiq(StringBuffer sb, int indent) { indentIt(sb, indent); - for (Node copyDecl : this.copyDeclarations) { - copyDecl.serializeToJSONiq(sb, 0); + for (CopyDeclaration copyDecl : this.copyDeclarations) { + sb.append("copy $").append(copyDecl.getVariableName().toString()); + sb.append(" := ("); + copyDecl.getSourceExpression().serializeToJSONiq(sb, 0); + sb.append(")\n"); } sb.append("\n modify "); this.modifyExpression.serializeToJSONiq(sb, 0); From 5da00a5c2fa6031cbefa530dfa14a8c7d1a47f5d Mon Sep 17 00:00:00 2001 From: dloughlin Date: Thu, 23 Mar 2023 20:54:22 +0100 Subject: [PATCH 024/119] Implement visit methods for updating exprs in InferTypeVisitor --- .../rumbledb/compiler/InferTypeVisitor.java | 81 +++++++++---------- 1 file changed, 39 insertions(+), 42 deletions(-) diff --git a/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java b/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java index c5c9873042..27b6f479b8 100644 --- a/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java +++ b/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java @@ -667,69 +667,66 @@ public StaticContext visitTreatExpression(TreatExpression expression, StaticCont @Override public StaticContext visitDeleteExpression(DeleteExpression expression, StaticContext argument) { visitDescendants(expression, argument); - - SequenceType mainExprInferredType = expression.getMainExpression().getStaticSequenceType(); - SequenceType locExprInferredType = expression.getLocatorExpression().getStaticSequenceType(); - - basicChecks( - Arrays.asList(mainExprInferredType, locExprInferredType), - expression.getClass().getSimpleName(), - true, - true, - expression.getMetadata() - ); - - - return super.visitDeleteExpression(expression, argument); + expression.setStaticSequenceType(SequenceType.EMPTY_SEQUENCE); + return argument; } @Override public StaticContext visitRenameExpression(RenameExpression expression, StaticContext argument) { - return super.visitRenameExpression(expression, argument); + visitDescendants(expression, argument); + expression.setStaticSequenceType(SequenceType.EMPTY_SEQUENCE); + return argument; } @Override public StaticContext visitReplaceExpression(ReplaceExpression expression, StaticContext argument) { - return super.visitReplaceExpression(expression, argument); + visitDescendants(expression, argument); + expression.setStaticSequenceType(SequenceType.EMPTY_SEQUENCE); + return argument; } @Override public StaticContext visitInsertExpression(InsertExpression expression, StaticContext argument) { - return super.visitInsertExpression(expression, argument); + visitDescendants(expression, argument); + expression.setStaticSequenceType(SequenceType.EMPTY_SEQUENCE); + return argument; } @Override public StaticContext visitAppendExpression(AppendExpression expression, StaticContext argument) { - return super.visitAppendExpression(expression, argument); + visitDescendants(expression, argument); + expression.setStaticSequenceType(SequenceType.EMPTY_SEQUENCE); + return argument; } @Override public StaticContext visitTransformExpression(TransformExpression expression, StaticContext argument) { - return super.visitTransformExpression(expression, argument); - } - -// @Override -// public StaticContext visitCopyDeclaration(CopyDeclaration expression, StaticContext argument) { -// visitDescendants(expression, argument); -// SequenceType declaredType = expression.getSourceSequenceType(); -// SequenceType inferredType; -// if (declaredType == null) { -// inferredType = expression.getSourceExpression().getStaticSequenceType(); -// } else { -// inferredType = declaredType; -// } -// checkAndUpdateVariableStaticType( -// declaredType, -// inferredType, -// argument, -// expression.getClass().getSimpleName(), -// expression.getVariableName(), -// expression.getMetadata() -// ); -// -// return argument; -// } + visitDescendants(expression, argument); + for (CopyDeclaration copyDecl : expression.getCopyDeclarations()) { + visit(copyDecl.getSourceExpression(), argument); + SequenceType declaredType = copyDecl.getSourceSequenceType(); + SequenceType inferredType; + if (declaredType == null) { + inferredType = copyDecl.getSourceExpression().getStaticSequenceType(); + } else { + inferredType = declaredType; + } + checkAndUpdateVariableStaticType( + declaredType, + inferredType, + argument, + expression.getClass().getSimpleName(), + copyDecl.getVariableName(), + expression.getMetadata() + ); + } + visit(expression.getModifyExpression(), argument); + visit(expression.getReturnExpression(), argument); + expression.setStaticSequenceType(SequenceType.EMPTY_SEQUENCE); + + return argument; + } // endregion From 8fc48778f090f05d74aff5b383f4c9ba019c2be3 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Thu, 23 Mar 2023 21:09:18 +0100 Subject: [PATCH 025/119] Restrict ExpressionClassification attribute to Expressions --- .../org/rumbledb/expressions/Expression.java | 16 ++++++-- .../java/org/rumbledb/expressions/Node.java | 41 ------------------- .../rumbledb/expressions/flowr/Clause.java | 1 - .../expressions/flowr/CountClause.java | 1 - .../rumbledb/expressions/flowr/ForClause.java | 1 - .../expressions/flowr/GroupByClause.java | 1 - .../rumbledb/expressions/flowr/LetClause.java | 1 - .../module/FunctionDeclaration.java | 1 - .../expressions/module/LibraryModule.java | 1 - .../module/VariableDeclaration.java | 1 - 10 files changed, 13 insertions(+), 52 deletions(-) diff --git a/src/main/java/org/rumbledb/expressions/Expression.java b/src/main/java/org/rumbledb/expressions/Expression.java index 6375eadcf7..af3d1a1b6a 100644 --- a/src/main/java/org/rumbledb/expressions/Expression.java +++ b/src/main/java/org/rumbledb/expressions/Expression.java @@ -103,7 +103,7 @@ public void setStaticSequenceType(SequenceType staticSequenceType) { } /** - * Gets the inferred expression classification, for use ... + * Gets the inferred expression classification of this node, for use ... * * @return Expression Classification of the expression. */ @@ -112,7 +112,7 @@ public ExpressionClassification getExpressionClassification() { } /** - * Sets the inferred expression classification, for use ... + * Sets the inferred expression classification of this node, for use ... * * @param expressionClassification the statically inferred expression classification. */ @@ -121,7 +121,7 @@ public void setExpressionClassification(ExpressionClassification expressionClass } /** - * Tells whether this expression is an updating expression or not. + * Tells whether this node is an updating expression or not. * * @return true if yes, false otherwise. */ @@ -129,6 +129,16 @@ public boolean isUpdating() { return this.expressionClassification.isUpdating(); } + /** + * Tells whether this node has an unset expression classification. + * + * @return true if yes, false otherwise. + */ + public boolean isUnset() { + return this.expressionClassification.isUnset(); + } + + @Override public void print(StringBuffer buffer, int indent) { for (int i = 0; i < indent; ++i) { diff --git a/src/main/java/org/rumbledb/expressions/Node.java b/src/main/java/org/rumbledb/expressions/Node.java index 2968a03335..1ebd4b5ab3 100644 --- a/src/main/java/org/rumbledb/expressions/Node.java +++ b/src/main/java/org/rumbledb/expressions/Node.java @@ -38,8 +38,6 @@ public abstract class Node { protected ExecutionMode highestExecutionMode = ExecutionMode.UNSET; - protected ExpressionClassification expressionClassification = ExpressionClassification.UNSET; - protected Node() { } @@ -114,44 +112,6 @@ public int numberOfUnsetExecutionModes() { return result; } - - /** - * Gets the inferred expression classification of this node, for use ... - * - * @return Expression Classification of the expression. - */ - public ExpressionClassification getExpressionClassification() { - return expressionClassification; - } - - /** - * Sets the inferred expression classification of this node, for use ... - * - * @param expressionClassification the statically inferred expression classification. - */ - public void setExpressionClassification(ExpressionClassification expressionClassification) { - this.expressionClassification = expressionClassification; - } - - /** - * Tells whether this node is an updating expression or not. - * - * @return true if yes, false otherwise. - */ - public boolean isUpdating() { - return this.expressionClassification.isUpdating(); - } - - /** - * Tells whether this node has an unset expression classification. - * - * @return true if yes, false otherwise. - */ - public boolean isUnset() { - return this.expressionClassification.isUnset(); - } - - /** * Accept method for the visitor pattern. * @@ -219,7 +179,6 @@ public void print(StringBuffer buffer, int indent) { } buffer.append(getClass().getSimpleName()); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + this.expressionClassification); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/flowr/Clause.java b/src/main/java/org/rumbledb/expressions/flowr/Clause.java index 132ea7ef41..25f6319acc 100644 --- a/src/main/java/org/rumbledb/expressions/flowr/Clause.java +++ b/src/main/java/org/rumbledb/expressions/flowr/Clause.java @@ -165,7 +165,6 @@ public void print(StringBuffer buffer, int indent) { } buffer.append(getClass().getSimpleName()); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + this.expressionClassification); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/flowr/CountClause.java b/src/main/java/org/rumbledb/expressions/flowr/CountClause.java index 558200b389..3392464788 100644 --- a/src/main/java/org/rumbledb/expressions/flowr/CountClause.java +++ b/src/main/java/org/rumbledb/expressions/flowr/CountClause.java @@ -58,7 +58,6 @@ public void print(StringBuffer buffer, int indent) { buffer.append(getClass().getSimpleName()); buffer.append(" (" + (this.countClauseVar) + ") "); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + this.expressionClassification); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/flowr/ForClause.java b/src/main/java/org/rumbledb/expressions/flowr/ForClause.java index d8c7b47713..435c0dadf1 100644 --- a/src/main/java/org/rumbledb/expressions/flowr/ForClause.java +++ b/src/main/java/org/rumbledb/expressions/flowr/ForClause.java @@ -139,7 +139,6 @@ public void print(StringBuffer buffer, int indent) { + ") " ); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + this.expressionClassification); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/flowr/GroupByClause.java b/src/main/java/org/rumbledb/expressions/flowr/GroupByClause.java index 36d1728a77..d4fb0ccd63 100644 --- a/src/main/java/org/rumbledb/expressions/flowr/GroupByClause.java +++ b/src/main/java/org/rumbledb/expressions/flowr/GroupByClause.java @@ -79,7 +79,6 @@ public void print(StringBuffer buffer, int indent) { } buffer.append(")"); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + this.expressionClassification); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/flowr/LetClause.java b/src/main/java/org/rumbledb/expressions/flowr/LetClause.java index 19a50fe9b6..b548b22efb 100644 --- a/src/main/java/org/rumbledb/expressions/flowr/LetClause.java +++ b/src/main/java/org/rumbledb/expressions/flowr/LetClause.java @@ -124,7 +124,6 @@ public void print(StringBuffer buffer, int indent) { ); buffer.append(")"); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + this.expressionClassification); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/module/FunctionDeclaration.java b/src/main/java/org/rumbledb/expressions/module/FunctionDeclaration.java index 59d9d540eb..0eace7ff8d 100644 --- a/src/main/java/org/rumbledb/expressions/module/FunctionDeclaration.java +++ b/src/main/java/org/rumbledb/expressions/module/FunctionDeclaration.java @@ -79,7 +79,6 @@ public void print(StringBuffer buffer, int indent) { } buffer.append("FunctionDeclaration " + this.getFunctionIdentifier()); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + this.expressionClassification); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); diff --git a/src/main/java/org/rumbledb/expressions/module/LibraryModule.java b/src/main/java/org/rumbledb/expressions/module/LibraryModule.java index ada6bf188d..08c4ca62e2 100644 --- a/src/main/java/org/rumbledb/expressions/module/LibraryModule.java +++ b/src/main/java/org/rumbledb/expressions/module/LibraryModule.java @@ -77,7 +77,6 @@ public void print(StringBuffer buffer, int indent) { } buffer.append("Library module " + this.namespace); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + this.expressionClassification); 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 2c03f54422..0b8f67be57 100644 --- a/src/main/java/org/rumbledb/expressions/module/VariableDeclaration.java +++ b/src/main/java/org/rumbledb/expressions/module/VariableDeclaration.java @@ -131,7 +131,6 @@ public void print(StringBuffer buffer, int indent) { + ") " ); buffer.append(" | " + this.highestExecutionMode); - buffer.append(" | " + this.expressionClassification); buffer.append("\n"); for (Node iterator : getChildren()) { iterator.print(buffer, indent + 1); From 2e5fafca7f7faed2e9dd3fe2be49b0c23b81a4d1 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sat, 25 Mar 2023 19:47:33 +0100 Subject: [PATCH 026/119] Fix recursion bug for ExpressionClassificationVisitor --- .../ExpressionClassificationVisitor.java | 163 ++++++++++++++---- .../org/rumbledb/compiler/VisitorHelpers.java | 3 +- .../org/rumbledb/expressions/Expression.java | 2 +- .../expressions/update/AppendExpression.java | 1 - .../expressions/update/DeleteExpression.java | 1 - .../expressions/update/InsertExpression.java | 1 - .../expressions/update/RenameExpression.java | 1 - .../expressions/update/ReplaceExpression.java | 1 - .../update/TransformExpression.java | 1 - 9 files changed, 136 insertions(+), 38 deletions(-) diff --git a/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java b/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java index bcbbed297b..ad45dc0ce9 100644 --- a/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java @@ -1,68 +1,171 @@ package org.rumbledb.compiler; import org.rumbledb.context.StaticContext; -import org.rumbledb.expressions.AbstractNodeVisitor; -import org.rumbledb.expressions.Expression; -import org.rumbledb.expressions.ExpressionClassification; -import org.rumbledb.expressions.Node; +import org.rumbledb.expressions.*; +import org.rumbledb.expressions.control.ConditionalExpression; +import org.rumbledb.expressions.control.SwitchExpression; +import org.rumbledb.expressions.control.TypeSwitchExpression; +import org.rumbledb.expressions.flowr.*; +import org.rumbledb.expressions.primary.FunctionCallExpression; import org.rumbledb.expressions.update.*; -public class ExpressionClassificationVisitor extends AbstractNodeVisitor { +import java.util.List; +import java.util.stream.Collectors; + +public class ExpressionClassificationVisitor extends AbstractNodeVisitor { @Override - protected StaticContext defaultAction(Node node, StaticContext argument) { - StaticContext staticContext = super.defaultAction(node, argument); - boolean hasUpdatingChild = false; - for (Node child : node.getChildren()) { - if (!hasUpdatingChild && child.isUpdating()) { - hasUpdatingChild = true; - } + protected ExpressionClassification defaultAction(Node node, ExpressionClassification argument) { + ExpressionClassification expressionClassification = this.visitDescendants(node, argument); + if (!(node instanceof Expression)) { + return expressionClassification; } - if (node instanceof Expression && hasUpdatingChild) { - node.setExpressionClassification(ExpressionClassification.UPDATING); - } else { - node.setExpressionClassification(ExpressionClassification.SIMPLE); + Expression expression = (Expression) node; + expression.setExpressionClassification(expressionClassification); + return expressionClassification; + } + + @Override + public ExpressionClassification visitDescendants(Node node, ExpressionClassification argument) { + List expressionClassifications = node.getChildren().stream().map(child -> this.visit(child, argument)).collect(Collectors.toList()); + return expressionClassifications.stream().anyMatch(ExpressionClassification::isUpdating) ? + ExpressionClassification.UPDATING : + ExpressionClassification.SIMPLE; + } + + @Override + public ExpressionClassification visitCommaExpression(CommaExpression expression, ExpressionClassification argument) { + return super.visitCommaExpression(expression, argument); + } + + // Region FLWOR + + @Override + public ExpressionClassification visitFlowrExpression(FlworExpression expression, ExpressionClassification argument) { + Clause clause = expression.getReturnClause().getFirstClause(); + ExpressionClassification result = argument; + while (clause != null) { + result = this.visit(clause, result); + clause = clause.getNextClause(); } - return staticContext; + result = expression.getReturnClause().getReturnExpr().getExpressionClassification(); + result = result.isUpdating() ? ExpressionClassification.UPDATING : result; + expression.setExpressionClassification(result); + return result; + } + + @Override + public ExpressionClassification visitForClause(ForClause expression, ExpressionClassification argument) { + return super.visitForClause(expression, argument); + } + + @Override + public ExpressionClassification visitLetClause(LetClause expression, ExpressionClassification argument) { + return super.visitLetClause(expression, argument); + } + + @Override + public ExpressionClassification visitGroupByClause(GroupByClause expression, ExpressionClassification argument) { + return super.visitGroupByClause(expression, argument); + } + + @Override + public ExpressionClassification visitOrderByClause(OrderByClause expression, ExpressionClassification argument) { + return super.visitOrderByClause(expression, argument); + } + + @Override + public ExpressionClassification visitWhereClause(WhereClause expression, ExpressionClassification argument) { + return super.visitWhereClause(expression, argument); + } + + @Override + public ExpressionClassification visitCountClause(CountClause expression, ExpressionClassification argument) { + return super.visitCountClause(expression, argument); + } + + @Override + public ExpressionClassification visitReturnClause(ReturnClause expression, ExpressionClassification argument) { + return super.visitReturnClause(expression, argument); + } + + // Endregion + + // Region Control + + @Override + public ExpressionClassification visitConditionalExpression(ConditionalExpression expression, ExpressionClassification argument) { + return super.visitConditionalExpression(expression, argument); + } + + @Override + public ExpressionClassification visitSwitchExpression(SwitchExpression expression, ExpressionClassification argument) { + return super.visitSwitchExpression(expression, argument); + } + + @Override + public ExpressionClassification visitTypeSwitchExpression(TypeSwitchExpression expression, ExpressionClassification argument) { + this.visitDescendants(expression, argument); +// boolean allVacuous = expression.getChildren().stream().allMatch(e -> e.) + return super.visitTypeSwitchExpression(expression, argument); } + // Endregion + + // Region Primary + + @Override + public ExpressionClassification visitFunctionCall(FunctionCallExpression expression, ExpressionClassification argument) { + // TODO: Make vacuous if call to fn:error? + return super.visitFunctionCall(expression, argument); + } + + // Endregion + + + // Region Basic Updating @Override - public StaticContext visitDeleteExpression(DeleteExpression expression, StaticContext argument) { + public ExpressionClassification visitDeleteExpression(DeleteExpression expression, ExpressionClassification argument) { + this.visitDescendants(expression, argument); expression.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); - return super.visitDeleteExpression(expression, argument); + return ExpressionClassification.BASIC_UPDATING; } @Override - public StaticContext visitRenameExpression(RenameExpression expression, StaticContext argument) { + public ExpressionClassification visitRenameExpression(RenameExpression expression, ExpressionClassification argument) { + this.visitDescendants(expression, argument); expression.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); - return super.visitRenameExpression(expression, argument); + return ExpressionClassification.BASIC_UPDATING; } @Override - public StaticContext visitReplaceExpression(ReplaceExpression expression, StaticContext argument) { + public ExpressionClassification visitReplaceExpression(ReplaceExpression expression, ExpressionClassification argument) { + this.visitDescendants(expression, argument); expression.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); - return super.visitReplaceExpression(expression, argument); + return ExpressionClassification.BASIC_UPDATING; } @Override - public StaticContext visitInsertExpression(InsertExpression expression, StaticContext argument) { + public ExpressionClassification visitInsertExpression(InsertExpression expression, ExpressionClassification argument) { + this.visitDescendants(expression, argument); expression.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); - return super.visitInsertExpression(expression, argument); + return ExpressionClassification.BASIC_UPDATING; } @Override - public StaticContext visitAppendExpression(AppendExpression expression, StaticContext argument) { + public ExpressionClassification visitAppendExpression(AppendExpression expression, ExpressionClassification argument) { + this.visitDescendants(expression, argument); expression.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); - return super.visitAppendExpression(expression, argument); + return ExpressionClassification.BASIC_UPDATING; } @Override - public StaticContext visitTransformExpression(TransformExpression expression, StaticContext argument) { - expression.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); + public ExpressionClassification visitTransformExpression(TransformExpression expression, ExpressionClassification argument) { this.visitDescendants(expression, argument); - return this.visitDescendants(expression, argument); + expression.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); + return ExpressionClassification.BASIC_UPDATING; } // Endregion diff --git a/src/main/java/org/rumbledb/compiler/VisitorHelpers.java b/src/main/java/org/rumbledb/compiler/VisitorHelpers.java index cca52aca9d..f728ec0ff4 100644 --- a/src/main/java/org/rumbledb/compiler/VisitorHelpers.java +++ b/src/main/java/org/rumbledb/compiler/VisitorHelpers.java @@ -23,6 +23,7 @@ import org.rumbledb.exceptions.OurBadException; import org.rumbledb.exceptions.ParsingException; import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.expressions.ExpressionClassification; import org.rumbledb.expressions.Node; import org.rumbledb.expressions.module.LibraryModule; import org.rumbledb.expressions.module.MainModule; @@ -368,7 +369,7 @@ private static void populateExpressionClassifications(Module module, RumbleRunti } ExpressionClassificationVisitor visitor = new ExpressionClassificationVisitor(); - visitor.visit(module, module.getStaticContext()); + visitor.visit(module, ExpressionClassification.SIMPLE); if (conf.isPrintIteratorTree()) { printTree(module, conf); diff --git a/src/main/java/org/rumbledb/expressions/Expression.java b/src/main/java/org/rumbledb/expressions/Expression.java index af3d1a1b6a..31d3ebdaf6 100644 --- a/src/main/java/org/rumbledb/expressions/Expression.java +++ b/src/main/java/org/rumbledb/expressions/Expression.java @@ -44,7 +44,7 @@ public abstract class Expression extends Node { protected SequenceType staticSequenceType; - protected ExpressionClassification expressionClassification = ExpressionClassification.SIMPLE; + protected ExpressionClassification expressionClassification = ExpressionClassification.UNSET; protected Expression(ExceptionMetadata metadata) { super(metadata); diff --git a/src/main/java/org/rumbledb/expressions/update/AppendExpression.java b/src/main/java/org/rumbledb/expressions/update/AppendExpression.java index f3ac0de302..0c54452f9c 100644 --- a/src/main/java/org/rumbledb/expressions/update/AppendExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/AppendExpression.java @@ -27,7 +27,6 @@ public AppendExpression(Expression arrayExpression, } this.arrayExpression = arrayExpression; this.toAppendExpression = toAppendExpression; - this.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); } public Expression getArrayExpression() { diff --git a/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java b/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java index df8f04c020..4003e4430f 100644 --- a/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java @@ -33,7 +33,6 @@ public DeleteExpression(Expression mainExpression, this.mainExpression = mainExpression; this.locatorExpression = locatorExpression; this.locatorKind = locatorKind; - this.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); } @Override diff --git a/src/main/java/org/rumbledb/expressions/update/InsertExpression.java b/src/main/java/org/rumbledb/expressions/update/InsertExpression.java index adc1c23dd8..100ad7b022 100644 --- a/src/main/java/org/rumbledb/expressions/update/InsertExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/InsertExpression.java @@ -25,7 +25,6 @@ public InsertExpression(Expression mainExpression, this.mainExpression = mainExpression; this.toInsertExpression = toInsertExpression; this.positionExpression = positionExpression; - this.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); } public boolean hasPositionExpression() { diff --git a/src/main/java/org/rumbledb/expressions/update/RenameExpression.java b/src/main/java/org/rumbledb/expressions/update/RenameExpression.java index 1224125cb7..43e74f3e09 100644 --- a/src/main/java/org/rumbledb/expressions/update/RenameExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/RenameExpression.java @@ -42,7 +42,6 @@ public RenameExpression(Expression mainExpression, this.locatorExpression = locatorExpression; this.nameExpression = nameExpression; this.locatorKind = locatorKind; - this.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); } @Override diff --git a/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java b/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java index d9a0b98259..377dd03f74 100644 --- a/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java @@ -39,7 +39,6 @@ public ReplaceExpression(Expression mainExpression, this.locatorExpression = locatorExpression; this.replacerExpression = replacerExpression; this.locatorKind = locatorKind; - this.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); } @Override diff --git a/src/main/java/org/rumbledb/expressions/update/TransformExpression.java b/src/main/java/org/rumbledb/expressions/update/TransformExpression.java index 2fd9a94609..afcf54573f 100644 --- a/src/main/java/org/rumbledb/expressions/update/TransformExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/TransformExpression.java @@ -31,7 +31,6 @@ public TransformExpression(List copyDeclarations, this.copyDeclarations = copyDeclarations; this.modifyExpression = modifyExpression; this.returnExpression = returnExpression; - this.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); } public List getCopyDeclarations() { From c1b0f0b9664cfabff66e85b80ce651506cb63d71 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sat, 25 Mar 2023 21:46:07 +0100 Subject: [PATCH 027/119] Implement FLWOR expression and clauses visit methods in ExpressionClassificationVisitor --- .../ExpressionClassificationVisitor.java | 27 ++++++++++++++++--- .../org/rumbledb/errorcodes/ErrorCode.java | 5 +++- ...idUpdatingExpressionPositionException.java | 13 +++++++++ 3 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/rumbledb/exceptions/InvalidUpdatingExpressionPositionException.java diff --git a/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java b/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java index ad45dc0ce9..af653a196b 100644 --- a/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java @@ -1,6 +1,7 @@ package org.rumbledb.compiler; import org.rumbledb.context.StaticContext; +import org.rumbledb.exceptions.InvalidUpdatingExpressionPositionException; import org.rumbledb.expressions.*; import org.rumbledb.expressions.control.ConditionalExpression; import org.rumbledb.expressions.control.SwitchExpression; @@ -56,31 +57,49 @@ public ExpressionClassification visitFlowrExpression(FlworExpression expression, @Override public ExpressionClassification visitForClause(ForClause expression, ExpressionClassification argument) { - return super.visitForClause(expression, argument); + ExpressionClassification result = this.visit(expression.getExpression(), argument); + if (result.isUpdating()) { + throw new InvalidUpdatingExpressionPositionException("Expression in For Clause can't be updating", expression.getMetadata()); + } + return result; } @Override public ExpressionClassification visitLetClause(LetClause expression, ExpressionClassification argument) { - return super.visitLetClause(expression, argument); + ExpressionClassification result = this.visit(expression.getExpression(), argument); + if (result.isUpdating()) { + throw new InvalidUpdatingExpressionPositionException("Expression in Let Clause can't be updating", expression.getMetadata()); + } + return result; } @Override public ExpressionClassification visitGroupByClause(GroupByClause expression, ExpressionClassification argument) { + // TODO: Add check for updating? return super.visitGroupByClause(expression, argument); } @Override public ExpressionClassification visitOrderByClause(OrderByClause expression, ExpressionClassification argument) { - return super.visitOrderByClause(expression, argument); + ExpressionClassification result = this.visitDescendants(expression, argument); + if (result.isUpdating()) { + throw new InvalidUpdatingExpressionPositionException("Expression in Order By Clause can't be updating", expression.getMetadata()); + } + return result; } @Override public ExpressionClassification visitWhereClause(WhereClause expression, ExpressionClassification argument) { - return super.visitWhereClause(expression, argument); + ExpressionClassification result = this.visitDescendants(expression, argument); + if (result.isUpdating()) { + throw new InvalidUpdatingExpressionPositionException("Expression in Where Clause can't be updating", expression.getMetadata()); + } + return result; } @Override public ExpressionClassification visitCountClause(CountClause expression, ExpressionClassification argument) { + // TODO: Add check for updating? return super.visitCountClause(expression, argument); } diff --git a/src/main/java/org/rumbledb/errorcodes/ErrorCode.java b/src/main/java/org/rumbledb/errorcodes/ErrorCode.java index 39fb5a5084..2a9d69ca75 100644 --- a/src/main/java/org/rumbledb/errorcodes/ErrorCode.java +++ b/src/main/java/org/rumbledb/errorcodes/ErrorCode.java @@ -120,7 +120,10 @@ public enum ErrorCode { AtomizationError("FOTY0012"), UnexpectedFunctionItem("FOTY0015"), ArithmeticOverflowOrUnderflow("FODT0002"), - InvalidTimezoneValue("FODT0003"); + InvalidTimezoneValue("FODT0003"), + + InvalidUpdatingExpressionPositionErrorCode("XUST0001"), + SimpleExpressionMustBeVacuousErrorCode("XUST0002"); diff --git a/src/main/java/org/rumbledb/exceptions/InvalidUpdatingExpressionPositionException.java b/src/main/java/org/rumbledb/exceptions/InvalidUpdatingExpressionPositionException.java new file mode 100644 index 0000000000..63546f4031 --- /dev/null +++ b/src/main/java/org/rumbledb/exceptions/InvalidUpdatingExpressionPositionException.java @@ -0,0 +1,13 @@ +package org.rumbledb.exceptions; + +import org.rumbledb.errorcodes.ErrorCode; + +public class InvalidUpdatingExpressionPositionException extends RumbleException { + + private static final long serialVersionUID = 1L; + + public InvalidUpdatingExpressionPositionException(String message, ExceptionMetadata metadata) { + super(message, ErrorCode.InvalidUpdatingExpressionPositionErrorCode, metadata); + } + +} From 87c7b30fda07ffe42fd39dfa80ee24fa3d39fe5f Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sat, 25 Mar 2023 22:04:50 +0100 Subject: [PATCH 028/119] Implement TypeSwitch expression visit method in ExpressionClassificationVisitor --- .../ExpressionClassificationVisitor.java | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java b/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java index af653a196b..722f92881e 100644 --- a/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java @@ -6,10 +6,12 @@ import org.rumbledb.expressions.control.ConditionalExpression; import org.rumbledb.expressions.control.SwitchExpression; import org.rumbledb.expressions.control.TypeSwitchExpression; +import org.rumbledb.expressions.control.TypeswitchCase; import org.rumbledb.expressions.flowr.*; import org.rumbledb.expressions.primary.FunctionCallExpression; import org.rumbledb.expressions.update.*; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -83,7 +85,7 @@ public ExpressionClassification visitGroupByClause(GroupByClause expression, Exp public ExpressionClassification visitOrderByClause(OrderByClause expression, ExpressionClassification argument) { ExpressionClassification result = this.visitDescendants(expression, argument); if (result.isUpdating()) { - throw new InvalidUpdatingExpressionPositionException("Expression in Order By Clause can't be updating", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException("Expressions in Order By Clause can't be updating", expression.getMetadata()); } return result; } @@ -124,9 +126,30 @@ public ExpressionClassification visitSwitchExpression(SwitchExpression expressio @Override public ExpressionClassification visitTypeSwitchExpression(TypeSwitchExpression expression, ExpressionClassification argument) { - this.visitDescendants(expression, argument); -// boolean allVacuous = expression.getChildren().stream().allMatch(e -> e.) - return super.visitTypeSwitchExpression(expression, argument); + ExpressionClassification condResult = this.visit(expression.getTestCondition(), argument); + if (condResult.isUpdating()) { + throw new InvalidUpdatingExpressionPositionException("Condition expression in Type Switch expression can't be updating", expression.getMetadata()); + } + + List branchResults = new ArrayList<>(); + branchResults.add(this.visit(expression.getDefaultCase().getReturnExpression(), argument)); + for (TypeswitchCase branch : expression.getCases()) { + branchResults.add(this.visit(branch.getReturnExpression(), argument)); + } + boolean anyUpdating = branchResults.stream().anyMatch(ExpressionClassification::isUpdating); + if (anyUpdating && !branchResults.stream().allMatch(e -> e.isUpdating() || e.isVacuous())) { + throw new InvalidUpdatingExpressionPositionException("All branch expressions in Type Switch expression must be Simple or Updating/Vacuous", expression.getMetadata()); + } + + if (anyUpdating) { + expression.setExpressionClassification(ExpressionClassification.UPDATING); + } else if (branchResults.stream().allMatch(ExpressionClassification::isVacuous)) { + expression.setExpressionClassification(ExpressionClassification.VACUOUS); + } else { + expression.setExpressionClassification(ExpressionClassification.SIMPLE); + } + + return expression.getExpressionClassification(); } // Endregion From c8c4c61b3ae06c308bce398c180cd57a4a0f4f7f Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sun, 26 Mar 2023 01:23:25 +0100 Subject: [PATCH 029/119] Implement Comma and Conditional expression visit methods in ExpressionClassificationVisitor --- .../ExpressionClassificationVisitor.java | 55 ++++++++++++++++--- 1 file changed, 47 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java b/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java index 722f92881e..bcc890a493 100644 --- a/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java @@ -38,7 +38,23 @@ public ExpressionClassification visitDescendants(Node node, ExpressionClassifica @Override public ExpressionClassification visitCommaExpression(CommaExpression expression, ExpressionClassification argument) { - return super.visitCommaExpression(expression, argument); + List results = expression.getChildren().stream().map(n -> this.visit(n, argument)).collect(Collectors.toList()); + boolean anyUpdating = results.stream().anyMatch(ExpressionClassification::isUpdating); + boolean allUpdatingOrVacuous = results.stream().allMatch(e -> e.isVacuous() || e.isUpdating()); + + if (anyUpdating && !allUpdatingOrVacuous) { + throw new InvalidUpdatingExpressionPositionException("All expressions in Comma separated expressions must only be Simple expressions or only be Updating/Vacuous expressions", expression.getMetadata()); + } + + if (anyUpdating) { + expression.setExpressionClassification(ExpressionClassification.UPDATING); + } else if (results.stream().allMatch(ExpressionClassification::isVacuous)) { + expression.setExpressionClassification(ExpressionClassification.VACUOUS); + } else { + expression.setExpressionClassification(ExpressionClassification.SIMPLE); + } + + return expression.getExpressionClassification(); } // Region FLWOR @@ -61,7 +77,7 @@ public ExpressionClassification visitFlowrExpression(FlworExpression expression, public ExpressionClassification visitForClause(ForClause expression, ExpressionClassification argument) { ExpressionClassification result = this.visit(expression.getExpression(), argument); if (result.isUpdating()) { - throw new InvalidUpdatingExpressionPositionException("Expression in For Clause can't be updating", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException("Expression in For Clause cannot be updating", expression.getMetadata()); } return result; } @@ -70,7 +86,7 @@ public ExpressionClassification visitForClause(ForClause expression, ExpressionC public ExpressionClassification visitLetClause(LetClause expression, ExpressionClassification argument) { ExpressionClassification result = this.visit(expression.getExpression(), argument); if (result.isUpdating()) { - throw new InvalidUpdatingExpressionPositionException("Expression in Let Clause can't be updating", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException("Expression in Let Clause cannot be updating", expression.getMetadata()); } return result; } @@ -85,7 +101,7 @@ public ExpressionClassification visitGroupByClause(GroupByClause expression, Exp public ExpressionClassification visitOrderByClause(OrderByClause expression, ExpressionClassification argument) { ExpressionClassification result = this.visitDescendants(expression, argument); if (result.isUpdating()) { - throw new InvalidUpdatingExpressionPositionException("Expressions in Order By Clause can't be updating", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException("Expressions in Order By Clause cannot be updating", expression.getMetadata()); } return result; } @@ -94,7 +110,7 @@ public ExpressionClassification visitOrderByClause(OrderByClause expression, Exp public ExpressionClassification visitWhereClause(WhereClause expression, ExpressionClassification argument) { ExpressionClassification result = this.visitDescendants(expression, argument); if (result.isUpdating()) { - throw new InvalidUpdatingExpressionPositionException("Expression in Where Clause can't be updating", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException("Expression in Where Clause cannot be updating", expression.getMetadata()); } return result; } @@ -116,7 +132,30 @@ public ExpressionClassification visitReturnClause(ReturnClause expression, Expre @Override public ExpressionClassification visitConditionalExpression(ConditionalExpression expression, ExpressionClassification argument) { - return super.visitConditionalExpression(expression, argument); + ExpressionClassification condResult = this.visit(expression.getCondition(), argument); + if (condResult.isUpdating()) { + throw new InvalidUpdatingExpressionPositionException("Condition expression in Conditional expression cannot be updating", expression.getMetadata()); + } + + ExpressionClassification thenResult = this.visit(expression.getBranch(), argument); + ExpressionClassification elseResult = this.visit(expression.getElseBranch(), argument); + + boolean oneUpdating = thenResult.isUpdating() || elseResult.isUpdating(); + boolean bothUpdatingOrVacuous = (thenResult.isUpdating() || thenResult.isVacuous()) && (elseResult.isVacuous()|| elseResult.isUpdating()); + + if (oneUpdating && !bothUpdatingOrVacuous) { + throw new InvalidUpdatingExpressionPositionException("Both branch expressions in Conditional expression must only be Simple expressions or only be Updating/Vacuous expressions", expression.getMetadata()); + } + + if (oneUpdating) { + expression.setExpressionClassification(ExpressionClassification.UPDATING); + } else if (thenResult.isVacuous() && elseResult.isVacuous()) { + expression.setExpressionClassification(ExpressionClassification.VACUOUS); + } else { + expression.setExpressionClassification(ExpressionClassification.SIMPLE); + } + + return expression.getExpressionClassification(); } @Override @@ -128,7 +167,7 @@ public ExpressionClassification visitSwitchExpression(SwitchExpression expressio public ExpressionClassification visitTypeSwitchExpression(TypeSwitchExpression expression, ExpressionClassification argument) { ExpressionClassification condResult = this.visit(expression.getTestCondition(), argument); if (condResult.isUpdating()) { - throw new InvalidUpdatingExpressionPositionException("Condition expression in Type Switch expression can't be updating", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException("Condition expression in Type Switch expression cannot be updating", expression.getMetadata()); } List branchResults = new ArrayList<>(); @@ -138,7 +177,7 @@ public ExpressionClassification visitTypeSwitchExpression(TypeSwitchExpression e } boolean anyUpdating = branchResults.stream().anyMatch(ExpressionClassification::isUpdating); if (anyUpdating && !branchResults.stream().allMatch(e -> e.isUpdating() || e.isVacuous())) { - throw new InvalidUpdatingExpressionPositionException("All branch expressions in Type Switch expression must be Simple or Updating/Vacuous", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException("All branch expressions in Type Switch expression must only be Simple expressions or only be Updating/Vacuous expressions", expression.getMetadata()); } if (anyUpdating) { From fba9ab9896468a8311718a9f53f342b4da415619 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sun, 26 Mar 2023 03:08:18 +0200 Subject: [PATCH 030/119] Implement basic updating expression visit methods in ExpressionClassificationVisitor --- .../ExpressionClassificationVisitor.java | 107 +++++++++++++++++- ...impleExpressionMustBeVacuousException.java | 12 ++ .../expressions/ExpressionClassification.java | 2 +- .../expressions/update/ReplaceExpression.java | 1 - 4 files changed, 114 insertions(+), 8 deletions(-) create mode 100644 src/main/java/org/rumbledb/exceptions/SimpleExpressionMustBeVacuousException.java diff --git a/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java b/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java index bcc890a493..8412594ef0 100644 --- a/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java @@ -2,12 +2,14 @@ import org.rumbledb.context.StaticContext; import org.rumbledb.exceptions.InvalidUpdatingExpressionPositionException; +import org.rumbledb.exceptions.SimpleExpressionMustBeVacuousException; import org.rumbledb.expressions.*; import org.rumbledb.expressions.control.ConditionalExpression; import org.rumbledb.expressions.control.SwitchExpression; import org.rumbledb.expressions.control.TypeSwitchExpression; import org.rumbledb.expressions.control.TypeswitchCase; import org.rumbledb.expressions.flowr.*; +import org.rumbledb.expressions.module.VariableDeclaration; import org.rumbledb.expressions.primary.FunctionCallExpression; import org.rumbledb.expressions.update.*; @@ -209,45 +211,138 @@ public ExpressionClassification visitFunctionCall(FunctionCallExpression express @Override public ExpressionClassification visitDeleteExpression(DeleteExpression expression, ExpressionClassification argument) { - this.visitDescendants(expression, argument); + ExpressionClassification mainResult = this.visit(expression.getMainExpression(), argument); + if (!mainResult.isSimple()) { + throw new InvalidUpdatingExpressionPositionException("Main expression in Delete expression must be Simple", expression.getMetadata()); + } + + ExpressionClassification locatorResult = this.visit(expression.getLocatorExpression(), argument); + if (!locatorResult.isSimple()) { + throw new InvalidUpdatingExpressionPositionException("Locator expression in Delete expression must be Simple", expression.getMetadata()); + } + expression.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); return ExpressionClassification.BASIC_UPDATING; } @Override public ExpressionClassification visitRenameExpression(RenameExpression expression, ExpressionClassification argument) { - this.visitDescendants(expression, argument); + ExpressionClassification mainResult = this.visit(expression.getMainExpression(), argument); + if (!mainResult.isSimple()) { + throw new InvalidUpdatingExpressionPositionException("Main expression in Rename expression must be Simple", expression.getMetadata()); + } + + ExpressionClassification locatorResult = this.visit(expression.getLocatorExpression(), argument); + if (!locatorResult.isSimple()) { + throw new InvalidUpdatingExpressionPositionException("Locator expression in Rename expression must be Simple", expression.getMetadata()); + } + + ExpressionClassification replacerResult = this.visit(expression.getNameExpression(), argument); + if (!replacerResult.isSimple()) { + throw new InvalidUpdatingExpressionPositionException("Replacer expression in Rename expression must be Simple", expression.getMetadata()); + } + expression.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); return ExpressionClassification.BASIC_UPDATING; } @Override public ExpressionClassification visitReplaceExpression(ReplaceExpression expression, ExpressionClassification argument) { - this.visitDescendants(expression, argument); + ExpressionClassification mainResult = this.visit(expression.getMainExpression(), argument); + if (!mainResult.isSimple()) { + throw new InvalidUpdatingExpressionPositionException("Main expression in Replace expression must be Simple", expression.getMetadata()); + } + + ExpressionClassification locatorResult = this.visit(expression.getLocatorExpression(), argument); + if (!locatorResult.isSimple()) { + throw new InvalidUpdatingExpressionPositionException("Locator expression in Replace expression must be Simple", expression.getMetadata()); + } + + ExpressionClassification replacerResult = this.visit(expression.getReplacerExpression(), argument); + if (!replacerResult.isSimple()) { + throw new InvalidUpdatingExpressionPositionException("Replacer expression in Replace expression must be Simple", expression.getMetadata()); + } + expression.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); return ExpressionClassification.BASIC_UPDATING; } @Override public ExpressionClassification visitInsertExpression(InsertExpression expression, ExpressionClassification argument) { - this.visitDescendants(expression, argument); + ExpressionClassification mainResult = this.visit(expression.getMainExpression(), argument); + if (!mainResult.isSimple()) { + throw new InvalidUpdatingExpressionPositionException("Main expression in Insert expression must be Simple", expression.getMetadata()); + } + + ExpressionClassification toInsertResult = this.visit(expression.getToInsertExpression(), argument); + if (!toInsertResult.isSimple()) { + throw new InvalidUpdatingExpressionPositionException("toInsert expression in Insert expression must be Simple", expression.getMetadata()); + } + + if (expression.hasPositionExpression()) { + ExpressionClassification positionResult = this.visit(expression.getPositionExpression(), argument); + if (!positionResult.isSimple()) { + throw new InvalidUpdatingExpressionPositionException("Position expression in Insert expression must be Simple", expression.getMetadata()); + } + } + expression.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); return ExpressionClassification.BASIC_UPDATING; } @Override public ExpressionClassification visitAppendExpression(AppendExpression expression, ExpressionClassification argument) { - this.visitDescendants(expression, argument); + ExpressionClassification arrayResult = this.visit(expression.getArrayExpression(), argument); + if (!arrayResult.isSimple()) { + throw new InvalidUpdatingExpressionPositionException("Array expression in Append expression must be Simple", expression.getMetadata()); + } + + ExpressionClassification toAppendResult = this.visit(expression.getToAppendExpression(), argument); + if (!toAppendResult.isSimple()) { + throw new InvalidUpdatingExpressionPositionException("toAppend expression in Append expression must be Simple", expression.getMetadata()); + } + expression.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); return ExpressionClassification.BASIC_UPDATING; } @Override public ExpressionClassification visitTransformExpression(TransformExpression expression, ExpressionClassification argument) { - this.visitDescendants(expression, argument); + + for (CopyDeclaration copyDecl : expression.getCopyDeclarations()) { + ExpressionClassification copyDeclResult = this.visit(copyDecl.getSourceExpression(), argument); + if (!copyDeclResult.isSimple()) { + throw new InvalidUpdatingExpressionPositionException("Source expression in Copy Declaration must be Simple", expression.getMetadata()); + } + } + + ExpressionClassification modifyResult = this.visit(expression.getModifyExpression(), argument); + if (!(modifyResult.isUpdating() || modifyResult.isVacuous())) { + throw new SimpleExpressionMustBeVacuousException("Modify expression must be Updating or Vacuous", expression.getMetadata()); + } + + ExpressionClassification returnResult = this.visit(expression.getReturnExpression(), argument); + if (!returnResult.isSimple()) { + throw new InvalidUpdatingExpressionPositionException("Return expression of Transform expression must be Simple", expression.getMetadata()); + } + expression.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); return ExpressionClassification.BASIC_UPDATING; } // Endregion + + + @Override + public ExpressionClassification visitVariableDeclaration(VariableDeclaration expression, ExpressionClassification argument) { + if (expression.getExpression() == null) { + return argument; + } + + ExpressionClassification result = this.visit(expression.getExpression(), argument); + if (!result.isSimple()) { + throw new InvalidUpdatingExpressionPositionException("Initialising expression in variable declaration must be Simple", expression.getMetadata()); + } + return ExpressionClassification.SIMPLE; + } } diff --git a/src/main/java/org/rumbledb/exceptions/SimpleExpressionMustBeVacuousException.java b/src/main/java/org/rumbledb/exceptions/SimpleExpressionMustBeVacuousException.java new file mode 100644 index 0000000000..95aa26fbc2 --- /dev/null +++ b/src/main/java/org/rumbledb/exceptions/SimpleExpressionMustBeVacuousException.java @@ -0,0 +1,12 @@ +package org.rumbledb.exceptions; + +import org.rumbledb.errorcodes.ErrorCode; + +public class SimpleExpressionMustBeVacuousException extends RumbleException { + + private static final long serialVersionUID = 1L; + + public SimpleExpressionMustBeVacuousException(String message, ExceptionMetadata metadata) { + super(message, ErrorCode.SimpleExpressionMustBeVacuousErrorCode, metadata); + } +} diff --git a/src/main/java/org/rumbledb/expressions/ExpressionClassification.java b/src/main/java/org/rumbledb/expressions/ExpressionClassification.java index 99905461a9..f852a1f3de 100644 --- a/src/main/java/org/rumbledb/expressions/ExpressionClassification.java +++ b/src/main/java/org/rumbledb/expressions/ExpressionClassification.java @@ -30,7 +30,7 @@ public boolean isUpdating() { } public boolean isSimple() { - return this == ExpressionClassification.SIMPLE; + return !isUpdating(); } public boolean isVacuous() { diff --git a/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java b/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java index 377dd03f74..fd26d0c04c 100644 --- a/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java @@ -4,7 +4,6 @@ import org.rumbledb.exceptions.OurBadException; import org.rumbledb.expressions.AbstractNodeVisitor; import org.rumbledb.expressions.Expression; -import org.rumbledb.expressions.ExpressionClassification; import org.rumbledb.expressions.Node; import java.util.Arrays; From 28d8fccee4ae0d225208ed8707fb4330b6dc3fa0 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sun, 26 Mar 2023 03:25:34 +0200 Subject: [PATCH 031/119] Ensure unaccounted for expression operands must not be updating --- .../ExpressionClassificationVisitor.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java b/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java index 8412594ef0..7d463eaa73 100644 --- a/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java @@ -22,9 +22,14 @@ public class ExpressionClassificationVisitor extends AbstractNodeVisitor expressionClassifications = node.getChildren().stream().map(child -> this.visit(child, argument)).collect(Collectors.toList()); - return expressionClassifications.stream().anyMatch(ExpressionClassification::isUpdating) ? + ExpressionClassification result = expressionClassifications.stream().anyMatch(ExpressionClassification::isUpdating) ? ExpressionClassification.UPDATING : ExpressionClassification.SIMPLE; + +// if (result.isUpdating()) { +// throw new InvalidUpdatingExpressionPositionException("Operand of expression is Updating when it should be Simple or Vacuous", node.getMetadata()); +// } + + return result; } @Override @@ -125,7 +136,10 @@ public ExpressionClassification visitCountClause(CountClause expression, Express @Override public ExpressionClassification visitReturnClause(ReturnClause expression, ExpressionClassification argument) { - return super.visitReturnClause(expression, argument); + if (expression.getReturnExpr() == null) { + return argument; + } + return this.visit(expression.getReturnExpr(), argument); } // Endregion From f3f2728ce3288395c9e1e1d894246d1bec482e0e Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sun, 26 Mar 2023 14:49:57 +0200 Subject: [PATCH 032/119] Add antlr updated files --- .../java/org/rumbledb/parser/Jsoniq.tokens | 322 +- .../rumbledb/parser/JsoniqBaseVisitor.java | 58 +- .../java/org/rumbledb/parser/JsoniqLexer.java | 878 ++--- .../org/rumbledb/parser/JsoniqLexer.tokens | 322 +- .../org/rumbledb/parser/JsoniqParser.java | 3099 ++++++++++------- .../org/rumbledb/parser/JsoniqVisitor.java | 50 +- 6 files changed, 2828 insertions(+), 1901 deletions(-) diff --git a/src/main/java/org/rumbledb/parser/Jsoniq.tokens b/src/main/java/org/rumbledb/parser/Jsoniq.tokens index 665fe05255..695f08ba0e 100644 --- a/src/main/java/org/rumbledb/parser/Jsoniq.tokens +++ b/src/main/java/org/rumbledb/parser/Jsoniq.tokens @@ -58,71 +58,82 @@ T__56=57 T__57=58 T__58=59 T__59=60 -T__60=61 -Kfor=62 -Klet=63 -Kwhere=64 -Kgroup=65 -Kby=66 -Korder=67 -Kreturn=68 -Kif=69 -Kin=70 -Kas=71 -Kat=72 -Kallowing=73 -Kempty=74 -Kcount=75 -Kstable=76 -Kascending=77 -Kdescending=78 -Ksome=79 -Kevery=80 -Ksatisfies=81 -Kcollation=82 -Kgreatest=83 -Kleast=84 -Kswitch=85 -Kcase=86 -Ktry=87 -Kcatch=88 -Kdefault=89 -Kthen=90 -Kelse=91 -Ktypeswitch=92 -Kor=93 -Kand=94 -Knot=95 -Kto=96 -Kinstance=97 -Kof=98 -Kstatically=99 -Kis=100 -Ktreat=101 -Kcast=102 -Kcastable=103 -Kversion=104 -Kjsoniq=105 -Kunordered=106 -Ktrue=107 -Kfalse=108 -Ktype=109 -Kdeclare=110 -Kcontext=111 -Kitem=112 -Kvariable=113 -STRING=114 -ArgumentPlaceholder=115 -NullLiteral=116 -Literal=117 -NumericLiteral=118 -IntegerLiteral=119 -DecimalLiteral=120 -DoubleLiteral=121 -WS=122 -NCName=123 -XQComment=124 -ContentChar=125 +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 +Kunordered=105 +Ktrue=106 +Kfalse=107 +Ktype=108 +Kdeclare=109 +Kcontext=110 +Kitem=111 +Kvariable=112 +Kinsert=113 +Kdelete=114 +Krename=115 +Kreplace=116 +Kcopy=117 +Kmodify=118 +Kappend=119 +Kinto=120 +Kvalue=121 +Kjson=122 +Kwith=123 +Kposition=124 +STRING=125 +ArgumentPlaceholder=126 +NullLiteral=127 +Literal=128 +NumericLiteral=129 +IntegerLiteral=130 +DecimalLiteral=131 +DoubleLiteral=132 +WS=133 +NCName=134 +XQComment=135 +ContentChar=136 ';'=1 'module'=2 'namespace'=3 @@ -153,88 +164,99 @@ ContentChar=125 'jsound'=28 'compact'=29 'verbose'=30 -'json'=31 -'schema'=32 -'$'=33 -'|'=34 -'*'=35 -'eq'=36 -'ne'=37 -'lt'=38 -'le'=39 -'gt'=40 -'ge'=41 -'!='=42 -'<'=43 -'<='=44 -'>'=45 -'>='=46 -'||'=47 -'+'=48 -'-'=49 -'div'=50 -'idiv'=51 -'mod'=52 -'validate'=53 -'!'=54 -'['=55 -']'=56 -'.'=57 -'$$'=58 -'#'=59 -'{|'=60 -'|}'=61 -'for'=62 -'let'=63 -'where'=64 -'group'=65 -'by'=66 -'order'=67 -'return'=68 -'if'=69 -'in'=70 -'as'=71 -'at'=72 -'allowing'=73 -'empty'=74 -'count'=75 -'stable'=76 -'ascending'=77 -'descending'=78 -'some'=79 -'every'=80 -'satisfies'=81 -'collation'=82 -'greatest'=83 -'least'=84 -'switch'=85 -'case'=86 -'try'=87 -'catch'=88 -'default'=89 -'then'=90 -'else'=91 -'typeswitch'=92 -'or'=93 -'and'=94 -'not'=95 -'to'=96 -'instance'=97 -'of'=98 -'statically'=99 -'is'=100 -'treat'=101 -'cast'=102 -'castable'=103 -'version'=104 -'jsoniq'=105 -'unordered'=106 -'true'=107 -'false'=108 -'type'=109 -'declare'=110 -'context'=111 -'item'=112 -'variable'=113 -'?'=115 -'null'=116 +'schema'=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 +'unordered'=105 +'true'=106 +'false'=107 +'type'=108 +'declare'=109 +'context'=110 +'item'=111 +'variable'=112 +'insert'=113 +'delete'=114 +'rename'=115 +'replace'=116 +'copy'=117 +'modify'=118 +'append'=119 +'into'=120 +'value'=121 +'json'=122 +'with'=123 +'position'=124 +'?'=126 +'null'=127 diff --git a/src/main/java/org/rumbledb/parser/JsoniqBaseVisitor.java b/src/main/java/org/rumbledb/parser/JsoniqBaseVisitor.java index ddf7c7ed7a..28072e19c9 100644 --- a/src/main/java/org/rumbledb/parser/JsoniqBaseVisitor.java +++ b/src/main/java/org/rumbledb/parser/JsoniqBaseVisitor.java @@ -1,4 +1,4 @@ -// Generated from ./src/main/java/org/rumbledb/parser/Jsoniq.g4 by ANTLR 4.8 +// Generated from ./src/main/java/org/rumbledb/parser/Jsoniq.g4 by ANTLR 4.7 // Java header package org.rumbledb.parser; @@ -574,6 +574,62 @@ public class JsoniqBaseVisitor extends AbstractParseTreeVisitor implements * {@link #visitChildren} on {@code ctx}.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

+ */ + @Override public T visitCopyDecl(JsoniqParser.CopyDeclContext 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 67cdc1b97e..0f4ae8c81a 100644 --- a/src/main/java/org/rumbledb/parser/JsoniqLexer.java +++ b/src/main/java/org/rumbledb/parser/JsoniqLexer.java @@ -1,22 +1,20 @@ -// Generated from ./src/main/java/org/rumbledb/parser/Jsoniq.g4 by ANTLR 4.8 +// Generated from ./src/main/java/org/rumbledb/parser/Jsoniq.g4 by ANTLR 4.7 // 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 { - static { RuntimeMetaData.checkVersion("4.8", RuntimeMetaData.VERSION); } + static { RuntimeMetaData.checkVersion("4.7", RuntimeMetaData.VERSION); } protected static final DFA[] _decisionToDFA; protected static final PredictionContextCache _sharedContextCache = @@ -30,17 +28,19 @@ 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, T__60=61, Kfor=62, Klet=63, Kwhere=64, Kgroup=65, Kby=66, Korder=67, - Kreturn=68, Kif=69, Kin=70, Kas=71, Kat=72, Kallowing=73, Kempty=74, Kcount=75, - Kstable=76, Kascending=77, Kdescending=78, Ksome=79, Kevery=80, Ksatisfies=81, - Kcollation=82, Kgreatest=83, Kleast=84, Kswitch=85, Kcase=86, Ktry=87, - Kcatch=88, Kdefault=89, Kthen=90, Kelse=91, Ktypeswitch=92, Kor=93, Kand=94, - Knot=95, Kto=96, Kinstance=97, Kof=98, Kstatically=99, Kis=100, Ktreat=101, - Kcast=102, Kcastable=103, Kversion=104, Kjsoniq=105, Kunordered=106, Ktrue=107, - Kfalse=108, Ktype=109, Kdeclare=110, Kcontext=111, Kitem=112, Kvariable=113, - STRING=114, ArgumentPlaceholder=115, NullLiteral=116, Literal=117, NumericLiteral=118, - IntegerLiteral=119, DecimalLiteral=120, DoubleLiteral=121, WS=122, NCName=123, - XQComment=124, ContentChar=125; + 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, Kunordered=105, Ktrue=106, Kfalse=107, Ktype=108, + Kdeclare=109, Kcontext=110, Kitem=111, Kvariable=112, Kinsert=113, Kdelete=114, + Krename=115, Kreplace=116, Kcopy=117, Kmodify=118, Kappend=119, Kinto=120, + Kvalue=121, Kjson=122, Kwith=123, Kposition=124, STRING=125, ArgumentPlaceholder=126, + NullLiteral=127, Literal=128, NumericLiteral=129, IntegerLiteral=130, + DecimalLiteral=131, DoubleLiteral=132, WS=133, NCName=134, XQComment=135, + ContentChar=136; public static String[] channelNames = { "DEFAULT_TOKEN_CHANNEL", "HIDDEN" }; @@ -49,72 +49,68 @@ public class JsoniqLexer extends Lexer { "DEFAULT_MODE" }; - private static String[] makeRuleNames() { - return new String[] { - "T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8", - "T__9", "T__10", "T__11", "T__12", "T__13", "T__14", "T__15", "T__16", - "T__17", "T__18", "T__19", "T__20", "T__21", "T__22", "T__23", "T__24", - "T__25", "T__26", "T__27", "T__28", "T__29", "T__30", "T__31", "T__32", - "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", "T__60", "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", - "Ktrue", "Kfalse", "Ktype", "Kdeclare", "Kcontext", "Kitem", "Kvariable", - "STRING", "ESC", "UNICODE", "HEX", "ArgumentPlaceholder", "NullLiteral", - "Literal", "NumericLiteral", "IntegerLiteral", "DecimalLiteral", "DoubleLiteral", - "Digits", "WS", "NCName", "NameStartChar", "NameChar", "XQComment", "ContentChar" - }; - } - public static final String[] ruleNames = makeRuleNames(); + public static final String[] ruleNames = { + "T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8", + "T__9", "T__10", "T__11", "T__12", "T__13", "T__14", "T__15", "T__16", + "T__17", "T__18", "T__19", "T__20", "T__21", "T__22", "T__23", "T__24", + "T__25", "T__26", "T__27", "T__28", "T__29", "T__30", "T__31", "T__32", + "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", + "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", "Ktrue", "Kfalse", "Ktype", "Kdeclare", + "Kcontext", "Kitem", "Kvariable", "Kinsert", "Kdelete", "Krename", "Kreplace", + "Kcopy", "Kmodify", "Kappend", "Kinto", "Kvalue", "Kjson", "Kwith", "Kposition", + "STRING", "ESC", "UNICODE", "HEX", "ArgumentPlaceholder", "NullLiteral", + "Literal", "NumericLiteral", "IntegerLiteral", "DecimalLiteral", "DoubleLiteral", + "Digits", "WS", "NCName", "NameStartChar", "NameChar", "XQComment", "ContentChar" + }; - private static String[] makeLiteralNames() { - return new String[] { - null, "';'", "'module'", "'namespace'", "'='", "'ordering'", "'ordered'", - "'decimal-format'", "':'", "'decimal-separator'", "'grouping-separator'", - "'infinity'", "'minus-sign'", "'NaN'", "'percent'", "'per-mille'", "'zero-digit'", - "'digit'", "'pattern-separator'", "'import'", "','", "':='", "'external'", - "'function'", "'('", "')'", "'{'", "'}'", "'jsound'", "'compact'", "'verbose'", - "'json'", "'schema'", "'$'", "'|'", "'*'", "'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'", - "'true'", "'false'", "'type'", "'declare'", "'context'", "'item'", "'variable'", - null, "'?'", "'null'" - }; - } - private static final String[] _LITERAL_NAMES = makeLiteralNames(); - private static String[] makeSymbolicNames() { - return new String[] { - 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, 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", "Ktrue", "Kfalse", "Ktype", "Kdeclare", "Kcontext", - "Kitem", "Kvariable", "STRING", "ArgumentPlaceholder", "NullLiteral", - "Literal", "NumericLiteral", "IntegerLiteral", "DecimalLiteral", "DoubleLiteral", - "WS", "NCName", "XQComment", "ContentChar" - }; - } - private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + private static final String[] _LITERAL_NAMES = { + null, "';'", "'module'", "'namespace'", "'='", "'ordering'", "'ordered'", + "'decimal-format'", "':'", "'decimal-separator'", "'grouping-separator'", + "'infinity'", "'minus-sign'", "'NaN'", "'percent'", "'per-mille'", "'zero-digit'", + "'digit'", "'pattern-separator'", "'import'", "','", "':='", "'external'", + "'function'", "'('", "')'", "'{'", "'}'", "'jsound'", "'compact'", "'verbose'", + "'schema'", "'$'", "'|'", "'*'", "'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'", "'true'", + "'false'", "'type'", "'declare'", "'context'", "'item'", "'variable'", + "'insert'", "'delete'", "'rename'", "'replace'", "'copy'", "'modify'", + "'append'", "'into'", "'value'", "'json'", "'with'", "'position'", null, + "'?'", "'null'" + }; + private static final String[] _SYMBOLIC_NAMES = { + 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, 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", "Ktrue", "Kfalse", "Ktype", "Kdeclare", "Kcontext", + "Kitem", "Kvariable", "Kinsert", "Kdelete", "Krename", "Kreplace", "Kcopy", + "Kmodify", "Kappend", "Kinto", "Kvalue", "Kjson", "Kwith", "Kposition", + "STRING", "ArgumentPlaceholder", "NullLiteral", "Literal", "NumericLiteral", + "IntegerLiteral", "DecimalLiteral", "DoubleLiteral", "WS", "NCName", "XQComment", + "ContentChar" + }; public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); /** @@ -173,9 +169,9 @@ public JsoniqLexer(CharStream input) { public ATN getATN() { return _ATN; } public static final String _serializedATN = - "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\177\u040b\b\1\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"+ + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\u008a\u046a\b\1\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\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t"+ " \4!\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t"+ @@ -188,339 +184,377 @@ public JsoniqLexer(CharStream input) { "\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{\4|\t|\4}\t}\4~\t~\4\177\t\177\4\u0080\t"+ "\u0080\4\u0081\t\u0081\4\u0082\t\u0082\4\u0083\t\u0083\4\u0084\t\u0084"+ - "\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\6\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\b\3\b\3\b\3\b\3\b\3\b\3"+ - "\b\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\n\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\13\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\16\3\16\3\16\3\16\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\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"+ - "\21\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\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\24\3\25\3\25\3\26\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\30\3\30\3\30\3\30\3\30\3\30\3\31\3"+ - "\31\3\32\3\32\3\33\3\33\3\34\3\34\3\35\3\35\3\35\3\35\3\35\3\35\3\35\3"+ - "\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\37\3\37\3\37\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-\3-\3.\3.\3/\3/\3/\3\60\3\60\3\60\3\61\3\61\3\62\3\62\3\63\3\63\3"+ - "\63\3\63\3\64\3\64\3\64\3\64\3\64\3\65\3\65\3\65\3\65\3\66\3\66\3\66\3"+ - "\66\3\66\3\66\3\66\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@\3A\3A\3A\3A\3A\3A\3B\3B\3"+ - "B\3B\3B\3B\3C\3C\3C\3D\3D\3D\3D\3D\3D\3E\3E\3E\3E\3E\3E\3E\3F\3F\3F\3"+ - "G\3G\3G\3H\3H\3H\3I\3I\3I\3J\3J\3J\3J\3J\3J\3J\3J\3J\3K\3K\3K\3K\3K\3"+ - "K\3L\3L\3L\3L\3L\3L\3M\3M\3M\3M\3M\3M\3M\3N\3N\3N\3N\3N\3N\3N\3N\3N\3"+ - "N\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3O\3P\3P\3P\3P\3P\3Q\3Q\3Q\3Q\3Q\3Q\3"+ - "R\3R\3R\3R\3R\3R\3R\3R\3R\3R\3S\3S\3S\3S\3S\3S\3S\3S\3S\3S\3T\3T\3T\3"+ - "T\3T\3T\3T\3T\3T\3U\3U\3U\3U\3U\3U\3V\3V\3V\3V\3V\3V\3V\3W\3W\3W\3W\3"+ - "W\3X\3X\3X\3X\3Y\3Y\3Y\3Y\3Y\3Y\3Z\3Z\3Z\3Z\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`\3`\3`\3a\3a\3a\3b\3b\3b\3b\3b\3b\3b\3b\3b\3c\3c\3c\3d\3d"+ - "\3d\3d\3d\3d\3d\3d\3d\3d\3d\3e\3e\3e\3f\3f\3f\3f\3f\3f\3g\3g\3g\3g\3g"+ - "\3h\3h\3h\3h\3h\3h\3h\3h\3h\3i\3i\3i\3i\3i\3i\3i\3i\3j\3j\3j\3j\3j\3j"+ - "\3j\3k\3k\3k\3k\3k\3k\3k\3k\3k\3k\3l\3l\3l\3l\3l\3m\3m\3m\3m\3m\3m\3n"+ - "\3n\3n\3n\3n\3o\3o\3o\3o\3o\3o\3o\3o\3p\3p\3p\3p\3p\3p\3p\3p\3q\3q\3q"+ - "\3q\3q\3r\3r\3r\3r\3r\3r\3r\3r\3r\3s\3s\3s\7s\u0399\ns\fs\16s\u039c\13"+ - "s\3s\3s\3t\3t\3t\5t\u03a3\nt\3u\3u\3u\3u\3u\3u\3v\3v\3w\3w\3x\3x\3x\3"+ - "x\3x\3y\3y\3z\3z\3z\5z\u03b9\nz\3{\3{\3|\3|\3|\3|\3|\7|\u03c2\n|\f|\16"+ - "|\u03c5\13|\5|\u03c7\n|\3}\3}\3}\3}\3}\7}\u03ce\n}\f}\16}\u03d1\13}\5"+ - "}\u03d3\n}\5}\u03d5\n}\3}\3}\5}\u03d9\n}\3}\3}\3~\6~\u03de\n~\r~\16~\u03df"+ - "\3\177\3\177\3\177\3\177\3\u0080\3\u0080\7\u0080\u03e8\n\u0080\f\u0080"+ - "\16\u0080\u03eb\13\u0080\3\u0081\5\u0081\u03ee\n\u0081\3\u0082\3\u0082"+ - "\5\u0082\u03f2\n\u0082\3\u0083\3\u0083\3\u0083\3\u0083\3\u0083\3\u0083"+ - "\3\u0083\3\u0083\7\u0083\u03fc\n\u0083\f\u0083\16\u0083\u03ff\13\u0083"+ - "\3\u0083\6\u0083\u0402\n\u0083\r\u0083\16\u0083\u0403\3\u0083\3\u0083"+ - "\3\u0083\3\u0083\3\u0084\3\u0084\2\2\u0085\3\3\5\4\7\5\t\6\13\7\r\b\17"+ - "\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37\21!\22#\23%\24\'\25)\26+"+ - "\27-\30/\31\61\32\63\33\65\34\67\359\36;\37= ?!A\"C#E$G%I&K\'M(O)Q*S+"+ - "U,W-Y.[/]\60_\61a\62c\63e\64g\65i\66k\67m8o9q:s;u{?}@\177A\u0081"+ - "B\u0083C\u0085D\u0087E\u0089F\u008bG\u008dH\u008fI\u0091J\u0093K\u0095"+ - "L\u0097M\u0099N\u009bO\u009dP\u009fQ\u00a1R\u00a3S\u00a5T\u00a7U\u00a9"+ - "V\u00abW\u00adX\u00afY\u00b1Z\u00b3[\u00b5\\\u00b7]\u00b9^\u00bb_\u00bd"+ - "`\u00bfa\u00c1b\u00c3c\u00c5d\u00c7e\u00c9f\u00cbg\u00cdh\u00cfi\u00d1"+ - "j\u00d3k\u00d5l\u00d7m\u00d9n\u00dbo\u00ddp\u00dfq\u00e1r\u00e3s\u00e5"+ - "t\u00e7\2\u00e9\2\u00eb\2\u00edu\u00efv\u00f1w\u00f3x\u00f5y\u00f7z\u00f9"+ - "{\u00fb\2\u00fd|\u00ff}\u0101\2\u0103\2\u0105~\u0107\177\3\2\17\4\2$$"+ - "^^\n\2$$\61\61^^ddhhppttvv\5\2\62;CHch\3\2\62;\4\2GGgg\4\2--//\5\2\13"+ - "\f\17\17\"\"\20\2C\\aac|\u00c2\u00d8\u00da\u00f8\u00fa\u0301\u0372\u037f"+ - "\u0381\u2001\u200e\u200f\u2072\u2191\u2c02\u2ff1\u3003\ud801\uf902\ufdd1"+ - "\ufdf2\uffff\7\2//\62;\u00b9\u00b9\u0302\u0371\u2041\u2042\3\2<<\3\2+"+ - "+\4\2**<<\7\2$$()>>}}\177\177\2\u0417\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2"+ - "\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2"+ - "\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3"+ - "\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3"+ - "\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65"+ - "\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3"+ - "\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2"+ - "\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2"+ - "[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2g\3"+ - "\2\2\2\2i\3\2\2\2\2k\3\2\2\2\2m\3\2\2\2\2o\3\2\2\2\2q\3\2\2\2\2s\3\2\2"+ - "\2\2u\3\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3\2\2\2\2\177\3\2\2"+ - "\2\2\u0081\3\2\2\2\2\u0083\3\2\2\2\2\u0085\3\2\2\2\2\u0087\3\2\2\2\2\u0089"+ - "\3\2\2\2\2\u008b\3\2\2\2\2\u008d\3\2\2\2\2\u008f\3\2\2\2\2\u0091\3\2\2"+ - "\2\2\u0093\3\2\2\2\2\u0095\3\2\2\2\2\u0097\3\2\2\2\2\u0099\3\2\2\2\2\u009b"+ - "\3\2\2\2\2\u009d\3\2\2\2\2\u009f\3\2\2\2\2\u00a1\3\2\2\2\2\u00a3\3\2\2"+ - "\2\2\u00a5\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9\3\2\2\2\2\u00ab\3\2\2\2\2\u00ad"+ - "\3\2\2\2\2\u00af\3\2\2\2\2\u00b1\3\2\2\2\2\u00b3\3\2\2\2\2\u00b5\3\2\2"+ - "\2\2\u00b7\3\2\2\2\2\u00b9\3\2\2\2\2\u00bb\3\2\2\2\2\u00bd\3\2\2\2\2\u00bf"+ - "\3\2\2\2\2\u00c1\3\2\2\2\2\u00c3\3\2\2\2\2\u00c5\3\2\2\2\2\u00c7\3\2\2"+ - "\2\2\u00c9\3\2\2\2\2\u00cb\3\2\2\2\2\u00cd\3\2\2\2\2\u00cf\3\2\2\2\2\u00d1"+ - "\3\2\2\2\2\u00d3\3\2\2\2\2\u00d5\3\2\2\2\2\u00d7\3\2\2\2\2\u00d9\3\2\2"+ - "\2\2\u00db\3\2\2\2\2\u00dd\3\2\2\2\2\u00df\3\2\2\2\2\u00e1\3\2\2\2\2\u00e3"+ - "\3\2\2\2\2\u00e5\3\2\2\2\2\u00ed\3\2\2\2\2\u00ef\3\2\2\2\2\u00f1\3\2\2"+ - "\2\2\u00f3\3\2\2\2\2\u00f5\3\2\2\2\2\u00f7\3\2\2\2\2\u00f9\3\2\2\2\2\u00fd"+ - "\3\2\2\2\2\u00ff\3\2\2\2\2\u0105\3\2\2\2\2\u0107\3\2\2\2\3\u0109\3\2\2"+ - "\2\5\u010b\3\2\2\2\7\u0112\3\2\2\2\t\u011c\3\2\2\2\13\u011e\3\2\2\2\r"+ - "\u0127\3\2\2\2\17\u012f\3\2\2\2\21\u013e\3\2\2\2\23\u0140\3\2\2\2\25\u0152"+ - "\3\2\2\2\27\u0165\3\2\2\2\31\u016e\3\2\2\2\33\u0179\3\2\2\2\35\u017d\3"+ - "\2\2\2\37\u0185\3\2\2\2!\u018f\3\2\2\2#\u019a\3\2\2\2%\u01a0\3\2\2\2\'"+ - "\u01b2\3\2\2\2)\u01b9\3\2\2\2+\u01bb\3\2\2\2-\u01be\3\2\2\2/\u01c7\3\2"+ - "\2\2\61\u01d0\3\2\2\2\63\u01d2\3\2\2\2\65\u01d4\3\2\2\2\67\u01d6\3\2\2"+ - "\29\u01d8\3\2\2\2;\u01df\3\2\2\2=\u01e7\3\2\2\2?\u01ef\3\2\2\2A\u01f4"+ - "\3\2\2\2C\u01fb\3\2\2\2E\u01fd\3\2\2\2G\u01ff\3\2\2\2I\u0201\3\2\2\2K"+ - "\u0204\3\2\2\2M\u0207\3\2\2\2O\u020a\3\2\2\2Q\u020d\3\2\2\2S\u0210\3\2"+ - "\2\2U\u0213\3\2\2\2W\u0216\3\2\2\2Y\u0218\3\2\2\2[\u021b\3\2\2\2]\u021d"+ - "\3\2\2\2_\u0220\3\2\2\2a\u0223\3\2\2\2c\u0225\3\2\2\2e\u0227\3\2\2\2g"+ - "\u022b\3\2\2\2i\u0230\3\2\2\2k\u0234\3\2\2\2m\u023d\3\2\2\2o\u023f\3\2"+ - "\2\2q\u0241\3\2\2\2s\u0243\3\2\2\2u\u0245\3\2\2\2w\u0248\3\2\2\2y\u024a"+ - "\3\2\2\2{\u024d\3\2\2\2}\u0250\3\2\2\2\177\u0254\3\2\2\2\u0081\u0258\3"+ - "\2\2\2\u0083\u025e\3\2\2\2\u0085\u0264\3\2\2\2\u0087\u0267\3\2\2\2\u0089"+ - "\u026d\3\2\2\2\u008b\u0274\3\2\2\2\u008d\u0277\3\2\2\2\u008f\u027a\3\2"+ - "\2\2\u0091\u027d\3\2\2\2\u0093\u0280\3\2\2\2\u0095\u0289\3\2\2\2\u0097"+ - "\u028f\3\2\2\2\u0099\u0295\3\2\2\2\u009b\u029c\3\2\2\2\u009d\u02a6\3\2"+ - "\2\2\u009f\u02b1\3\2\2\2\u00a1\u02b6\3\2\2\2\u00a3\u02bc\3\2\2\2\u00a5"+ - "\u02c6\3\2\2\2\u00a7\u02d0\3\2\2\2\u00a9\u02d9\3\2\2\2\u00ab\u02df\3\2"+ - "\2\2\u00ad\u02e6\3\2\2\2\u00af\u02eb\3\2\2\2\u00b1\u02ef\3\2\2\2\u00b3"+ - "\u02f5\3\2\2\2\u00b5\u02fd\3\2\2\2\u00b7\u0302\3\2\2\2\u00b9\u0307\3\2"+ - "\2\2\u00bb\u0312\3\2\2\2\u00bd\u0315\3\2\2\2\u00bf\u0319\3\2\2\2\u00c1"+ - "\u031d\3\2\2\2\u00c3\u0320\3\2\2\2\u00c5\u0329\3\2\2\2\u00c7\u032c\3\2"+ - "\2\2\u00c9\u0337\3\2\2\2\u00cb\u033a\3\2\2\2\u00cd\u0340\3\2\2\2\u00cf"+ - "\u0345\3\2\2\2\u00d1\u034e\3\2\2\2\u00d3\u0356\3\2\2\2\u00d5\u035d\3\2"+ - "\2\2\u00d7\u0367\3\2\2\2\u00d9\u036c\3\2\2\2\u00db\u0372\3\2\2\2\u00dd"+ - "\u0377\3\2\2\2\u00df\u037f\3\2\2\2\u00e1\u0387\3\2\2\2\u00e3\u038c\3\2"+ - "\2\2\u00e5\u0395\3\2\2\2\u00e7\u039f\3\2\2\2\u00e9\u03a4\3\2\2\2\u00eb"+ - "\u03aa\3\2\2\2\u00ed\u03ac\3\2\2\2\u00ef\u03ae\3\2\2\2\u00f1\u03b3\3\2"+ - "\2\2\u00f3\u03b8\3\2\2\2\u00f5\u03ba\3\2\2\2\u00f7\u03c6\3\2\2\2\u00f9"+ - "\u03d4\3\2\2\2\u00fb\u03dd\3\2\2\2\u00fd\u03e1\3\2\2\2\u00ff\u03e5\3\2"+ - "\2\2\u0101\u03ed\3\2\2\2\u0103\u03f1\3\2\2\2\u0105\u03f3\3\2\2\2\u0107"+ - "\u0409\3\2\2\2\u0109\u010a\7=\2\2\u010a\4\3\2\2\2\u010b\u010c\7o\2\2\u010c"+ - "\u010d\7q\2\2\u010d\u010e\7f\2\2\u010e\u010f\7w\2\2\u010f\u0110\7n\2\2"+ - "\u0110\u0111\7g\2\2\u0111\6\3\2\2\2\u0112\u0113\7p\2\2\u0113\u0114\7c"+ - "\2\2\u0114\u0115\7o\2\2\u0115\u0116\7g\2\2\u0116\u0117\7u\2\2\u0117\u0118"+ - "\7r\2\2\u0118\u0119\7c\2\2\u0119\u011a\7e\2\2\u011a\u011b\7g\2\2\u011b"+ - "\b\3\2\2\2\u011c\u011d\7?\2\2\u011d\n\3\2\2\2\u011e\u011f\7q\2\2\u011f"+ - "\u0120\7t\2\2\u0120\u0121\7f\2\2\u0121\u0122\7g\2\2\u0122\u0123\7t\2\2"+ - "\u0123\u0124\7k\2\2\u0124\u0125\7p\2\2\u0125\u0126\7i\2\2\u0126\f\3\2"+ - "\2\2\u0127\u0128\7q\2\2\u0128\u0129\7t\2\2\u0129\u012a\7f\2\2\u012a\u012b"+ - "\7g\2\2\u012b\u012c\7t\2\2\u012c\u012d\7g\2\2\u012d\u012e\7f\2\2\u012e"+ - "\16\3\2\2\2\u012f\u0130\7f\2\2\u0130\u0131\7g\2\2\u0131\u0132\7e\2\2\u0132"+ - "\u0133\7k\2\2\u0133\u0134\7o\2\2\u0134\u0135\7c\2\2\u0135\u0136\7n\2\2"+ - "\u0136\u0137\7/\2\2\u0137\u0138\7h\2\2\u0138\u0139\7q\2\2\u0139\u013a"+ - "\7t\2\2\u013a\u013b\7o\2\2\u013b\u013c\7c\2\2\u013c\u013d\7v\2\2\u013d"+ - "\20\3\2\2\2\u013e\u013f\7<\2\2\u013f\22\3\2\2\2\u0140\u0141\7f\2\2\u0141"+ - "\u0142\7g\2\2\u0142\u0143\7e\2\2\u0143\u0144\7k\2\2\u0144\u0145\7o\2\2"+ - "\u0145\u0146\7c\2\2\u0146\u0147\7n\2\2\u0147\u0148\7/\2\2\u0148\u0149"+ - "\7u\2\2\u0149\u014a\7g\2\2\u014a\u014b\7r\2\2\u014b\u014c\7c\2\2\u014c"+ - "\u014d\7t\2\2\u014d\u014e\7c\2\2\u014e\u014f\7v\2\2\u014f\u0150\7q\2\2"+ - "\u0150\u0151\7t\2\2\u0151\24\3\2\2\2\u0152\u0153\7i\2\2\u0153\u0154\7"+ - "t\2\2\u0154\u0155\7q\2\2\u0155\u0156\7w\2\2\u0156\u0157\7r\2\2\u0157\u0158"+ - "\7k\2\2\u0158\u0159\7p\2\2\u0159\u015a\7i\2\2\u015a\u015b\7/\2\2\u015b"+ - "\u015c\7u\2\2\u015c\u015d\7g\2\2\u015d\u015e\7r\2\2\u015e\u015f\7c\2\2"+ - "\u015f\u0160\7t\2\2\u0160\u0161\7c\2\2\u0161\u0162\7v\2\2\u0162\u0163"+ - "\7q\2\2\u0163\u0164\7t\2\2\u0164\26\3\2\2\2\u0165\u0166\7k\2\2\u0166\u0167"+ - "\7p\2\2\u0167\u0168\7h\2\2\u0168\u0169\7k\2\2\u0169\u016a\7p\2\2\u016a"+ - "\u016b\7k\2\2\u016b\u016c\7v\2\2\u016c\u016d\7{\2\2\u016d\30\3\2\2\2\u016e"+ - "\u016f\7o\2\2\u016f\u0170\7k\2\2\u0170\u0171\7p\2\2\u0171\u0172\7w\2\2"+ - "\u0172\u0173\7u\2\2\u0173\u0174\7/\2\2\u0174\u0175\7u\2\2\u0175\u0176"+ - "\7k\2\2\u0176\u0177\7i\2\2\u0177\u0178\7p\2\2\u0178\32\3\2\2\2\u0179\u017a"+ - "\7P\2\2\u017a\u017b\7c\2\2\u017b\u017c\7P\2\2\u017c\34\3\2\2\2\u017d\u017e"+ - "\7r\2\2\u017e\u017f\7g\2\2\u017f\u0180\7t\2\2\u0180\u0181\7e\2\2\u0181"+ - "\u0182\7g\2\2\u0182\u0183\7p\2\2\u0183\u0184\7v\2\2\u0184\36\3\2\2\2\u0185"+ - "\u0186\7r\2\2\u0186\u0187\7g\2\2\u0187\u0188\7t\2\2\u0188\u0189\7/\2\2"+ - "\u0189\u018a\7o\2\2\u018a\u018b\7k\2\2\u018b\u018c\7n\2\2\u018c\u018d"+ - "\7n\2\2\u018d\u018e\7g\2\2\u018e \3\2\2\2\u018f\u0190\7|\2\2\u0190\u0191"+ - "\7g\2\2\u0191\u0192\7t\2\2\u0192\u0193\7q\2\2\u0193\u0194\7/\2\2\u0194"+ - "\u0195\7f\2\2\u0195\u0196\7k\2\2\u0196\u0197\7i\2\2\u0197\u0198\7k\2\2"+ - "\u0198\u0199\7v\2\2\u0199\"\3\2\2\2\u019a\u019b\7f\2\2\u019b\u019c\7k"+ - "\2\2\u019c\u019d\7i\2\2\u019d\u019e\7k\2\2\u019e\u019f\7v\2\2\u019f$\3"+ - "\2\2\2\u01a0\u01a1\7r\2\2\u01a1\u01a2\7c\2\2\u01a2\u01a3\7v\2\2\u01a3"+ - "\u01a4\7v\2\2\u01a4\u01a5\7g\2\2\u01a5\u01a6\7t\2\2\u01a6\u01a7\7p\2\2"+ - "\u01a7\u01a8\7/\2\2\u01a8\u01a9\7u\2\2\u01a9\u01aa\7g\2\2\u01aa\u01ab"+ - "\7r\2\2\u01ab\u01ac\7c\2\2\u01ac\u01ad\7t\2\2\u01ad\u01ae\7c\2\2\u01ae"+ - "\u01af\7v\2\2\u01af\u01b0\7q\2\2\u01b0\u01b1\7t\2\2\u01b1&\3\2\2\2\u01b2"+ - "\u01b3\7k\2\2\u01b3\u01b4\7o\2\2\u01b4\u01b5\7r\2\2\u01b5\u01b6\7q\2\2"+ - "\u01b6\u01b7\7t\2\2\u01b7\u01b8\7v\2\2\u01b8(\3\2\2\2\u01b9\u01ba\7.\2"+ - "\2\u01ba*\3\2\2\2\u01bb\u01bc\7<\2\2\u01bc\u01bd\7?\2\2\u01bd,\3\2\2\2"+ - "\u01be\u01bf\7g\2\2\u01bf\u01c0\7z\2\2\u01c0\u01c1\7v\2\2\u01c1\u01c2"+ - "\7g\2\2\u01c2\u01c3\7t\2\2\u01c3\u01c4\7p\2\2\u01c4\u01c5\7c\2\2\u01c5"+ - "\u01c6\7n\2\2\u01c6.\3\2\2\2\u01c7\u01c8\7h\2\2\u01c8\u01c9\7w\2\2\u01c9"+ - "\u01ca\7p\2\2\u01ca\u01cb\7e\2\2\u01cb\u01cc\7v\2\2\u01cc\u01cd\7k\2\2"+ - "\u01cd\u01ce\7q\2\2\u01ce\u01cf\7p\2\2\u01cf\60\3\2\2\2\u01d0\u01d1\7"+ - "*\2\2\u01d1\62\3\2\2\2\u01d2\u01d3\7+\2\2\u01d3\64\3\2\2\2\u01d4\u01d5"+ - "\7}\2\2\u01d5\66\3\2\2\2\u01d6\u01d7\7\177\2\2\u01d78\3\2\2\2\u01d8\u01d9"+ - "\7l\2\2\u01d9\u01da\7u\2\2\u01da\u01db\7q\2\2\u01db\u01dc\7w\2\2\u01dc"+ - "\u01dd\7p\2\2\u01dd\u01de\7f\2\2\u01de:\3\2\2\2\u01df\u01e0\7e\2\2\u01e0"+ - "\u01e1\7q\2\2\u01e1\u01e2\7o\2\2\u01e2\u01e3\7r\2\2\u01e3\u01e4\7c\2\2"+ - "\u01e4\u01e5\7e\2\2\u01e5\u01e6\7v\2\2\u01e6<\3\2\2\2\u01e7\u01e8\7x\2"+ - "\2\u01e8\u01e9\7g\2\2\u01e9\u01ea\7t\2\2\u01ea\u01eb\7d\2\2\u01eb\u01ec"+ - "\7q\2\2\u01ec\u01ed\7u\2\2\u01ed\u01ee\7g\2\2\u01ee>\3\2\2\2\u01ef\u01f0"+ - "\7l\2\2\u01f0\u01f1\7u\2\2\u01f1\u01f2\7q\2\2\u01f2\u01f3\7p\2\2\u01f3"+ - "@\3\2\2\2\u01f4\u01f5\7u\2\2\u01f5\u01f6\7e\2\2\u01f6\u01f7\7j\2\2\u01f7"+ - "\u01f8\7g\2\2\u01f8\u01f9\7o\2\2\u01f9\u01fa\7c\2\2\u01faB\3\2\2\2\u01fb"+ - "\u01fc\7&\2\2\u01fcD\3\2\2\2\u01fd\u01fe\7~\2\2\u01feF\3\2\2\2\u01ff\u0200"+ - "\7,\2\2\u0200H\3\2\2\2\u0201\u0202\7g\2\2\u0202\u0203\7s\2\2\u0203J\3"+ - "\2\2\2\u0204\u0205\7p\2\2\u0205\u0206\7g\2\2\u0206L\3\2\2\2\u0207\u0208"+ - "\7n\2\2\u0208\u0209\7v\2\2\u0209N\3\2\2\2\u020a\u020b\7n\2\2\u020b\u020c"+ - "\7g\2\2\u020cP\3\2\2\2\u020d\u020e\7i\2\2\u020e\u020f\7v\2\2\u020fR\3"+ - "\2\2\2\u0210\u0211\7i\2\2\u0211\u0212\7g\2\2\u0212T\3\2\2\2\u0213\u0214"+ - "\7#\2\2\u0214\u0215\7?\2\2\u0215V\3\2\2\2\u0216\u0217\7>\2\2\u0217X\3"+ - "\2\2\2\u0218\u0219\7>\2\2\u0219\u021a\7?\2\2\u021aZ\3\2\2\2\u021b\u021c"+ - "\7@\2\2\u021c\\\3\2\2\2\u021d\u021e\7@\2\2\u021e\u021f\7?\2\2\u021f^\3"+ - "\2\2\2\u0220\u0221\7~\2\2\u0221\u0222\7~\2\2\u0222`\3\2\2\2\u0223\u0224"+ - "\7-\2\2\u0224b\3\2\2\2\u0225\u0226\7/\2\2\u0226d\3\2\2\2\u0227\u0228\7"+ - "f\2\2\u0228\u0229\7k\2\2\u0229\u022a\7x\2\2\u022af\3\2\2\2\u022b\u022c"+ - "\7k\2\2\u022c\u022d\7f\2\2\u022d\u022e\7k\2\2\u022e\u022f\7x\2\2\u022f"+ - "h\3\2\2\2\u0230\u0231\7o\2\2\u0231\u0232\7q\2\2\u0232\u0233\7f\2\2\u0233"+ - "j\3\2\2\2\u0234\u0235\7x\2\2\u0235\u0236\7c\2\2\u0236\u0237\7n\2\2\u0237"+ - "\u0238\7k\2\2\u0238\u0239\7f\2\2\u0239\u023a\7c\2\2\u023a\u023b\7v\2\2"+ - "\u023b\u023c\7g\2\2\u023cl\3\2\2\2\u023d\u023e\7#\2\2\u023en\3\2\2\2\u023f"+ - "\u0240\7]\2\2\u0240p\3\2\2\2\u0241\u0242\7_\2\2\u0242r\3\2\2\2\u0243\u0244"+ - "\7\60\2\2\u0244t\3\2\2\2\u0245\u0246\7&\2\2\u0246\u0247\7&\2\2\u0247v"+ - "\3\2\2\2\u0248\u0249\7%\2\2\u0249x\3\2\2\2\u024a\u024b\7}\2\2\u024b\u024c"+ - "\7~\2\2\u024cz\3\2\2\2\u024d\u024e\7~\2\2\u024e\u024f\7\177\2\2\u024f"+ - "|\3\2\2\2\u0250\u0251\7h\2\2\u0251\u0252\7q\2\2\u0252\u0253\7t\2\2\u0253"+ - "~\3\2\2\2\u0254\u0255\7n\2\2\u0255\u0256\7g\2\2\u0256\u0257\7v\2\2\u0257"+ - "\u0080\3\2\2\2\u0258\u0259\7y\2\2\u0259\u025a\7j\2\2\u025a\u025b\7g\2"+ - "\2\u025b\u025c\7t\2\2\u025c\u025d\7g\2\2\u025d\u0082\3\2\2\2\u025e\u025f"+ - "\7i\2\2\u025f\u0260\7t\2\2\u0260\u0261\7q\2\2\u0261\u0262\7w\2\2\u0262"+ - "\u0263\7r\2\2\u0263\u0084\3\2\2\2\u0264\u0265\7d\2\2\u0265\u0266\7{\2"+ - "\2\u0266\u0086\3\2\2\2\u0267\u0268\7q\2\2\u0268\u0269\7t\2\2\u0269\u026a"+ - "\7f\2\2\u026a\u026b\7g\2\2\u026b\u026c\7t\2\2\u026c\u0088\3\2\2\2\u026d"+ - "\u026e\7t\2\2\u026e\u026f\7g\2\2\u026f\u0270\7v\2\2\u0270\u0271\7w\2\2"+ - "\u0271\u0272\7t\2\2\u0272\u0273\7p\2\2\u0273\u008a\3\2\2\2\u0274\u0275"+ - "\7k\2\2\u0275\u0276\7h\2\2\u0276\u008c\3\2\2\2\u0277\u0278\7k\2\2\u0278"+ - "\u0279\7p\2\2\u0279\u008e\3\2\2\2\u027a\u027b\7c\2\2\u027b\u027c\7u\2"+ - "\2\u027c\u0090\3\2\2\2\u027d\u027e\7c\2\2\u027e\u027f\7v\2\2\u027f\u0092"+ - "\3\2\2\2\u0280\u0281\7c\2\2\u0281\u0282\7n\2\2\u0282\u0283\7n\2\2\u0283"+ - "\u0284\7q\2\2\u0284\u0285\7y\2\2\u0285\u0286\7k\2\2\u0286\u0287\7p\2\2"+ - "\u0287\u0288\7i\2\2\u0288\u0094\3\2\2\2\u0289\u028a\7g\2\2\u028a\u028b"+ - "\7o\2\2\u028b\u028c\7r\2\2\u028c\u028d\7v\2\2\u028d\u028e\7{\2\2\u028e"+ - "\u0096\3\2\2\2\u028f\u0290\7e\2\2\u0290\u0291\7q\2\2\u0291\u0292\7w\2"+ - "\2\u0292\u0293\7p\2\2\u0293\u0294\7v\2\2\u0294\u0098\3\2\2\2\u0295\u0296"+ - "\7u\2\2\u0296\u0297\7v\2\2\u0297\u0298\7c\2\2\u0298\u0299\7d\2\2\u0299"+ - "\u029a\7n\2\2\u029a\u029b\7g\2\2\u029b\u009a\3\2\2\2\u029c\u029d\7c\2"+ - "\2\u029d\u029e\7u\2\2\u029e\u029f\7e\2\2\u029f\u02a0\7g\2\2\u02a0\u02a1"+ - "\7p\2\2\u02a1\u02a2\7f\2\2\u02a2\u02a3\7k\2\2\u02a3\u02a4\7p\2\2\u02a4"+ - "\u02a5\7i\2\2\u02a5\u009c\3\2\2\2\u02a6\u02a7\7f\2\2\u02a7\u02a8\7g\2"+ - "\2\u02a8\u02a9\7u\2\2\u02a9\u02aa\7e\2\2\u02aa\u02ab\7g\2\2\u02ab\u02ac"+ - "\7p\2\2\u02ac\u02ad\7f\2\2\u02ad\u02ae\7k\2\2\u02ae\u02af\7p\2\2\u02af"+ - "\u02b0\7i\2\2\u02b0\u009e\3\2\2\2\u02b1\u02b2\7u\2\2\u02b2\u02b3\7q\2"+ - "\2\u02b3\u02b4\7o\2\2\u02b4\u02b5\7g\2\2\u02b5\u00a0\3\2\2\2\u02b6\u02b7"+ - "\7g\2\2\u02b7\u02b8\7x\2\2\u02b8\u02b9\7g\2\2\u02b9\u02ba\7t\2\2\u02ba"+ - "\u02bb\7{\2\2\u02bb\u00a2\3\2\2\2\u02bc\u02bd\7u\2\2\u02bd\u02be\7c\2"+ - "\2\u02be\u02bf\7v\2\2\u02bf\u02c0\7k\2\2\u02c0\u02c1\7u\2\2\u02c1\u02c2"+ - "\7h\2\2\u02c2\u02c3\7k\2\2\u02c3\u02c4\7g\2\2\u02c4\u02c5\7u\2\2\u02c5"+ - "\u00a4\3\2\2\2\u02c6\u02c7\7e\2\2\u02c7\u02c8\7q\2\2\u02c8\u02c9\7n\2"+ - "\2\u02c9\u02ca\7n\2\2\u02ca\u02cb\7c\2\2\u02cb\u02cc\7v\2\2\u02cc\u02cd"+ - "\7k\2\2\u02cd\u02ce\7q\2\2\u02ce\u02cf\7p\2\2\u02cf\u00a6\3\2\2\2\u02d0"+ - "\u02d1\7i\2\2\u02d1\u02d2\7t\2\2\u02d2\u02d3\7g\2\2\u02d3\u02d4\7c\2\2"+ - "\u02d4\u02d5\7v\2\2\u02d5\u02d6\7g\2\2\u02d6\u02d7\7u\2\2\u02d7\u02d8"+ - "\7v\2\2\u02d8\u00a8\3\2\2\2\u02d9\u02da\7n\2\2\u02da\u02db\7g\2\2\u02db"+ - "\u02dc\7c\2\2\u02dc\u02dd\7u\2\2\u02dd\u02de\7v\2\2\u02de\u00aa\3\2\2"+ - "\2\u02df\u02e0\7u\2\2\u02e0\u02e1\7y\2\2\u02e1\u02e2\7k\2\2\u02e2\u02e3"+ - "\7v\2\2\u02e3\u02e4\7e\2\2\u02e4\u02e5\7j\2\2\u02e5\u00ac\3\2\2\2\u02e6"+ - "\u02e7\7e\2\2\u02e7\u02e8\7c\2\2\u02e8\u02e9\7u\2\2\u02e9\u02ea\7g\2\2"+ - "\u02ea\u00ae\3\2\2\2\u02eb\u02ec\7v\2\2\u02ec\u02ed\7t\2\2\u02ed\u02ee"+ - "\7{\2\2\u02ee\u00b0\3\2\2\2\u02ef\u02f0\7e\2\2\u02f0\u02f1\7c\2\2\u02f1"+ - "\u02f2\7v\2\2\u02f2\u02f3\7e\2\2\u02f3\u02f4\7j\2\2\u02f4\u00b2\3\2\2"+ - "\2\u02f5\u02f6\7f\2\2\u02f6\u02f7\7g\2\2\u02f7\u02f8\7h\2\2\u02f8\u02f9"+ - "\7c\2\2\u02f9\u02fa\7w\2\2\u02fa\u02fb\7n\2\2\u02fb\u02fc\7v\2\2\u02fc"+ - "\u00b4\3\2\2\2\u02fd\u02fe\7v\2\2\u02fe\u02ff\7j\2\2\u02ff\u0300\7g\2"+ - "\2\u0300\u0301\7p\2\2\u0301\u00b6\3\2\2\2\u0302\u0303\7g\2\2\u0303\u0304"+ - "\7n\2\2\u0304\u0305\7u\2\2\u0305\u0306\7g\2\2\u0306\u00b8\3\2\2\2\u0307"+ - "\u0308\7v\2\2\u0308\u0309\7{\2\2\u0309\u030a\7r\2\2\u030a\u030b\7g\2\2"+ - "\u030b\u030c\7u\2\2\u030c\u030d\7y\2\2\u030d\u030e\7k\2\2\u030e\u030f"+ - "\7v\2\2\u030f\u0310\7e\2\2\u0310\u0311\7j\2\2\u0311\u00ba\3\2\2\2\u0312"+ - "\u0313\7q\2\2\u0313\u0314\7t\2\2\u0314\u00bc\3\2\2\2\u0315\u0316\7c\2"+ - "\2\u0316\u0317\7p\2\2\u0317\u0318\7f\2\2\u0318\u00be\3\2\2\2\u0319\u031a"+ - "\7p\2\2\u031a\u031b\7q\2\2\u031b\u031c\7v\2\2\u031c\u00c0\3\2\2\2\u031d"+ - "\u031e\7v\2\2\u031e\u031f\7q\2\2\u031f\u00c2\3\2\2\2\u0320\u0321\7k\2"+ - "\2\u0321\u0322\7p\2\2\u0322\u0323\7u\2\2\u0323\u0324\7v\2\2\u0324\u0325"+ - "\7c\2\2\u0325\u0326\7p\2\2\u0326\u0327\7e\2\2\u0327\u0328\7g\2\2\u0328"+ - "\u00c4\3\2\2\2\u0329\u032a\7q\2\2\u032a\u032b\7h\2\2\u032b\u00c6\3\2\2"+ - "\2\u032c\u032d\7u\2\2\u032d\u032e\7v\2\2\u032e\u032f\7c\2\2\u032f\u0330"+ - "\7v\2\2\u0330\u0331\7k\2\2\u0331\u0332\7e\2\2\u0332\u0333\7c\2\2\u0333"+ - "\u0334\7n\2\2\u0334\u0335\7n\2\2\u0335\u0336\7{\2\2\u0336\u00c8\3\2\2"+ - "\2\u0337\u0338\7k\2\2\u0338\u0339\7u\2\2\u0339\u00ca\3\2\2\2\u033a\u033b"+ - "\7v\2\2\u033b\u033c\7t\2\2\u033c\u033d\7g\2\2\u033d\u033e\7c\2\2\u033e"+ - "\u033f\7v\2\2\u033f\u00cc\3\2\2\2\u0340\u0341\7e\2\2\u0341\u0342\7c\2"+ - "\2\u0342\u0343\7u\2\2\u0343\u0344\7v\2\2\u0344\u00ce\3\2\2\2\u0345\u0346"+ - "\7e\2\2\u0346\u0347\7c\2\2\u0347\u0348\7u\2\2\u0348\u0349\7v\2\2\u0349"+ - "\u034a\7c\2\2\u034a\u034b\7d\2\2\u034b\u034c\7n\2\2\u034c\u034d\7g\2\2"+ - "\u034d\u00d0\3\2\2\2\u034e\u034f\7x\2\2\u034f\u0350\7g\2\2\u0350\u0351"+ - "\7t\2\2\u0351\u0352\7u\2\2\u0352\u0353\7k\2\2\u0353\u0354\7q\2\2\u0354"+ - "\u0355\7p\2\2\u0355\u00d2\3\2\2\2\u0356\u0357\7l\2\2\u0357\u0358\7u\2"+ - "\2\u0358\u0359\7q\2\2\u0359\u035a\7p\2\2\u035a\u035b\7k\2\2\u035b\u035c"+ - "\7s\2\2\u035c\u00d4\3\2\2\2\u035d\u035e\7w\2\2\u035e\u035f\7p\2\2\u035f"+ - "\u0360\7q\2\2\u0360\u0361\7t\2\2\u0361\u0362\7f\2\2\u0362\u0363\7g\2\2"+ - "\u0363\u0364\7t\2\2\u0364\u0365\7g\2\2\u0365\u0366\7f\2\2\u0366\u00d6"+ - "\3\2\2\2\u0367\u0368\7v\2\2\u0368\u0369\7t\2\2\u0369\u036a\7w\2\2\u036a"+ - "\u036b\7g\2\2\u036b\u00d8\3\2\2\2\u036c\u036d\7h\2\2\u036d\u036e\7c\2"+ - "\2\u036e\u036f\7n\2\2\u036f\u0370\7u\2\2\u0370\u0371\7g\2\2\u0371\u00da"+ - "\3\2\2\2\u0372\u0373\7v\2\2\u0373\u0374\7{\2\2\u0374\u0375\7r\2\2\u0375"+ - "\u0376\7g\2\2\u0376\u00dc\3\2\2\2\u0377\u0378\7f\2\2\u0378\u0379\7g\2"+ - "\2\u0379\u037a\7e\2\2\u037a\u037b\7n\2\2\u037b\u037c\7c\2\2\u037c\u037d"+ - "\7t\2\2\u037d\u037e\7g\2\2\u037e\u00de\3\2\2\2\u037f\u0380\7e\2\2\u0380"+ - "\u0381\7q\2\2\u0381\u0382\7p\2\2\u0382\u0383\7v\2\2\u0383\u0384\7g\2\2"+ - "\u0384\u0385\7z\2\2\u0385\u0386\7v\2\2\u0386\u00e0\3\2\2\2\u0387\u0388"+ - "\7k\2\2\u0388\u0389\7v\2\2\u0389\u038a\7g\2\2\u038a\u038b\7o\2\2\u038b"+ - "\u00e2\3\2\2\2\u038c\u038d\7x\2\2\u038d\u038e\7c\2\2\u038e\u038f\7t\2"+ - "\2\u038f\u0390\7k\2\2\u0390\u0391\7c\2\2\u0391\u0392\7d\2\2\u0392\u0393"+ - "\7n\2\2\u0393\u0394\7g\2\2\u0394\u00e4\3\2\2\2\u0395\u039a\7$\2\2\u0396"+ - "\u0399\5\u00e7t\2\u0397\u0399\n\2\2\2\u0398\u0396\3\2\2\2\u0398\u0397"+ - "\3\2\2\2\u0399\u039c\3\2\2\2\u039a\u0398\3\2\2\2\u039a\u039b\3\2\2\2\u039b"+ - "\u039d\3\2\2\2\u039c\u039a\3\2\2\2\u039d\u039e\7$\2\2\u039e\u00e6\3\2"+ - "\2\2\u039f\u03a2\7^\2\2\u03a0\u03a3\t\3\2\2\u03a1\u03a3\5\u00e9u\2\u03a2"+ - "\u03a0\3\2\2\2\u03a2\u03a1\3\2\2\2\u03a3\u00e8\3\2\2\2\u03a4\u03a5\7w"+ - "\2\2\u03a5\u03a6\5\u00ebv\2\u03a6\u03a7\5\u00ebv\2\u03a7\u03a8\5\u00eb"+ - "v\2\u03a8\u03a9\5\u00ebv\2\u03a9\u00ea\3\2\2\2\u03aa\u03ab\t\4\2\2\u03ab"+ - "\u00ec\3\2\2\2\u03ac\u03ad\7A\2\2\u03ad\u00ee\3\2\2\2\u03ae\u03af\7p\2"+ - "\2\u03af\u03b0\7w\2\2\u03b0\u03b1\7n\2\2\u03b1\u03b2\7n\2\2\u03b2\u00f0"+ - "\3\2\2\2\u03b3\u03b4\5\u00f3z\2\u03b4\u00f2\3\2\2\2\u03b5\u03b9\5\u00f5"+ - "{\2\u03b6\u03b9\5\u00f7|\2\u03b7\u03b9\5\u00f9}\2\u03b8\u03b5\3\2\2\2"+ - "\u03b8\u03b6\3\2\2\2\u03b8\u03b7\3\2\2\2\u03b9\u00f4\3\2\2\2\u03ba\u03bb"+ - "\5\u00fb~\2\u03bb\u00f6\3\2\2\2\u03bc\u03bd\7\60\2\2\u03bd\u03c7\5\u00fb"+ - "~\2\u03be\u03bf\5\u00fb~\2\u03bf\u03c3\7\60\2\2\u03c0\u03c2\t\5\2\2\u03c1"+ - "\u03c0\3\2\2\2\u03c2\u03c5\3\2\2\2\u03c3\u03c1\3\2\2\2\u03c3\u03c4\3\2"+ - "\2\2\u03c4\u03c7\3\2\2\2\u03c5\u03c3\3\2\2\2\u03c6\u03bc\3\2\2\2\u03c6"+ - "\u03be\3\2\2\2\u03c7\u00f8\3\2\2\2\u03c8\u03c9\7\60\2\2\u03c9\u03d5\5"+ - "\u00fb~\2\u03ca\u03d2\5\u00fb~\2\u03cb\u03cf\7\60\2\2\u03cc\u03ce\t\5"+ - "\2\2\u03cd\u03cc\3\2\2\2\u03ce\u03d1\3\2\2\2\u03cf\u03cd\3\2\2\2\u03cf"+ - "\u03d0\3\2\2\2\u03d0\u03d3\3\2\2\2\u03d1\u03cf\3\2\2\2\u03d2\u03cb\3\2"+ - "\2\2\u03d2\u03d3\3\2\2\2\u03d3\u03d5\3\2\2\2\u03d4\u03c8\3\2\2\2\u03d4"+ - "\u03ca\3\2\2\2\u03d5\u03d6\3\2\2\2\u03d6\u03d8\t\6\2\2\u03d7\u03d9\t\7"+ - "\2\2\u03d8\u03d7\3\2\2\2\u03d8\u03d9\3\2\2\2\u03d9\u03da\3\2\2\2\u03da"+ - "\u03db\5\u00fb~\2\u03db\u00fa\3\2\2\2\u03dc\u03de\t\5\2\2\u03dd\u03dc"+ - "\3\2\2\2\u03de\u03df\3\2\2\2\u03df\u03dd\3\2\2\2\u03df\u03e0\3\2\2\2\u03e0"+ - "\u00fc\3\2\2\2\u03e1\u03e2\t\b\2\2\u03e2\u03e3\3\2\2\2\u03e3\u03e4\b\177"+ - "\2\2\u03e4\u00fe\3\2\2\2\u03e5\u03e9\5\u0101\u0081\2\u03e6\u03e8\5\u0103"+ - "\u0082\2\u03e7\u03e6\3\2\2\2\u03e8\u03eb\3\2\2\2\u03e9\u03e7\3\2\2\2\u03e9"+ - "\u03ea\3\2\2\2\u03ea\u0100\3\2\2\2\u03eb\u03e9\3\2\2\2\u03ec\u03ee\t\t"+ - "\2\2\u03ed\u03ec\3\2\2\2\u03ee\u0102\3\2\2\2\u03ef\u03f2\5\u0101\u0081"+ - "\2\u03f0\u03f2\t\n\2\2\u03f1\u03ef\3\2\2\2\u03f1\u03f0\3\2\2\2\u03f2\u0104"+ - "\3\2\2\2\u03f3\u03f4\7*\2\2\u03f4\u03fd\7<\2\2\u03f5\u03fc\5\u0105\u0083"+ - "\2\u03f6\u03f7\7*\2\2\u03f7\u03fc\n\13\2\2\u03f8\u03f9\7<\2\2\u03f9\u03fc"+ - "\n\f\2\2\u03fa\u03fc\n\r\2\2\u03fb\u03f5\3\2\2\2\u03fb\u03f6\3\2\2\2\u03fb"+ - "\u03f8\3\2\2\2\u03fb\u03fa\3\2\2\2\u03fc\u03ff\3\2\2\2\u03fd\u03fb\3\2"+ - "\2\2\u03fd\u03fe\3\2\2\2\u03fe\u0401\3\2\2\2\u03ff\u03fd\3\2\2\2\u0400"+ - "\u0402\7<\2\2\u0401\u0400\3\2\2\2\u0402\u0403\3\2\2\2\u0403\u0401\3\2"+ - "\2\2\u0403\u0404\3\2\2\2\u0404\u0405\3\2\2\2\u0405\u0406\7+\2\2\u0406"+ - "\u0407\3\2\2\2\u0407\u0408\b\u0083\2\2\u0408\u0106\3\2\2\2\u0409\u040a"+ - "\n\16\2\2\u040a\u0108\3\2\2\2\24\2\u0398\u039a\u03a2\u03b8\u03c3\u03c6"+ - "\u03cf\u03d2\u03d4\u03d8\u03df\u03e9\u03ed\u03f1\u03fb\u03fd\u0403\3\2"+ - "\3\2"; + "\4\u0085\t\u0085\4\u0086\t\u0086\4\u0087\t\u0087\4\u0088\t\u0088\4\u0089"+ + "\t\u0089\4\u008a\t\u008a\4\u008b\t\u008b\4\u008c\t\u008c\4\u008d\t\u008d"+ + "\4\u008e\t\u008e\4\u008f\t\u008f\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\6\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\b\3\b\3\b\3\b\3\b\3\b\3\b\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\n\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\13"+ + "\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\16\3\16\3\16\3\16\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\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\21\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\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\24\3\25\3\25\3\26\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\30"+ + "\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\32\3\32\3\33\3\33\3\34\3\34\3\35"+ + "\3\35\3\35\3\35\3\35\3\35\3\35\3\36\3\36\3\36\3\36\3\36\3\36\3\36\3\36"+ + "\3\37\3\37\3\37\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.\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\3"+ + "9\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\3"+ + "D\3D\3E\3E\3E\3F\3F\3F\3G\3G\3G\3H\3H\3H\3I\3I\3I\3I\3I\3I\3I\3I\3I\3"+ + "J\3J\3J\3J\3J\3J\3K\3K\3K\3K\3K\3K\3L\3L\3L\3L\3L\3L\3L\3M\3M\3M\3M\3"+ + "M\3M\3M\3M\3M\3M\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3N\3O\3O\3O\3O\3O\3P\3"+ + "P\3P\3P\3P\3P\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3Q\3R\3R\3R\3R\3R\3R\3R\3R\3"+ + "R\3R\3S\3S\3S\3S\3S\3S\3S\3S\3S\3T\3T\3T\3T\3T\3T\3U\3U\3U\3U\3U\3U\3"+ + "U\3V\3V\3V\3V\3V\3W\3W\3W\3W\3X\3X\3X\3X\3X\3X\3Y\3Y\3Y\3Y\3Y\3Y\3Y\3"+ + "Y\3Z\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\3a\3b\3b\3b\3c\3c\3c\3c\3c\3c\3c\3c\3c\3c\3c\3d\3d\3d\3e\3e\3e\3e"+ + "\3e\3e\3f\3f\3f\3f\3f\3g\3g\3g\3g\3g\3g\3g\3g\3g\3h\3h\3h\3h\3h\3h\3h"+ + "\3h\3i\3i\3i\3i\3i\3i\3i\3j\3j\3j\3j\3j\3j\3j\3j\3j\3j\3k\3k\3k\3k\3k"+ + "\3l\3l\3l\3l\3l\3l\3m\3m\3m\3m\3m\3n\3n\3n\3n\3n\3n\3n\3n\3o\3o\3o\3o"+ + "\3o\3o\3o\3o\3p\3p\3p\3p\3p\3q\3q\3q\3q\3q\3q\3q\3q\3q\3r\3r\3r\3r\3r"+ + "\3r\3r\3s\3s\3s\3s\3s\3s\3s\3t\3t\3t\3t\3t\3t\3t\3u\3u\3u\3u\3u\3u\3u"+ + "\3u\3v\3v\3v\3v\3v\3w\3w\3w\3w\3w\3w\3w\3x\3x\3x\3x\3x\3x\3x\3y\3y\3y"+ + "\3y\3y\3z\3z\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~\7~\u03f8\n~\f~\16~\u03fb\13~\3~\3~\3\177\3\177\3"+ + "\177\5\177\u0402\n\177\3\u0080\3\u0080\3\u0080\3\u0080\3\u0080\3\u0080"+ + "\3\u0081\3\u0081\3\u0082\3\u0082\3\u0083\3\u0083\3\u0083\3\u0083\3\u0083"+ + "\3\u0084\3\u0084\3\u0085\3\u0085\3\u0085\5\u0085\u0418\n\u0085\3\u0086"+ + "\3\u0086\3\u0087\3\u0087\3\u0087\3\u0087\3\u0087\7\u0087\u0421\n\u0087"+ + "\f\u0087\16\u0087\u0424\13\u0087\5\u0087\u0426\n\u0087\3\u0088\3\u0088"+ + "\3\u0088\3\u0088\3\u0088\7\u0088\u042d\n\u0088\f\u0088\16\u0088\u0430"+ + "\13\u0088\5\u0088\u0432\n\u0088\5\u0088\u0434\n\u0088\3\u0088\3\u0088"+ + "\5\u0088\u0438\n\u0088\3\u0088\3\u0088\3\u0089\6\u0089\u043d\n\u0089\r"+ + "\u0089\16\u0089\u043e\3\u008a\3\u008a\3\u008a\3\u008a\3\u008b\3\u008b"+ + "\7\u008b\u0447\n\u008b\f\u008b\16\u008b\u044a\13\u008b\3\u008c\5\u008c"+ + "\u044d\n\u008c\3\u008d\3\u008d\5\u008d\u0451\n\u008d\3\u008e\3\u008e\3"+ + "\u008e\3\u008e\3\u008e\3\u008e\3\u008e\3\u008e\7\u008e\u045b\n\u008e\f"+ + "\u008e\16\u008e\u045e\13\u008e\3\u008e\6\u008e\u0461\n\u008e\r\u008e\16"+ + "\u008e\u0462\3\u008e\3\u008e\3\u008e\3\u008e\3\u008f\3\u008f\2\2\u0090"+ + "\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20"+ + "\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36;\37"+ + "= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65i\66k\67m8o"+ + "9q:s;u{?}@\177A\u0081B\u0083C\u0085D\u0087E\u0089F\u008bG\u008dH"+ + "\u008fI\u0091J\u0093K\u0095L\u0097M\u0099N\u009bO\u009dP\u009fQ\u00a1"+ + "R\u00a3S\u00a5T\u00a7U\u00a9V\u00abW\u00adX\u00afY\u00b1Z\u00b3[\u00b5"+ + "\\\u00b7]\u00b9^\u00bb_\u00bd`\u00bfa\u00c1b\u00c3c\u00c5d\u00c7e\u00c9"+ + "f\u00cbg\u00cdh\u00cfi\u00d1j\u00d3k\u00d5l\u00d7m\u00d9n\u00dbo\u00dd"+ + "p\u00dfq\u00e1r\u00e3s\u00e5t\u00e7u\u00e9v\u00ebw\u00edx\u00efy\u00f1"+ + "z\u00f3{\u00f5|\u00f7}\u00f9~\u00fb\177\u00fd\2\u00ff\2\u0101\2\u0103"+ + "\u0080\u0105\u0081\u0107\u0082\u0109\u0083\u010b\u0084\u010d\u0085\u010f"+ + "\u0086\u0111\2\u0113\u0087\u0115\u0088\u0117\2\u0119\2\u011b\u0089\u011d"+ + "\u008a\3\2\17\4\2$$^^\n\2$$\61\61^^ddhhppttvv\5\2\62;CHch\3\2\62;\4\2"+ + "GGgg\4\2--//\5\2\13\f\17\17\"\"\20\2C\\aac|\u00c2\u00d8\u00da\u00f8\u00fa"+ + "\u0301\u0372\u037f\u0381\u2001\u200e\u200f\u2072\u2191\u2c02\u2ff1\u3003"+ + "\ud801\uf902\ufdd1\ufdf2\uffff\7\2//\62;\u00b9\u00b9\u0302\u0371\u2041"+ + "\u2042\3\2<<\3\2++\4\2**<<\7\2$$()>>}}\177\177\2\u0476\2\3\3\2\2\2\2\5"+ + "\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2"+ + "\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33"+ + "\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2"+ + "\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2"+ + "\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2"+ + "\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K"+ + "\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2"+ + "\2\2\2Y\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2"+ + "\2e\3\2\2\2\2g\3\2\2\2\2i\3\2\2\2\2k\3\2\2\2\2m\3\2\2\2\2o\3\2\2\2\2q"+ + "\3\2\2\2\2s\3\2\2\2\2u\3\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3\2"+ + "\2\2\2\177\3\2\2\2\2\u0081\3\2\2\2\2\u0083\3\2\2\2\2\u0085\3\2\2\2\2\u0087"+ + "\3\2\2\2\2\u0089\3\2\2\2\2\u008b\3\2\2\2\2\u008d\3\2\2\2\2\u008f\3\2\2"+ + "\2\2\u0091\3\2\2\2\2\u0093\3\2\2\2\2\u0095\3\2\2\2\2\u0097\3\2\2\2\2\u0099"+ + "\3\2\2\2\2\u009b\3\2\2\2\2\u009d\3\2\2\2\2\u009f\3\2\2\2\2\u00a1\3\2\2"+ + "\2\2\u00a3\3\2\2\2\2\u00a5\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9\3\2\2\2\2\u00ab"+ + "\3\2\2\2\2\u00ad\3\2\2\2\2\u00af\3\2\2\2\2\u00b1\3\2\2\2\2\u00b3\3\2\2"+ + "\2\2\u00b5\3\2\2\2\2\u00b7\3\2\2\2\2\u00b9\3\2\2\2\2\u00bb\3\2\2\2\2\u00bd"+ + "\3\2\2\2\2\u00bf\3\2\2\2\2\u00c1\3\2\2\2\2\u00c3\3\2\2\2\2\u00c5\3\2\2"+ + "\2\2\u00c7\3\2\2\2\2\u00c9\3\2\2\2\2\u00cb\3\2\2\2\2\u00cd\3\2\2\2\2\u00cf"+ + "\3\2\2\2\2\u00d1\3\2\2\2\2\u00d3\3\2\2\2\2\u00d5\3\2\2\2\2\u00d7\3\2\2"+ + "\2\2\u00d9\3\2\2\2\2\u00db\3\2\2\2\2\u00dd\3\2\2\2\2\u00df\3\2\2\2\2\u00e1"+ + "\3\2\2\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\u00eb\3\2\2\2\2\u00ed\3\2\2\2\2\u00ef\3\2\2\2\2\u00f1\3\2\2\2\2\u00f3"+ + "\3\2\2\2\2\u00f5\3\2\2\2\2\u00f7\3\2\2\2\2\u00f9\3\2\2\2\2\u00fb\3\2\2"+ + "\2\2\u0103\3\2\2\2\2\u0105\3\2\2\2\2\u0107\3\2\2\2\2\u0109\3\2\2\2\2\u010b"+ + "\3\2\2\2\2\u010d\3\2\2\2\2\u010f\3\2\2\2\2\u0113\3\2\2\2\2\u0115\3\2\2"+ + "\2\2\u011b\3\2\2\2\2\u011d\3\2\2\2\3\u011f\3\2\2\2\5\u0121\3\2\2\2\7\u0128"+ + "\3\2\2\2\t\u0132\3\2\2\2\13\u0134\3\2\2\2\r\u013d\3\2\2\2\17\u0145\3\2"+ + "\2\2\21\u0154\3\2\2\2\23\u0156\3\2\2\2\25\u0168\3\2\2\2\27\u017b\3\2\2"+ + "\2\31\u0184\3\2\2\2\33\u018f\3\2\2\2\35\u0193\3\2\2\2\37\u019b\3\2\2\2"+ + "!\u01a5\3\2\2\2#\u01b0\3\2\2\2%\u01b6\3\2\2\2\'\u01c8\3\2\2\2)\u01cf\3"+ + "\2\2\2+\u01d1\3\2\2\2-\u01d4\3\2\2\2/\u01dd\3\2\2\2\61\u01e6\3\2\2\2\63"+ + "\u01e8\3\2\2\2\65\u01ea\3\2\2\2\67\u01ec\3\2\2\29\u01ee\3\2\2\2;\u01f5"+ + "\3\2\2\2=\u01fd\3\2\2\2?\u0205\3\2\2\2A\u020c\3\2\2\2C\u020e\3\2\2\2E"+ + "\u0210\3\2\2\2G\u0212\3\2\2\2I\u0215\3\2\2\2K\u0218\3\2\2\2M\u021b\3\2"+ + "\2\2O\u021e\3\2\2\2Q\u0221\3\2\2\2S\u0224\3\2\2\2U\u0227\3\2\2\2W\u0229"+ + "\3\2\2\2Y\u022c\3\2\2\2[\u022e\3\2\2\2]\u0231\3\2\2\2_\u0234\3\2\2\2a"+ + "\u0236\3\2\2\2c\u0238\3\2\2\2e\u023c\3\2\2\2g\u0241\3\2\2\2i\u0245\3\2"+ + "\2\2k\u024e\3\2\2\2m\u0250\3\2\2\2o\u0252\3\2\2\2q\u0254\3\2\2\2s\u0256"+ + "\3\2\2\2u\u0259\3\2\2\2w\u025b\3\2\2\2y\u025e\3\2\2\2{\u0261\3\2\2\2}"+ + "\u0265\3\2\2\2\177\u0269\3\2\2\2\u0081\u026f\3\2\2\2\u0083\u0275\3\2\2"+ + "\2\u0085\u0278\3\2\2\2\u0087\u027e\3\2\2\2\u0089\u0285\3\2\2\2\u008b\u0288"+ + "\3\2\2\2\u008d\u028b\3\2\2\2\u008f\u028e\3\2\2\2\u0091\u0291\3\2\2\2\u0093"+ + "\u029a\3\2\2\2\u0095\u02a0\3\2\2\2\u0097\u02a6\3\2\2\2\u0099\u02ad\3\2"+ + "\2\2\u009b\u02b7\3\2\2\2\u009d\u02c2\3\2\2\2\u009f\u02c7\3\2\2\2\u00a1"+ + "\u02cd\3\2\2\2\u00a3\u02d7\3\2\2\2\u00a5\u02e1\3\2\2\2\u00a7\u02ea\3\2"+ + "\2\2\u00a9\u02f0\3\2\2\2\u00ab\u02f7\3\2\2\2\u00ad\u02fc\3\2\2\2\u00af"+ + "\u0300\3\2\2\2\u00b1\u0306\3\2\2\2\u00b3\u030e\3\2\2\2\u00b5\u0313\3\2"+ + "\2\2\u00b7\u0318\3\2\2\2\u00b9\u0323\3\2\2\2\u00bb\u0326\3\2\2\2\u00bd"+ + "\u032a\3\2\2\2\u00bf\u032e\3\2\2\2\u00c1\u0331\3\2\2\2\u00c3\u033a\3\2"+ + "\2\2\u00c5\u033d\3\2\2\2\u00c7\u0348\3\2\2\2\u00c9\u034b\3\2\2\2\u00cb"+ + "\u0351\3\2\2\2\u00cd\u0356\3\2\2\2\u00cf\u035f\3\2\2\2\u00d1\u0367\3\2"+ + "\2\2\u00d3\u036e\3\2\2\2\u00d5\u0378\3\2\2\2\u00d7\u037d\3\2\2\2\u00d9"+ + "\u0383\3\2\2\2\u00db\u0388\3\2\2\2\u00dd\u0390\3\2\2\2\u00df\u0398\3\2"+ + "\2\2\u00e1\u039d\3\2\2\2\u00e3\u03a6\3\2\2\2\u00e5\u03ad\3\2\2\2\u00e7"+ + "\u03b4\3\2\2\2\u00e9\u03bb\3\2\2\2\u00eb\u03c3\3\2\2\2\u00ed\u03c8\3\2"+ + "\2\2\u00ef\u03cf\3\2\2\2\u00f1\u03d6\3\2\2\2\u00f3\u03db\3\2\2\2\u00f5"+ + "\u03e1\3\2\2\2\u00f7\u03e6\3\2\2\2\u00f9\u03eb\3\2\2\2\u00fb\u03f4\3\2"+ + "\2\2\u00fd\u03fe\3\2\2\2\u00ff\u0403\3\2\2\2\u0101\u0409\3\2\2\2\u0103"+ + "\u040b\3\2\2\2\u0105\u040d\3\2\2\2\u0107\u0412\3\2\2\2\u0109\u0417\3\2"+ + "\2\2\u010b\u0419\3\2\2\2\u010d\u0425\3\2\2\2\u010f\u0433\3\2\2\2\u0111"+ + "\u043c\3\2\2\2\u0113\u0440\3\2\2\2\u0115\u0444\3\2\2\2\u0117\u044c\3\2"+ + "\2\2\u0119\u0450\3\2\2\2\u011b\u0452\3\2\2\2\u011d\u0468\3\2\2\2\u011f"+ + "\u0120\7=\2\2\u0120\4\3\2\2\2\u0121\u0122\7o\2\2\u0122\u0123\7q\2\2\u0123"+ + "\u0124\7f\2\2\u0124\u0125\7w\2\2\u0125\u0126\7n\2\2\u0126\u0127\7g\2\2"+ + "\u0127\6\3\2\2\2\u0128\u0129\7p\2\2\u0129\u012a\7c\2\2\u012a\u012b\7o"+ + "\2\2\u012b\u012c\7g\2\2\u012c\u012d\7u\2\2\u012d\u012e\7r\2\2\u012e\u012f"+ + "\7c\2\2\u012f\u0130\7e\2\2\u0130\u0131\7g\2\2\u0131\b\3\2\2\2\u0132\u0133"+ + "\7?\2\2\u0133\n\3\2\2\2\u0134\u0135\7q\2\2\u0135\u0136\7t\2\2\u0136\u0137"+ + "\7f\2\2\u0137\u0138\7g\2\2\u0138\u0139\7t\2\2\u0139\u013a\7k\2\2\u013a"+ + "\u013b\7p\2\2\u013b\u013c\7i\2\2\u013c\f\3\2\2\2\u013d\u013e\7q\2\2\u013e"+ + "\u013f\7t\2\2\u013f\u0140\7f\2\2\u0140\u0141\7g\2\2\u0141\u0142\7t\2\2"+ + "\u0142\u0143\7g\2\2\u0143\u0144\7f\2\2\u0144\16\3\2\2\2\u0145\u0146\7"+ + "f\2\2\u0146\u0147\7g\2\2\u0147\u0148\7e\2\2\u0148\u0149\7k\2\2\u0149\u014a"+ + "\7o\2\2\u014a\u014b\7c\2\2\u014b\u014c\7n\2\2\u014c\u014d\7/\2\2\u014d"+ + "\u014e\7h\2\2\u014e\u014f\7q\2\2\u014f\u0150\7t\2\2\u0150\u0151\7o\2\2"+ + "\u0151\u0152\7c\2\2\u0152\u0153\7v\2\2\u0153\20\3\2\2\2\u0154\u0155\7"+ + "<\2\2\u0155\22\3\2\2\2\u0156\u0157\7f\2\2\u0157\u0158\7g\2\2\u0158\u0159"+ + "\7e\2\2\u0159\u015a\7k\2\2\u015a\u015b\7o\2\2\u015b\u015c\7c\2\2\u015c"+ + "\u015d\7n\2\2\u015d\u015e\7/\2\2\u015e\u015f\7u\2\2\u015f\u0160\7g\2\2"+ + "\u0160\u0161\7r\2\2\u0161\u0162\7c\2\2\u0162\u0163\7t\2\2\u0163\u0164"+ + "\7c\2\2\u0164\u0165\7v\2\2\u0165\u0166\7q\2\2\u0166\u0167\7t\2\2\u0167"+ + "\24\3\2\2\2\u0168\u0169\7i\2\2\u0169\u016a\7t\2\2\u016a\u016b\7q\2\2\u016b"+ + "\u016c\7w\2\2\u016c\u016d\7r\2\2\u016d\u016e\7k\2\2\u016e\u016f\7p\2\2"+ + "\u016f\u0170\7i\2\2\u0170\u0171\7/\2\2\u0171\u0172\7u\2\2\u0172\u0173"+ + "\7g\2\2\u0173\u0174\7r\2\2\u0174\u0175\7c\2\2\u0175\u0176\7t\2\2\u0176"+ + "\u0177\7c\2\2\u0177\u0178\7v\2\2\u0178\u0179\7q\2\2\u0179\u017a\7t\2\2"+ + "\u017a\26\3\2\2\2\u017b\u017c\7k\2\2\u017c\u017d\7p\2\2\u017d\u017e\7"+ + "h\2\2\u017e\u017f\7k\2\2\u017f\u0180\7p\2\2\u0180\u0181\7k\2\2\u0181\u0182"+ + "\7v\2\2\u0182\u0183\7{\2\2\u0183\30\3\2\2\2\u0184\u0185\7o\2\2\u0185\u0186"+ + "\7k\2\2\u0186\u0187\7p\2\2\u0187\u0188\7w\2\2\u0188\u0189\7u\2\2\u0189"+ + "\u018a\7/\2\2\u018a\u018b\7u\2\2\u018b\u018c\7k\2\2\u018c\u018d\7i\2\2"+ + "\u018d\u018e\7p\2\2\u018e\32\3\2\2\2\u018f\u0190\7P\2\2\u0190\u0191\7"+ + "c\2\2\u0191\u0192\7P\2\2\u0192\34\3\2\2\2\u0193\u0194\7r\2\2\u0194\u0195"+ + "\7g\2\2\u0195\u0196\7t\2\2\u0196\u0197\7e\2\2\u0197\u0198\7g\2\2\u0198"+ + "\u0199\7p\2\2\u0199\u019a\7v\2\2\u019a\36\3\2\2\2\u019b\u019c\7r\2\2\u019c"+ + "\u019d\7g\2\2\u019d\u019e\7t\2\2\u019e\u019f\7/\2\2\u019f\u01a0\7o\2\2"+ + "\u01a0\u01a1\7k\2\2\u01a1\u01a2\7n\2\2\u01a2\u01a3\7n\2\2\u01a3\u01a4"+ + "\7g\2\2\u01a4 \3\2\2\2\u01a5\u01a6\7|\2\2\u01a6\u01a7\7g\2\2\u01a7\u01a8"+ + "\7t\2\2\u01a8\u01a9\7q\2\2\u01a9\u01aa\7/\2\2\u01aa\u01ab\7f\2\2\u01ab"+ + "\u01ac\7k\2\2\u01ac\u01ad\7i\2\2\u01ad\u01ae\7k\2\2\u01ae\u01af\7v\2\2"+ + "\u01af\"\3\2\2\2\u01b0\u01b1\7f\2\2\u01b1\u01b2\7k\2\2\u01b2\u01b3\7i"+ + "\2\2\u01b3\u01b4\7k\2\2\u01b4\u01b5\7v\2\2\u01b5$\3\2\2\2\u01b6\u01b7"+ + "\7r\2\2\u01b7\u01b8\7c\2\2\u01b8\u01b9\7v\2\2\u01b9\u01ba\7v\2\2\u01ba"+ + "\u01bb\7g\2\2\u01bb\u01bc\7t\2\2\u01bc\u01bd\7p\2\2\u01bd\u01be\7/\2\2"+ + "\u01be\u01bf\7u\2\2\u01bf\u01c0\7g\2\2\u01c0\u01c1\7r\2\2\u01c1\u01c2"+ + "\7c\2\2\u01c2\u01c3\7t\2\2\u01c3\u01c4\7c\2\2\u01c4\u01c5\7v\2\2\u01c5"+ + "\u01c6\7q\2\2\u01c6\u01c7\7t\2\2\u01c7&\3\2\2\2\u01c8\u01c9\7k\2\2\u01c9"+ + "\u01ca\7o\2\2\u01ca\u01cb\7r\2\2\u01cb\u01cc\7q\2\2\u01cc\u01cd\7t\2\2"+ + "\u01cd\u01ce\7v\2\2\u01ce(\3\2\2\2\u01cf\u01d0\7.\2\2\u01d0*\3\2\2\2\u01d1"+ + "\u01d2\7<\2\2\u01d2\u01d3\7?\2\2\u01d3,\3\2\2\2\u01d4\u01d5\7g\2\2\u01d5"+ + "\u01d6\7z\2\2\u01d6\u01d7\7v\2\2\u01d7\u01d8\7g\2\2\u01d8\u01d9\7t\2\2"+ + "\u01d9\u01da\7p\2\2\u01da\u01db\7c\2\2\u01db\u01dc\7n\2\2\u01dc.\3\2\2"+ + "\2\u01dd\u01de\7h\2\2\u01de\u01df\7w\2\2\u01df\u01e0\7p\2\2\u01e0\u01e1"+ + "\7e\2\2\u01e1\u01e2\7v\2\2\u01e2\u01e3\7k\2\2\u01e3\u01e4\7q\2\2\u01e4"+ + "\u01e5\7p\2\2\u01e5\60\3\2\2\2\u01e6\u01e7\7*\2\2\u01e7\62\3\2\2\2\u01e8"+ + "\u01e9\7+\2\2\u01e9\64\3\2\2\2\u01ea\u01eb\7}\2\2\u01eb\66\3\2\2\2\u01ec"+ + "\u01ed\7\177\2\2\u01ed8\3\2\2\2\u01ee\u01ef\7l\2\2\u01ef\u01f0\7u\2\2"+ + "\u01f0\u01f1\7q\2\2\u01f1\u01f2\7w\2\2\u01f2\u01f3\7p\2\2\u01f3\u01f4"+ + "\7f\2\2\u01f4:\3\2\2\2\u01f5\u01f6\7e\2\2\u01f6\u01f7\7q\2\2\u01f7\u01f8"+ + "\7o\2\2\u01f8\u01f9\7r\2\2\u01f9\u01fa\7c\2\2\u01fa\u01fb\7e\2\2\u01fb"+ + "\u01fc\7v\2\2\u01fc<\3\2\2\2\u01fd\u01fe\7x\2\2\u01fe\u01ff\7g\2\2\u01ff"+ + "\u0200\7t\2\2\u0200\u0201\7d\2\2\u0201\u0202\7q\2\2\u0202\u0203\7u\2\2"+ + "\u0203\u0204\7g\2\2\u0204>\3\2\2\2\u0205\u0206\7u\2\2\u0206\u0207\7e\2"+ + "\2\u0207\u0208\7j\2\2\u0208\u0209\7g\2\2\u0209\u020a\7o\2\2\u020a\u020b"+ + "\7c\2\2\u020b@\3\2\2\2\u020c\u020d\7&\2\2\u020dB\3\2\2\2\u020e\u020f\7"+ + "~\2\2\u020fD\3\2\2\2\u0210\u0211\7,\2\2\u0211F\3\2\2\2\u0212\u0213\7g"+ + "\2\2\u0213\u0214\7s\2\2\u0214H\3\2\2\2\u0215\u0216\7p\2\2\u0216\u0217"+ + "\7g\2\2\u0217J\3\2\2\2\u0218\u0219\7n\2\2\u0219\u021a\7v\2\2\u021aL\3"+ + "\2\2\2\u021b\u021c\7n\2\2\u021c\u021d\7g\2\2\u021dN\3\2\2\2\u021e\u021f"+ + "\7i\2\2\u021f\u0220\7v\2\2\u0220P\3\2\2\2\u0221\u0222\7i\2\2\u0222\u0223"+ + "\7g\2\2\u0223R\3\2\2\2\u0224\u0225\7#\2\2\u0225\u0226\7?\2\2\u0226T\3"+ + "\2\2\2\u0227\u0228\7>\2\2\u0228V\3\2\2\2\u0229\u022a\7>\2\2\u022a\u022b"+ + "\7?\2\2\u022bX\3\2\2\2\u022c\u022d\7@\2\2\u022dZ\3\2\2\2\u022e\u022f\7"+ + "@\2\2\u022f\u0230\7?\2\2\u0230\\\3\2\2\2\u0231\u0232\7~\2\2\u0232\u0233"+ + "\7~\2\2\u0233^\3\2\2\2\u0234\u0235\7-\2\2\u0235`\3\2\2\2\u0236\u0237\7"+ + "/\2\2\u0237b\3\2\2\2\u0238\u0239\7f\2\2\u0239\u023a\7k\2\2\u023a\u023b"+ + "\7x\2\2\u023bd\3\2\2\2\u023c\u023d\7k\2\2\u023d\u023e\7f\2\2\u023e\u023f"+ + "\7k\2\2\u023f\u0240\7x\2\2\u0240f\3\2\2\2\u0241\u0242\7o\2\2\u0242\u0243"+ + "\7q\2\2\u0243\u0244\7f\2\2\u0244h\3\2\2\2\u0245\u0246\7x\2\2\u0246\u0247"+ + "\7c\2\2\u0247\u0248\7n\2\2\u0248\u0249\7k\2\2\u0249\u024a\7f\2\2\u024a"+ + "\u024b\7c\2\2\u024b\u024c\7v\2\2\u024c\u024d\7g\2\2\u024dj\3\2\2\2\u024e"+ + "\u024f\7#\2\2\u024fl\3\2\2\2\u0250\u0251\7]\2\2\u0251n\3\2\2\2\u0252\u0253"+ + "\7_\2\2\u0253p\3\2\2\2\u0254\u0255\7\60\2\2\u0255r\3\2\2\2\u0256\u0257"+ + "\7&\2\2\u0257\u0258\7&\2\2\u0258t\3\2\2\2\u0259\u025a\7%\2\2\u025av\3"+ + "\2\2\2\u025b\u025c\7}\2\2\u025c\u025d\7~\2\2\u025dx\3\2\2\2\u025e\u025f"+ + "\7~\2\2\u025f\u0260\7\177\2\2\u0260z\3\2\2\2\u0261\u0262\7h\2\2\u0262"+ + "\u0263\7q\2\2\u0263\u0264\7t\2\2\u0264|\3\2\2\2\u0265\u0266\7n\2\2\u0266"+ + "\u0267\7g\2\2\u0267\u0268\7v\2\2\u0268~\3\2\2\2\u0269\u026a\7y\2\2\u026a"+ + "\u026b\7j\2\2\u026b\u026c\7g\2\2\u026c\u026d\7t\2\2\u026d\u026e\7g\2\2"+ + "\u026e\u0080\3\2\2\2\u026f\u0270\7i\2\2\u0270\u0271\7t\2\2\u0271\u0272"+ + "\7q\2\2\u0272\u0273\7w\2\2\u0273\u0274\7r\2\2\u0274\u0082\3\2\2\2\u0275"+ + "\u0276\7d\2\2\u0276\u0277\7{\2\2\u0277\u0084\3\2\2\2\u0278\u0279\7q\2"+ + "\2\u0279\u027a\7t\2\2\u027a\u027b\7f\2\2\u027b\u027c\7g\2\2\u027c\u027d"+ + "\7t\2\2\u027d\u0086\3\2\2\2\u027e\u027f\7t\2\2\u027f\u0280\7g\2\2\u0280"+ + "\u0281\7v\2\2\u0281\u0282\7w\2\2\u0282\u0283\7t\2\2\u0283\u0284\7p\2\2"+ + "\u0284\u0088\3\2\2\2\u0285\u0286\7k\2\2\u0286\u0287\7h\2\2\u0287\u008a"+ + "\3\2\2\2\u0288\u0289\7k\2\2\u0289\u028a\7p\2\2\u028a\u008c\3\2\2\2\u028b"+ + "\u028c\7c\2\2\u028c\u028d\7u\2\2\u028d\u008e\3\2\2\2\u028e\u028f\7c\2"+ + "\2\u028f\u0290\7v\2\2\u0290\u0090\3\2\2\2\u0291\u0292\7c\2\2\u0292\u0293"+ + "\7n\2\2\u0293\u0294\7n\2\2\u0294\u0295\7q\2\2\u0295\u0296\7y\2\2\u0296"+ + "\u0297\7k\2\2\u0297\u0298\7p\2\2\u0298\u0299\7i\2\2\u0299\u0092\3\2\2"+ + "\2\u029a\u029b\7g\2\2\u029b\u029c\7o\2\2\u029c\u029d\7r\2\2\u029d\u029e"+ + "\7v\2\2\u029e\u029f\7{\2\2\u029f\u0094\3\2\2\2\u02a0\u02a1\7e\2\2\u02a1"+ + "\u02a2\7q\2\2\u02a2\u02a3\7w\2\2\u02a3\u02a4\7p\2\2\u02a4\u02a5\7v\2\2"+ + "\u02a5\u0096\3\2\2\2\u02a6\u02a7\7u\2\2\u02a7\u02a8\7v\2\2\u02a8\u02a9"+ + "\7c\2\2\u02a9\u02aa\7d\2\2\u02aa\u02ab\7n\2\2\u02ab\u02ac\7g\2\2\u02ac"+ + "\u0098\3\2\2\2\u02ad\u02ae\7c\2\2\u02ae\u02af\7u\2\2\u02af\u02b0\7e\2"+ + "\2\u02b0\u02b1\7g\2\2\u02b1\u02b2\7p\2\2\u02b2\u02b3\7f\2\2\u02b3\u02b4"+ + "\7k\2\2\u02b4\u02b5\7p\2\2\u02b5\u02b6\7i\2\2\u02b6\u009a\3\2\2\2\u02b7"+ + "\u02b8\7f\2\2\u02b8\u02b9\7g\2\2\u02b9\u02ba\7u\2\2\u02ba\u02bb\7e\2\2"+ + "\u02bb\u02bc\7g\2\2\u02bc\u02bd\7p\2\2\u02bd\u02be\7f\2\2\u02be\u02bf"+ + "\7k\2\2\u02bf\u02c0\7p\2\2\u02c0\u02c1\7i\2\2\u02c1\u009c\3\2\2\2\u02c2"+ + "\u02c3\7u\2\2\u02c3\u02c4\7q\2\2\u02c4\u02c5\7o\2\2\u02c5\u02c6\7g\2\2"+ + "\u02c6\u009e\3\2\2\2\u02c7\u02c8\7g\2\2\u02c8\u02c9\7x\2\2\u02c9\u02ca"+ + "\7g\2\2\u02ca\u02cb\7t\2\2\u02cb\u02cc\7{\2\2\u02cc\u00a0\3\2\2\2\u02cd"+ + "\u02ce\7u\2\2\u02ce\u02cf\7c\2\2\u02cf\u02d0\7v\2\2\u02d0\u02d1\7k\2\2"+ + "\u02d1\u02d2\7u\2\2\u02d2\u02d3\7h\2\2\u02d3\u02d4\7k\2\2\u02d4\u02d5"+ + "\7g\2\2\u02d5\u02d6\7u\2\2\u02d6\u00a2\3\2\2\2\u02d7\u02d8\7e\2\2\u02d8"+ + "\u02d9\7q\2\2\u02d9\u02da\7n\2\2\u02da\u02db\7n\2\2\u02db\u02dc\7c\2\2"+ + "\u02dc\u02dd\7v\2\2\u02dd\u02de\7k\2\2\u02de\u02df\7q\2\2\u02df\u02e0"+ + "\7p\2\2\u02e0\u00a4\3\2\2\2\u02e1\u02e2\7i\2\2\u02e2\u02e3\7t\2\2\u02e3"+ + "\u02e4\7g\2\2\u02e4\u02e5\7c\2\2\u02e5\u02e6\7v\2\2\u02e6\u02e7\7g\2\2"+ + "\u02e7\u02e8\7u\2\2\u02e8\u02e9\7v\2\2\u02e9\u00a6\3\2\2\2\u02ea\u02eb"+ + "\7n\2\2\u02eb\u02ec\7g\2\2\u02ec\u02ed\7c\2\2\u02ed\u02ee\7u\2\2\u02ee"+ + "\u02ef\7v\2\2\u02ef\u00a8\3\2\2\2\u02f0\u02f1\7u\2\2\u02f1\u02f2\7y\2"+ + "\2\u02f2\u02f3\7k\2\2\u02f3\u02f4\7v\2\2\u02f4\u02f5\7e\2\2\u02f5\u02f6"+ + "\7j\2\2\u02f6\u00aa\3\2\2\2\u02f7\u02f8\7e\2\2\u02f8\u02f9\7c\2\2\u02f9"+ + "\u02fa\7u\2\2\u02fa\u02fb\7g\2\2\u02fb\u00ac\3\2\2\2\u02fc\u02fd\7v\2"+ + "\2\u02fd\u02fe\7t\2\2\u02fe\u02ff\7{\2\2\u02ff\u00ae\3\2\2\2\u0300\u0301"+ + "\7e\2\2\u0301\u0302\7c\2\2\u0302\u0303\7v\2\2\u0303\u0304\7e\2\2\u0304"+ + "\u0305\7j\2\2\u0305\u00b0\3\2\2\2\u0306\u0307\7f\2\2\u0307\u0308\7g\2"+ + "\2\u0308\u0309\7h\2\2\u0309\u030a\7c\2\2\u030a\u030b\7w\2\2\u030b\u030c"+ + "\7n\2\2\u030c\u030d\7v\2\2\u030d\u00b2\3\2\2\2\u030e\u030f\7v\2\2\u030f"+ + "\u0310\7j\2\2\u0310\u0311\7g\2\2\u0311\u0312\7p\2\2\u0312\u00b4\3\2\2"+ + "\2\u0313\u0314\7g\2\2\u0314\u0315\7n\2\2\u0315\u0316\7u\2\2\u0316\u0317"+ + "\7g\2\2\u0317\u00b6\3\2\2\2\u0318\u0319\7v\2\2\u0319\u031a\7{\2\2\u031a"+ + "\u031b\7r\2\2\u031b\u031c\7g\2\2\u031c\u031d\7u\2\2\u031d\u031e\7y\2\2"+ + "\u031e\u031f\7k\2\2\u031f\u0320\7v\2\2\u0320\u0321\7e\2\2\u0321\u0322"+ + "\7j\2\2\u0322\u00b8\3\2\2\2\u0323\u0324\7q\2\2\u0324\u0325\7t\2\2\u0325"+ + "\u00ba\3\2\2\2\u0326\u0327\7c\2\2\u0327\u0328\7p\2\2\u0328\u0329\7f\2"+ + "\2\u0329\u00bc\3\2\2\2\u032a\u032b\7p\2\2\u032b\u032c\7q\2\2\u032c\u032d"+ + "\7v\2\2\u032d\u00be\3\2\2\2\u032e\u032f\7v\2\2\u032f\u0330\7q\2\2\u0330"+ + "\u00c0\3\2\2\2\u0331\u0332\7k\2\2\u0332\u0333\7p\2\2\u0333\u0334\7u\2"+ + "\2\u0334\u0335\7v\2\2\u0335\u0336\7c\2\2\u0336\u0337\7p\2\2\u0337\u0338"+ + "\7e\2\2\u0338\u0339\7g\2\2\u0339\u00c2\3\2\2\2\u033a\u033b\7q\2\2\u033b"+ + "\u033c\7h\2\2\u033c\u00c4\3\2\2\2\u033d\u033e\7u\2\2\u033e\u033f\7v\2"+ + "\2\u033f\u0340\7c\2\2\u0340\u0341\7v\2\2\u0341\u0342\7k\2\2\u0342\u0343"+ + "\7e\2\2\u0343\u0344\7c\2\2\u0344\u0345\7n\2\2\u0345\u0346\7n\2\2\u0346"+ + "\u0347\7{\2\2\u0347\u00c6\3\2\2\2\u0348\u0349\7k\2\2\u0349\u034a\7u\2"+ + "\2\u034a\u00c8\3\2\2\2\u034b\u034c\7v\2\2\u034c\u034d\7t\2\2\u034d\u034e"+ + "\7g\2\2\u034e\u034f\7c\2\2\u034f\u0350\7v\2\2\u0350\u00ca\3\2\2\2\u0351"+ + "\u0352\7e\2\2\u0352\u0353\7c\2\2\u0353\u0354\7u\2\2\u0354\u0355\7v\2\2"+ + "\u0355\u00cc\3\2\2\2\u0356\u0357\7e\2\2\u0357\u0358\7c\2\2\u0358\u0359"+ + "\7u\2\2\u0359\u035a\7v\2\2\u035a\u035b\7c\2\2\u035b\u035c\7d\2\2\u035c"+ + "\u035d\7n\2\2\u035d\u035e\7g\2\2\u035e\u00ce\3\2\2\2\u035f\u0360\7x\2"+ + "\2\u0360\u0361\7g\2\2\u0361\u0362\7t\2\2\u0362\u0363\7u\2\2\u0363\u0364"+ + "\7k\2\2\u0364\u0365\7q\2\2\u0365\u0366\7p\2\2\u0366\u00d0\3\2\2\2\u0367"+ + "\u0368\7l\2\2\u0368\u0369\7u\2\2\u0369\u036a\7q\2\2\u036a\u036b\7p\2\2"+ + "\u036b\u036c\7k\2\2\u036c\u036d\7s\2\2\u036d\u00d2\3\2\2\2\u036e\u036f"+ + "\7w\2\2\u036f\u0370\7p\2\2\u0370\u0371\7q\2\2\u0371\u0372\7t\2\2\u0372"+ + "\u0373\7f\2\2\u0373\u0374\7g\2\2\u0374\u0375\7t\2\2\u0375\u0376\7g\2\2"+ + "\u0376\u0377\7f\2\2\u0377\u00d4\3\2\2\2\u0378\u0379\7v\2\2\u0379\u037a"+ + "\7t\2\2\u037a\u037b\7w\2\2\u037b\u037c\7g\2\2\u037c\u00d6\3\2\2\2\u037d"+ + "\u037e\7h\2\2\u037e\u037f\7c\2\2\u037f\u0380\7n\2\2\u0380\u0381\7u\2\2"+ + "\u0381\u0382\7g\2\2\u0382\u00d8\3\2\2\2\u0383\u0384\7v\2\2\u0384\u0385"+ + "\7{\2\2\u0385\u0386\7r\2\2\u0386\u0387\7g\2\2\u0387\u00da\3\2\2\2\u0388"+ + "\u0389\7f\2\2\u0389\u038a\7g\2\2\u038a\u038b\7e\2\2\u038b\u038c\7n\2\2"+ + "\u038c\u038d\7c\2\2\u038d\u038e\7t\2\2\u038e\u038f\7g\2\2\u038f\u00dc"+ + "\3\2\2\2\u0390\u0391\7e\2\2\u0391\u0392\7q\2\2\u0392\u0393\7p\2\2\u0393"+ + "\u0394\7v\2\2\u0394\u0395\7g\2\2\u0395\u0396\7z\2\2\u0396\u0397\7v\2\2"+ + "\u0397\u00de\3\2\2\2\u0398\u0399\7k\2\2\u0399\u039a\7v\2\2\u039a\u039b"+ + "\7g\2\2\u039b\u039c\7o\2\2\u039c\u00e0\3\2\2\2\u039d\u039e\7x\2\2\u039e"+ + "\u039f\7c\2\2\u039f\u03a0\7t\2\2\u03a0\u03a1\7k\2\2\u03a1\u03a2\7c\2\2"+ + "\u03a2\u03a3\7d\2\2\u03a3\u03a4\7n\2\2\u03a4\u03a5\7g\2\2\u03a5\u00e2"+ + "\3\2\2\2\u03a6\u03a7\7k\2\2\u03a7\u03a8\7p\2\2\u03a8\u03a9\7u\2\2\u03a9"+ + "\u03aa\7g\2\2\u03aa\u03ab\7t\2\2\u03ab\u03ac\7v\2\2\u03ac\u00e4\3\2\2"+ + "\2\u03ad\u03ae\7f\2\2\u03ae\u03af\7g\2\2\u03af\u03b0\7n\2\2\u03b0\u03b1"+ + "\7g\2\2\u03b1\u03b2\7v\2\2\u03b2\u03b3\7g\2\2\u03b3\u00e6\3\2\2\2\u03b4"+ + "\u03b5\7t\2\2\u03b5\u03b6\7g\2\2\u03b6\u03b7\7p\2\2\u03b7\u03b8\7c\2\2"+ + "\u03b8\u03b9\7o\2\2\u03b9\u03ba\7g\2\2\u03ba\u00e8\3\2\2\2\u03bb\u03bc"+ + "\7t\2\2\u03bc\u03bd\7g\2\2\u03bd\u03be\7r\2\2\u03be\u03bf\7n\2\2\u03bf"+ + "\u03c0\7c\2\2\u03c0\u03c1\7e\2\2\u03c1\u03c2\7g\2\2\u03c2\u00ea\3\2\2"+ + "\2\u03c3\u03c4\7e\2\2\u03c4\u03c5\7q\2\2\u03c5\u03c6\7r\2\2\u03c6\u03c7"+ + "\7{\2\2\u03c7\u00ec\3\2\2\2\u03c8\u03c9\7o\2\2\u03c9\u03ca\7q\2\2\u03ca"+ + "\u03cb\7f\2\2\u03cb\u03cc\7k\2\2\u03cc\u03cd\7h\2\2\u03cd\u03ce\7{\2\2"+ + "\u03ce\u00ee\3\2\2\2\u03cf\u03d0\7c\2\2\u03d0\u03d1\7r\2\2\u03d1\u03d2"+ + "\7r\2\2\u03d2\u03d3\7g\2\2\u03d3\u03d4\7p\2\2\u03d4\u03d5\7f\2\2\u03d5"+ + "\u00f0\3\2\2\2\u03d6\u03d7\7k\2\2\u03d7\u03d8\7p\2\2\u03d8\u03d9\7v\2"+ + "\2\u03d9\u03da\7q\2\2\u03da\u00f2\3\2\2\2\u03db\u03dc\7x\2\2\u03dc\u03dd"+ + "\7c\2\2\u03dd\u03de\7n\2\2\u03de\u03df\7w\2\2\u03df\u03e0\7g\2\2\u03e0"+ + "\u00f4\3\2\2\2\u03e1\u03e2\7l\2\2\u03e2\u03e3\7u\2\2\u03e3\u03e4\7q\2"+ + "\2\u03e4\u03e5\7p\2\2\u03e5\u00f6\3\2\2\2\u03e6\u03e7\7y\2\2\u03e7\u03e8"+ + "\7k\2\2\u03e8\u03e9\7v\2\2\u03e9\u03ea\7j\2\2\u03ea\u00f8\3\2\2\2\u03eb"+ + "\u03ec\7r\2\2\u03ec\u03ed\7q\2\2\u03ed\u03ee\7u\2\2\u03ee\u03ef\7k\2\2"+ + "\u03ef\u03f0\7v\2\2\u03f0\u03f1\7k\2\2\u03f1\u03f2\7q\2\2\u03f2\u03f3"+ + "\7p\2\2\u03f3\u00fa\3\2\2\2\u03f4\u03f9\7$\2\2\u03f5\u03f8\5\u00fd\177"+ + "\2\u03f6\u03f8\n\2\2\2\u03f7\u03f5\3\2\2\2\u03f7\u03f6\3\2\2\2\u03f8\u03fb"+ + "\3\2\2\2\u03f9\u03f7\3\2\2\2\u03f9\u03fa\3\2\2\2\u03fa\u03fc\3\2\2\2\u03fb"+ + "\u03f9\3\2\2\2\u03fc\u03fd\7$\2\2\u03fd\u00fc\3\2\2\2\u03fe\u0401\7^\2"+ + "\2\u03ff\u0402\t\3\2\2\u0400\u0402\5\u00ff\u0080\2\u0401\u03ff\3\2\2\2"+ + "\u0401\u0400\3\2\2\2\u0402\u00fe\3\2\2\2\u0403\u0404\7w\2\2\u0404\u0405"+ + "\5\u0101\u0081\2\u0405\u0406\5\u0101\u0081\2\u0406\u0407\5\u0101\u0081"+ + "\2\u0407\u0408\5\u0101\u0081\2\u0408\u0100\3\2\2\2\u0409\u040a\t\4\2\2"+ + "\u040a\u0102\3\2\2\2\u040b\u040c\7A\2\2\u040c\u0104\3\2\2\2\u040d\u040e"+ + "\7p\2\2\u040e\u040f\7w\2\2\u040f\u0410\7n\2\2\u0410\u0411\7n\2\2\u0411"+ + "\u0106\3\2\2\2\u0412\u0413\5\u0109\u0085\2\u0413\u0108\3\2\2\2\u0414\u0418"+ + "\5\u010b\u0086\2\u0415\u0418\5\u010d\u0087\2\u0416\u0418\5\u010f\u0088"+ + "\2\u0417\u0414\3\2\2\2\u0417\u0415\3\2\2\2\u0417\u0416\3\2\2\2\u0418\u010a"+ + "\3\2\2\2\u0419\u041a\5\u0111\u0089\2\u041a\u010c\3\2\2\2\u041b\u041c\7"+ + "\60\2\2\u041c\u0426\5\u0111\u0089\2\u041d\u041e\5\u0111\u0089\2\u041e"+ + "\u0422\7\60\2\2\u041f\u0421\t\5\2\2\u0420\u041f\3\2\2\2\u0421\u0424\3"+ + "\2\2\2\u0422\u0420\3\2\2\2\u0422\u0423\3\2\2\2\u0423\u0426\3\2\2\2\u0424"+ + "\u0422\3\2\2\2\u0425\u041b\3\2\2\2\u0425\u041d\3\2\2\2\u0426\u010e\3\2"+ + "\2\2\u0427\u0428\7\60\2\2\u0428\u0434\5\u0111\u0089\2\u0429\u0431\5\u0111"+ + "\u0089\2\u042a\u042e\7\60\2\2\u042b\u042d\t\5\2\2\u042c\u042b\3\2\2\2"+ + "\u042d\u0430\3\2\2\2\u042e\u042c\3\2\2\2\u042e\u042f\3\2\2\2\u042f\u0432"+ + "\3\2\2\2\u0430\u042e\3\2\2\2\u0431\u042a\3\2\2\2\u0431\u0432\3\2\2\2\u0432"+ + "\u0434\3\2\2\2\u0433\u0427\3\2\2\2\u0433\u0429\3\2\2\2\u0434\u0435\3\2"+ + "\2\2\u0435\u0437\t\6\2\2\u0436\u0438\t\7\2\2\u0437\u0436\3\2\2\2\u0437"+ + "\u0438\3\2\2\2\u0438\u0439\3\2\2\2\u0439\u043a\5\u0111\u0089\2\u043a\u0110"+ + "\3\2\2\2\u043b\u043d\t\5\2\2\u043c\u043b\3\2\2\2\u043d\u043e\3\2\2\2\u043e"+ + "\u043c\3\2\2\2\u043e\u043f\3\2\2\2\u043f\u0112\3\2\2\2\u0440\u0441\t\b"+ + "\2\2\u0441\u0442\3\2\2\2\u0442\u0443\b\u008a\2\2\u0443\u0114\3\2\2\2\u0444"+ + "\u0448\5\u0117\u008c\2\u0445\u0447\5\u0119\u008d\2\u0446\u0445\3\2\2\2"+ + "\u0447\u044a\3\2\2\2\u0448\u0446\3\2\2\2\u0448\u0449\3\2\2\2\u0449\u0116"+ + "\3\2\2\2\u044a\u0448\3\2\2\2\u044b\u044d\t\t\2\2\u044c\u044b\3\2\2\2\u044d"+ + "\u0118\3\2\2\2\u044e\u0451\5\u0117\u008c\2\u044f\u0451\t\n\2\2\u0450\u044e"+ + "\3\2\2\2\u0450\u044f\3\2\2\2\u0451\u011a\3\2\2\2\u0452\u0453\7*\2\2\u0453"+ + "\u045c\7<\2\2\u0454\u045b\5\u011b\u008e\2\u0455\u0456\7*\2\2\u0456\u045b"+ + "\n\13\2\2\u0457\u0458\7<\2\2\u0458\u045b\n\f\2\2\u0459\u045b\n\r\2\2\u045a"+ + "\u0454\3\2\2\2\u045a\u0455\3\2\2\2\u045a\u0457\3\2\2\2\u045a\u0459\3\2"+ + "\2\2\u045b\u045e\3\2\2\2\u045c\u045a\3\2\2\2\u045c\u045d\3\2\2\2\u045d"+ + "\u0460\3\2\2\2\u045e\u045c\3\2\2\2\u045f\u0461\7<\2\2\u0460\u045f\3\2"+ + "\2\2\u0461\u0462\3\2\2\2\u0462\u0460\3\2\2\2\u0462\u0463\3\2\2\2\u0463"+ + "\u0464\3\2\2\2\u0464\u0465\7+\2\2\u0465\u0466\3\2\2\2\u0466\u0467\b\u008e"+ + "\2\2\u0467\u011c\3\2\2\2\u0468\u0469\n\16\2\2\u0469\u011e\3\2\2\2\24\2"+ + "\u03f7\u03f9\u0401\u0417\u0422\u0425\u042e\u0431\u0433\u0437\u043e\u0448"+ + "\u044c\u0450\u045a\u045c\u0462\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 665fe05255..695f08ba0e 100644 --- a/src/main/java/org/rumbledb/parser/JsoniqLexer.tokens +++ b/src/main/java/org/rumbledb/parser/JsoniqLexer.tokens @@ -58,71 +58,82 @@ T__56=57 T__57=58 T__58=59 T__59=60 -T__60=61 -Kfor=62 -Klet=63 -Kwhere=64 -Kgroup=65 -Kby=66 -Korder=67 -Kreturn=68 -Kif=69 -Kin=70 -Kas=71 -Kat=72 -Kallowing=73 -Kempty=74 -Kcount=75 -Kstable=76 -Kascending=77 -Kdescending=78 -Ksome=79 -Kevery=80 -Ksatisfies=81 -Kcollation=82 -Kgreatest=83 -Kleast=84 -Kswitch=85 -Kcase=86 -Ktry=87 -Kcatch=88 -Kdefault=89 -Kthen=90 -Kelse=91 -Ktypeswitch=92 -Kor=93 -Kand=94 -Knot=95 -Kto=96 -Kinstance=97 -Kof=98 -Kstatically=99 -Kis=100 -Ktreat=101 -Kcast=102 -Kcastable=103 -Kversion=104 -Kjsoniq=105 -Kunordered=106 -Ktrue=107 -Kfalse=108 -Ktype=109 -Kdeclare=110 -Kcontext=111 -Kitem=112 -Kvariable=113 -STRING=114 -ArgumentPlaceholder=115 -NullLiteral=116 -Literal=117 -NumericLiteral=118 -IntegerLiteral=119 -DecimalLiteral=120 -DoubleLiteral=121 -WS=122 -NCName=123 -XQComment=124 -ContentChar=125 +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 +Kunordered=105 +Ktrue=106 +Kfalse=107 +Ktype=108 +Kdeclare=109 +Kcontext=110 +Kitem=111 +Kvariable=112 +Kinsert=113 +Kdelete=114 +Krename=115 +Kreplace=116 +Kcopy=117 +Kmodify=118 +Kappend=119 +Kinto=120 +Kvalue=121 +Kjson=122 +Kwith=123 +Kposition=124 +STRING=125 +ArgumentPlaceholder=126 +NullLiteral=127 +Literal=128 +NumericLiteral=129 +IntegerLiteral=130 +DecimalLiteral=131 +DoubleLiteral=132 +WS=133 +NCName=134 +XQComment=135 +ContentChar=136 ';'=1 'module'=2 'namespace'=3 @@ -153,88 +164,99 @@ ContentChar=125 'jsound'=28 'compact'=29 'verbose'=30 -'json'=31 -'schema'=32 -'$'=33 -'|'=34 -'*'=35 -'eq'=36 -'ne'=37 -'lt'=38 -'le'=39 -'gt'=40 -'ge'=41 -'!='=42 -'<'=43 -'<='=44 -'>'=45 -'>='=46 -'||'=47 -'+'=48 -'-'=49 -'div'=50 -'idiv'=51 -'mod'=52 -'validate'=53 -'!'=54 -'['=55 -']'=56 -'.'=57 -'$$'=58 -'#'=59 -'{|'=60 -'|}'=61 -'for'=62 -'let'=63 -'where'=64 -'group'=65 -'by'=66 -'order'=67 -'return'=68 -'if'=69 -'in'=70 -'as'=71 -'at'=72 -'allowing'=73 -'empty'=74 -'count'=75 -'stable'=76 -'ascending'=77 -'descending'=78 -'some'=79 -'every'=80 -'satisfies'=81 -'collation'=82 -'greatest'=83 -'least'=84 -'switch'=85 -'case'=86 -'try'=87 -'catch'=88 -'default'=89 -'then'=90 -'else'=91 -'typeswitch'=92 -'or'=93 -'and'=94 -'not'=95 -'to'=96 -'instance'=97 -'of'=98 -'statically'=99 -'is'=100 -'treat'=101 -'cast'=102 -'castable'=103 -'version'=104 -'jsoniq'=105 -'unordered'=106 -'true'=107 -'false'=108 -'type'=109 -'declare'=110 -'context'=111 -'item'=112 -'variable'=113 -'?'=115 -'null'=116 +'schema'=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 +'unordered'=105 +'true'=106 +'false'=107 +'type'=108 +'declare'=109 +'context'=110 +'item'=111 +'variable'=112 +'insert'=113 +'delete'=114 +'rename'=115 +'replace'=116 +'copy'=117 +'modify'=118 +'append'=119 +'into'=120 +'value'=121 +'json'=122 +'with'=123 +'position'=124 +'?'=126 +'null'=127 diff --git a/src/main/java/org/rumbledb/parser/JsoniqParser.java b/src/main/java/org/rumbledb/parser/JsoniqParser.java index 18b06b8c1e..48078c179b 100644 --- a/src/main/java/org/rumbledb/parser/JsoniqParser.java +++ b/src/main/java/org/rumbledb/parser/JsoniqParser.java @@ -1,31 +1,20 @@ -// Generated from ./src/main/java/org/rumbledb/parser/Jsoniq.g4 by ANTLR 4.8 +// Generated from ./src/main/java/org/rumbledb/parser/Jsoniq.g4 by ANTLR 4.7 // 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 { - static { RuntimeMetaData.checkVersion("4.8", RuntimeMetaData.VERSION); } + static { RuntimeMetaData.checkVersion("4.7", RuntimeMetaData.VERSION); } protected static final DFA[] _decisionToDFA; protected static final PredictionContextCache _sharedContextCache = @@ -39,17 +28,19 @@ 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, T__60=61, Kfor=62, Klet=63, Kwhere=64, Kgroup=65, Kby=66, Korder=67, - Kreturn=68, Kif=69, Kin=70, Kas=71, Kat=72, Kallowing=73, Kempty=74, Kcount=75, - Kstable=76, Kascending=77, Kdescending=78, Ksome=79, Kevery=80, Ksatisfies=81, - Kcollation=82, Kgreatest=83, Kleast=84, Kswitch=85, Kcase=86, Ktry=87, - Kcatch=88, Kdefault=89, Kthen=90, Kelse=91, Ktypeswitch=92, Kor=93, Kand=94, - Knot=95, Kto=96, Kinstance=97, Kof=98, Kstatically=99, Kis=100, Ktreat=101, - Kcast=102, Kcastable=103, Kversion=104, Kjsoniq=105, Kunordered=106, Ktrue=107, - Kfalse=108, Ktype=109, Kdeclare=110, Kcontext=111, Kitem=112, Kvariable=113, - STRING=114, ArgumentPlaceholder=115, NullLiteral=116, Literal=117, NumericLiteral=118, - IntegerLiteral=119, DecimalLiteral=120, DoubleLiteral=121, WS=122, NCName=123, - XQComment=124, ContentChar=125; + 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, Kunordered=105, Ktrue=106, Kfalse=107, Ktype=108, + Kdeclare=109, Kcontext=110, Kitem=111, Kvariable=112, Kinsert=113, Kdelete=114, + Krename=115, Kreplace=116, Kcopy=117, Kmodify=118, Kappend=119, Kinto=120, + Kvalue=121, Kjson=122, Kwith=123, Kposition=124, STRING=125, ArgumentPlaceholder=126, + NullLiteral=127, Literal=128, NumericLiteral=129, IntegerLiteral=130, + DecimalLiteral=131, DoubleLiteral=132, WS=133, NCName=134, XQComment=135, + ContentChar=136; 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, @@ -74,78 +65,77 @@ public class JsoniqParser extends Parser { RULE_parenthesizedExpr = 70, RULE_contextItemExpr = 71, RULE_orderedExpr = 72, RULE_unorderedExpr = 73, RULE_functionCall = 74, RULE_argumentList = 75, RULE_argument = 76, RULE_functionItemExpr = 77, RULE_namedFunctionRef = 78, - RULE_inlineFunctionExpr = 79, RULE_sequenceType = 80, RULE_objectConstructor = 81, - RULE_itemType = 82, RULE_functionTest = 83, RULE_anyFunctionTest = 84, - RULE_typedFunctionTest = 85, RULE_singleType = 86, RULE_pairConstructor = 87, - RULE_arrayConstructor = 88, RULE_uriLiteral = 89, RULE_stringLiteral = 90, - RULE_keyWords = 91; - private static String[] makeRuleNames() { - return new String[] { - "moduleAndThisIsIt", "module", "mainModule", "libraryModule", "prolog", - "setter", "namespaceDecl", "annotatedDecl", "defaultCollationDecl", "orderingModeDecl", - "emptyOrderDecl", "decimalFormatDecl", "qname", "dfPropertyName", "moduleImport", - "varDecl", "contextItemDecl", "functionDecl", "typeDecl", "schemaLanguage", - "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", "arrowFunctionSpecifier", "unaryExpr", "valueExpr", "validateExpr", - "simpleMapExpr", "postFixExpr", "arrayLookup", "arrayUnboxing", "predicate", - "objectLookup", "primaryExpr", "varRef", "parenthesizedExpr", "contextItemExpr", - "orderedExpr", "unorderedExpr", "functionCall", "argumentList", "argument", - "functionItemExpr", "namedFunctionRef", "inlineFunctionExpr", "sequenceType", - "objectConstructor", "itemType", "functionTest", "anyFunctionTest", "typedFunctionTest", - "singleType", "pairConstructor", "arrayConstructor", "uriLiteral", "stringLiteral", - "keyWords" - }; - } - public static final String[] ruleNames = makeRuleNames(); - - private static String[] makeLiteralNames() { - return new String[] { - null, "';'", "'module'", "'namespace'", "'='", "'ordering'", "'ordered'", - "'decimal-format'", "':'", "'decimal-separator'", "'grouping-separator'", - "'infinity'", "'minus-sign'", "'NaN'", "'percent'", "'per-mille'", "'zero-digit'", - "'digit'", "'pattern-separator'", "'import'", "','", "':='", "'external'", - "'function'", "'('", "')'", "'{'", "'}'", "'jsound'", "'compact'", "'verbose'", - "'json'", "'schema'", "'$'", "'|'", "'*'", "'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'", - "'true'", "'false'", "'type'", "'declare'", "'context'", "'item'", "'variable'", - null, "'?'", "'null'" - }; - } - private static final String[] _LITERAL_NAMES = makeLiteralNames(); - private static String[] makeSymbolicNames() { - return new String[] { - 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, 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", "Ktrue", "Kfalse", "Ktype", "Kdeclare", "Kcontext", - "Kitem", "Kvariable", "STRING", "ArgumentPlaceholder", "NullLiteral", - "Literal", "NumericLiteral", "IntegerLiteral", "DecimalLiteral", "DoubleLiteral", - "WS", "NCName", "XQComment", "ContentChar" - }; - } - private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + RULE_inlineFunctionExpr = 79, RULE_insertExpr = 80, RULE_deleteExpr = 81, + RULE_renameExpr = 82, RULE_replaceExpr = 83, RULE_transformExpr = 84, + RULE_appendExpr = 85, RULE_updateLocator = 86, RULE_copyDecl = 87, RULE_sequenceType = 88, + RULE_objectConstructor = 89, RULE_itemType = 90, RULE_functionTest = 91, + RULE_anyFunctionTest = 92, RULE_typedFunctionTest = 93, RULE_singleType = 94, + RULE_pairConstructor = 95, RULE_arrayConstructor = 96, RULE_uriLiteral = 97, + RULE_stringLiteral = 98, RULE_keyWords = 99; + public static final String[] ruleNames = { + "moduleAndThisIsIt", "module", "mainModule", "libraryModule", "prolog", + "setter", "namespaceDecl", "annotatedDecl", "defaultCollationDecl", "orderingModeDecl", + "emptyOrderDecl", "decimalFormatDecl", "qname", "dfPropertyName", "moduleImport", + "varDecl", "contextItemDecl", "functionDecl", "typeDecl", "schemaLanguage", + "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", "arrowFunctionSpecifier", "unaryExpr", "valueExpr", "validateExpr", + "simpleMapExpr", "postFixExpr", "arrayLookup", "arrayUnboxing", "predicate", + "objectLookup", "primaryExpr", "varRef", "parenthesizedExpr", "contextItemExpr", + "orderedExpr", "unorderedExpr", "functionCall", "argumentList", "argument", + "functionItemExpr", "namedFunctionRef", "inlineFunctionExpr", "insertExpr", + "deleteExpr", "renameExpr", "replaceExpr", "transformExpr", "appendExpr", + "updateLocator", "copyDecl", "sequenceType", "objectConstructor", "itemType", + "functionTest", "anyFunctionTest", "typedFunctionTest", "singleType", + "pairConstructor", "arrayConstructor", "uriLiteral", "stringLiteral", + "keyWords" + }; + + private static final String[] _LITERAL_NAMES = { + null, "';'", "'module'", "'namespace'", "'='", "'ordering'", "'ordered'", + "'decimal-format'", "':'", "'decimal-separator'", "'grouping-separator'", + "'infinity'", "'minus-sign'", "'NaN'", "'percent'", "'per-mille'", "'zero-digit'", + "'digit'", "'pattern-separator'", "'import'", "','", "':='", "'external'", + "'function'", "'('", "')'", "'{'", "'}'", "'jsound'", "'compact'", "'verbose'", + "'schema'", "'$'", "'|'", "'*'", "'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'", "'true'", + "'false'", "'type'", "'declare'", "'context'", "'item'", "'variable'", + "'insert'", "'delete'", "'rename'", "'replace'", "'copy'", "'modify'", + "'append'", "'into'", "'value'", "'json'", "'with'", "'position'", null, + "'?'", "'null'" + }; + private static final String[] _SYMBOLIC_NAMES = { + 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, 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", "Ktrue", "Kfalse", "Ktype", "Kdeclare", "Kcontext", + "Kitem", "Kvariable", "Kinsert", "Kdelete", "Krename", "Kreplace", "Kcopy", + "Kmodify", "Kappend", "Kinto", "Kvalue", "Kjson", "Kwith", "Kposition", + "STRING", "ArgumentPlaceholder", "NullLiteral", "Literal", "NumericLiteral", + "IntegerLiteral", "DecimalLiteral", "DoubleLiteral", "WS", "NCName", "XQComment", + "ContentChar" + }; public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES); /** @@ -195,7 +185,6 @@ public JsoniqParser(TokenStream input) { super(input); _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); } - public static class ModuleAndThisIsItContext extends ParserRuleContext { public ModuleContext module() { return getRuleContext(ModuleContext.class,0); @@ -218,9 +207,9 @@ public final ModuleAndThisIsItContext moduleAndThisIsIt() throws RecognitionExce try { enterOuterAlt(_localctx, 1); { - setState(184); + setState(200); module(); - setState(185); + setState(201); match(EOF); } } @@ -266,28 +255,28 @@ public final ModuleContext module() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(192); + setState(208); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,0,_ctx) ) { case 1: { - setState(187); + setState(203); match(Kjsoniq); - setState(188); + setState(204); match(Kversion); - setState(189); + setState(205); ((ModuleContext)_localctx).vers = stringLiteral(); - setState(190); + setState(206); match(T__0); } break; } - setState(196); + setState(212); _errHandler.sync(this); switch (_input.LA(1)) { case T__1: { - setState(194); + setState(210); libraryModule(); } break; @@ -296,13 +285,13 @@ public final ModuleContext module() throws RecognitionException { case T__22: case T__23: case T__25: - case T__32: + case T__31: + case T__46: case T__47: - case T__48: - case T__52: - case T__54: - case T__57: - case T__59: + case T__51: + case T__53: + case T__56: + case T__58: case Kfor: case Klet: case Kwhere: @@ -355,12 +344,24 @@ public final ModuleContext module() throws RecognitionException { case Kcontext: case Kitem: case Kvariable: + case Kinsert: + case Kdelete: + case Krename: + case Kreplace: + case Kcopy: + case Kmodify: + case Kappend: + case Kinto: + case Kvalue: + case Kjson: + case Kwith: + case Kposition: case STRING: case NullLiteral: case Literal: case NCName: { - setState(195); + setState(211); ((ModuleContext)_localctx).main = mainModule(); } break; @@ -404,9 +405,9 @@ public final MainModuleContext mainModule() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(198); + setState(214); prolog(); - setState(199); + setState(215); expr(); } } @@ -446,19 +447,19 @@ public final LibraryModuleContext libraryModule() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(201); + setState(217); match(T__1); - setState(202); + setState(218); match(T__2); - setState(203); + setState(219); match(NCName); - setState(204); + setState(220); match(T__3); - setState(205); + setState(221); uriLiteral(); - setState(206); + setState(222); match(T__0); - setState(207); + setState(223); prolog(); } } @@ -516,59 +517,59 @@ public final PrologContext prolog() throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(218); + setState(234); _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(212); + setState(228); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,2,_ctx) ) { case 1: { - setState(209); + setState(225); setter(); } break; case 2: { - setState(210); + setState(226); namespaceDecl(); } break; case 3: { - setState(211); + setState(227); moduleImport(); } break; } - setState(214); + setState(230); match(T__0); } } } - setState(220); + setState(236); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,3,_ctx); } - setState(226); + setState(242); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,4,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(221); + setState(237); annotatedDecl(); - setState(222); + setState(238); match(T__0); } } } - setState(228); + setState(244); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,4,_ctx); } @@ -613,34 +614,34 @@ public final SetterContext setter() throws RecognitionException { SetterContext _localctx = new SetterContext(_ctx, getState()); enterRule(_localctx, 10, RULE_setter); try { - setState(233); + setState(249); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,5,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(229); + setState(245); defaultCollationDecl(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(230); + setState(246); orderingModeDecl(); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(231); + setState(247); emptyOrderDecl(); } break; case 4: enterOuterAlt(_localctx, 4); { - setState(232); + setState(248); decimalFormatDecl(); } break; @@ -680,15 +681,15 @@ public final NamespaceDeclContext namespaceDecl() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(235); + setState(251); match(Kdeclare); - setState(236); + setState(252); match(T__2); - setState(237); + setState(253); match(NCName); - setState(238); + setState(254); match(T__3); - setState(239); + setState(255); uriLiteral(); } } @@ -731,34 +732,34 @@ public final AnnotatedDeclContext annotatedDecl() throws RecognitionException { AnnotatedDeclContext _localctx = new AnnotatedDeclContext(_ctx, getState()); enterRule(_localctx, 14, RULE_annotatedDecl); try { - setState(245); + setState(261); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,6,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(241); + setState(257); functionDecl(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(242); + setState(258); varDecl(); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(243); + setState(259); typeDecl(); } break; case 4: enterOuterAlt(_localctx, 4); { - setState(244); + setState(260); contextItemDecl(); } break; @@ -799,13 +800,13 @@ public final DefaultCollationDeclContext defaultCollationDecl() throws Recogniti try { enterOuterAlt(_localctx, 1); { - setState(247); + setState(263); match(Kdeclare); - setState(248); + setState(264); match(Kdefault); - setState(249); + setState(265); match(Kcollation); - setState(250); + setState(266); uriLiteral(); } } @@ -822,7 +823,6 @@ public final DefaultCollationDeclContext defaultCollationDecl() throws Recogniti public static class OrderingModeDeclContext extends ParserRuleContext { public TerminalNode Kdeclare() { return getToken(JsoniqParser.Kdeclare, 0); } - public TerminalNode Kunordered() { return getToken(JsoniqParser.Kunordered, 0); } public OrderingModeDeclContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); } @@ -841,11 +841,11 @@ public final OrderingModeDeclContext orderingModeDecl() throws RecognitionExcept try { enterOuterAlt(_localctx, 1); { - setState(252); + setState(268); match(Kdeclare); - setState(253); + setState(269); match(T__4); - setState(254); + setState(270); _la = _input.LA(1); if ( !(_la==T__5 || _la==Kunordered) ) { _errHandler.recoverInline(this); @@ -872,7 +872,6 @@ public static class EmptyOrderDeclContext extends ParserRuleContext { public Token emptySequenceOrder; public TerminalNode Kdeclare() { return getToken(JsoniqParser.Kdeclare, 0); } public TerminalNode Kdefault() { return getToken(JsoniqParser.Kdefault, 0); } - public TerminalNode Korder() { return getToken(JsoniqParser.Korder, 0); } public TerminalNode Kempty() { return getToken(JsoniqParser.Kempty, 0); } public TerminalNode Kgreatest() { return getToken(JsoniqParser.Kgreatest, 0); } public TerminalNode Kleast() { return getToken(JsoniqParser.Kleast, 0); } @@ -894,16 +893,16 @@ public final EmptyOrderDeclContext emptyOrderDecl() throws RecognitionException try { enterOuterAlt(_localctx, 1); { - setState(256); + setState(272); match(Kdeclare); - setState(257); + setState(273); match(Kdefault); - setState(258); + setState(274); match(Korder); - setState(259); + setState(275); match(Kempty); { - setState(260); + setState(276); ((EmptyOrderDeclContext)_localctx).emptySequenceOrder = _input.LT(1); _la = _input.LA(1); if ( !(_la==Kgreatest || _la==Kleast) ) { @@ -964,17 +963,17 @@ public final DecimalFormatDeclContext decimalFormatDecl() throws RecognitionExce try { enterOuterAlt(_localctx, 1); { - setState(262); + setState(278); match(Kdeclare); - setState(267); + setState(283); _errHandler.sync(this); switch (_input.LA(1)) { case T__6: { { - setState(263); + setState(279); match(T__6); - setState(264); + setState(280); qname(); } } @@ -982,9 +981,9 @@ public final DecimalFormatDeclContext decimalFormatDecl() throws RecognitionExce case Kdefault: { { - setState(265); + setState(281); match(Kdefault); - setState(266); + setState(282); match(T__6); } } @@ -992,21 +991,21 @@ public final DecimalFormatDeclContext decimalFormatDecl() throws RecognitionExce default: throw new NoViableAltException(this); } - setState(275); + setState(291); _errHandler.sync(this); _la = _input.LA(1); while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__8) | (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))) != 0)) { { { - setState(269); + setState(285); dfPropertyName(); - setState(270); + setState(286); match(T__3); - setState(271); + setState(287); stringLiteral(); } } - setState(277); + setState(293); _errHandler.sync(this); _la = _input.LA(1); } @@ -1055,17 +1054,17 @@ public final QnameContext qname() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(283); + setState(299); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,10,_ctx) ) { case 1: { - setState(280); + setState(296); _errHandler.sync(this); switch (_input.LA(1)) { case NCName: { - setState(278); + setState(294); ((QnameContext)_localctx).ns = match(NCName); } break; @@ -1121,26 +1120,38 @@ public final QnameContext qname() throws RecognitionException { case Kcontext: case Kitem: case Kvariable: + case Kinsert: + case Kdelete: + case Krename: + case Kreplace: + case Kcopy: + case Kmodify: + case Kappend: + case Kinto: + case Kvalue: + case Kjson: + case Kwith: + case Kposition: case NullLiteral: { - setState(279); + setState(295); ((QnameContext)_localctx).nskw = keyWords(); } break; default: throw new NoViableAltException(this); } - setState(282); + setState(298); match(T__7); } break; } - setState(287); + setState(303); _errHandler.sync(this); switch (_input.LA(1)) { case NCName: { - setState(285); + setState(301); ((QnameContext)_localctx).local_name = match(NCName); } break; @@ -1196,9 +1207,21 @@ public final QnameContext qname() throws RecognitionException { case Kcontext: case Kitem: case Kvariable: + case Kinsert: + case Kdelete: + case Krename: + case Kreplace: + case Kcopy: + case Kmodify: + case Kappend: + case Kinto: + case Kvalue: + case Kjson: + case Kwith: + case Kposition: case NullLiteral: { - setState(286); + setState(302); ((QnameContext)_localctx).local_namekw = keyWords(); } break; @@ -1237,7 +1260,7 @@ public final DfPropertyNameContext dfPropertyName() throws RecognitionException try { enterOuterAlt(_localctx, 1); { - setState(289); + setState(305); _la = _input.LA(1); if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__8) | (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))) != 0)) ) { _errHandler.recoverInline(this); @@ -1289,48 +1312,48 @@ public final ModuleImportContext moduleImport() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(291); + setState(307); match(T__18); - setState(292); + setState(308); match(T__1); - setState(296); + setState(312); _errHandler.sync(this); _la = _input.LA(1); if (_la==T__2) { { - setState(293); + setState(309); match(T__2); - setState(294); + setState(310); ((ModuleImportContext)_localctx).prefix = match(NCName); - setState(295); + setState(311); match(T__3); } } - setState(298); + setState(314); ((ModuleImportContext)_localctx).targetNamespace = uriLiteral(); - setState(308); + setState(324); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kat) { { - setState(299); + setState(315); match(Kat); - setState(300); + setState(316); uriLiteral(); - setState(305); + setState(321); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__19) { { { - setState(301); + setState(317); match(T__19); - setState(302); + setState(318); uriLiteral(); } } - setState(307); + setState(323); _errHandler.sync(this); _la = _input.LA(1); } @@ -1382,33 +1405,33 @@ public final VarDeclContext varDecl() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(310); + setState(326); match(Kdeclare); - setState(311); + setState(327); match(Kvariable); - setState(312); + setState(328); varRef(); - setState(315); + setState(331); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kas) { { - setState(313); + setState(329); match(Kas); - setState(314); + setState(330); sequenceType(); } } - setState(324); + setState(340); _errHandler.sync(this); switch (_input.LA(1)) { case T__20: { { - setState(317); + setState(333); match(T__20); - setState(318); + setState(334); exprSingle(); } } @@ -1416,16 +1439,16 @@ public final VarDeclContext varDecl() throws RecognitionException { case T__21: { { - setState(319); + setState(335); ((VarDeclContext)_localctx).external = match(T__21); - setState(322); + setState(338); _errHandler.sync(this); _la = _input.LA(1); if (_la==T__20) { { - setState(320); + setState(336); match(T__20); - setState(321); + setState(337); exprSingle(); } } @@ -1479,33 +1502,33 @@ public final ContextItemDeclContext contextItemDecl() throws RecognitionExceptio try { enterOuterAlt(_localctx, 1); { - setState(326); + setState(342); match(Kdeclare); - setState(327); + setState(343); match(Kcontext); - setState(328); + setState(344); match(Kitem); - setState(331); + setState(347); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kas) { { - setState(329); + setState(345); match(Kas); - setState(330); + setState(346); sequenceType(); } } - setState(340); + setState(356); _errHandler.sync(this); switch (_input.LA(1)) { case T__20: { { - setState(333); + setState(349); match(T__20); - setState(334); + setState(350); exprSingle(); } } @@ -1513,16 +1536,16 @@ public final ContextItemDeclContext contextItemDecl() throws RecognitionExceptio case T__21: { { - setState(335); + setState(351); ((ContextItemDeclContext)_localctx).external = match(T__21); - setState(338); + setState(354); _errHandler.sync(this); _la = _input.LA(1); if (_la==T__20) { { - setState(336); + setState(352); match(T__20); - setState(337); + setState(353); exprSingle(); } } @@ -1582,62 +1605,62 @@ public final FunctionDeclContext functionDecl() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(342); + setState(358); match(Kdeclare); - setState(343); + setState(359); match(T__22); - setState(344); + setState(360); ((FunctionDeclContext)_localctx).fn_name = qname(); - setState(345); + setState(361); match(T__23); - setState(347); + setState(363); _errHandler.sync(this); _la = _input.LA(1); - if (_la==T__32) { + if (_la==T__31) { { - setState(346); + setState(362); paramList(); } } - setState(349); + setState(365); match(T__24); - setState(352); + setState(368); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kas) { { - setState(350); + setState(366); match(Kas); - setState(351); + setState(367); ((FunctionDeclContext)_localctx).return_type = sequenceType(); } } - setState(360); + setState(376); _errHandler.sync(this); switch (_input.LA(1)) { case T__25: { - setState(354); + setState(370); match(T__25); - setState(356); + setState(372); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__5) | (1L << T__22) | (1L << T__23) | (1L << T__25) | (1L << T__32) | (1L << T__47) | (1L << T__48) | (1L << T__52) | (1L << T__54) | (1L << T__57) | (1L << T__59) | (1L << Kfor) | (1L << Klet))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kwhere - 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 << (Kunordered - 64)) | (1L << (Ktrue - 64)) | (1L << (Kfalse - 64)) | (1L << (Ktype - 64)) | (1L << (Kdeclare - 64)) | (1L << (Kcontext - 64)) | (1L << (Kitem - 64)) | (1L << (Kvariable - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__5) | (1L << T__22) | (1L << T__23) | (1L << T__25) | (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 << (Kunordered - 64)) | (1L << (Ktrue - 64)) | (1L << (Kfalse - 64)) | (1L << (Ktype - 64)) | (1L << (Kdeclare - 64)) | (1L << (Kcontext - 64)) | (1L << (Kitem - 64)) | (1L << (Kvariable - 64)) | (1L << (Kinsert - 64)) | (1L << (Kdelete - 64)) | (1L << (Krename - 64)) | (1L << (Kreplace - 64)) | (1L << (Kcopy - 64)) | (1L << (Kmodify - 64)) | (1L << (Kappend - 64)) | (1L << (Kinto - 64)) | (1L << (Kvalue - 64)) | (1L << (Kjson - 64)) | (1L << (Kwith - 64)) | (1L << (Kposition - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)))) != 0) || _la==Literal || _la==NCName) { { - setState(355); + setState(371); ((FunctionDeclContext)_localctx).fn_body = expr(); } } - setState(358); + setState(374); match(T__26); } break; case T__21: { - setState(359); + setState(375); match(T__21); } break; @@ -1663,7 +1686,6 @@ public static class TypeDeclContext extends ParserRuleContext { public ExprSingleContext type_definition; public TerminalNode Kdeclare() { return getToken(JsoniqParser.Kdeclare, 0); } public TerminalNode Ktype() { return getToken(JsoniqParser.Ktype, 0); } - public TerminalNode Kas() { return getToken(JsoniqParser.Kas, 0); } public QnameContext qname() { return getRuleContext(QnameContext.class,0); } @@ -1687,29 +1709,28 @@ public T accept(ParseTreeVisitor visitor) { public final TypeDeclContext typeDecl() throws RecognitionException { TypeDeclContext _localctx = new TypeDeclContext(_ctx, getState()); enterRule(_localctx, 36, RULE_typeDecl); - int _la; try { enterOuterAlt(_localctx, 1); { - setState(362); + setState(378); match(Kdeclare); - setState(363); + setState(379); match(Ktype); - setState(364); + setState(380); ((TypeDeclContext)_localctx).type_name = qname(); - setState(365); + setState(381); match(Kas); - setState(367); + setState(383); _errHandler.sync(this); - _la = _input.LA(1); - if (_la==T__27 || _la==T__30) { + switch ( getInterpreter().adaptivePredict(_input,25,_ctx) ) { + case 1: { - setState(366); + setState(382); ((TypeDeclContext)_localctx).schema = schemaLanguage(); } + break; } - - setState(369); + setState(385); ((TypeDeclContext)_localctx).type_definition = exprSingle(); } } @@ -1740,34 +1761,34 @@ public final SchemaLanguageContext schemaLanguage() throws RecognitionException SchemaLanguageContext _localctx = new SchemaLanguageContext(_ctx, getState()); enterRule(_localctx, 38, RULE_schemaLanguage); try { - setState(377); + setState(393); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,26,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(371); + setState(387); match(T__27); - setState(372); + setState(388); match(T__28); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(373); + setState(389); match(T__27); - setState(374); + setState(390); match(T__29); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(375); + setState(391); + match(Kjson); + setState(392); match(T__30); - setState(376); - match(T__31); } break; } @@ -1808,21 +1829,21 @@ public final ParamListContext paramList() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(379); + setState(395); param(); - setState(384); + setState(400); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__19) { { { - setState(380); + setState(396); match(T__19); - setState(381); + setState(397); param(); } } - setState(386); + setState(402); _errHandler.sync(this); _la = _input.LA(1); } @@ -1865,18 +1886,18 @@ public final ParamContext param() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(387); - match(T__32); - setState(388); + setState(403); + match(T__31); + setState(404); qname(); - setState(391); + setState(407); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kas) { { - setState(389); + setState(405); match(Kas); - setState(390); + setState(406); sequenceType(); } } @@ -1919,21 +1940,21 @@ public final ExprContext expr() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(393); + setState(409); exprSingle(); - setState(398); + setState(414); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__19) { { { - setState(394); + setState(410); match(T__19); - setState(395); + setState(411); exprSingle(); } } - setState(400); + setState(416); _errHandler.sync(this); _la = _input.LA(1); } @@ -1969,6 +1990,24 @@ public IfExprContext ifExpr() { public TryCatchExprContext tryCatchExpr() { return getRuleContext(TryCatchExprContext.class,0); } + public InsertExprContext insertExpr() { + return getRuleContext(InsertExprContext.class,0); + } + public DeleteExprContext deleteExpr() { + return getRuleContext(DeleteExprContext.class,0); + } + public RenameExprContext renameExpr() { + return getRuleContext(RenameExprContext.class,0); + } + public ReplaceExprContext replaceExpr() { + return getRuleContext(ReplaceExprContext.class,0); + } + public TransformExprContext transformExpr() { + return getRuleContext(TransformExprContext.class,0); + } + public AppendExprContext appendExpr() { + return getRuleContext(AppendExprContext.class,0); + } public OrExprContext orExpr() { return getRuleContext(OrExprContext.class,0); } @@ -1987,55 +2026,97 @@ public final ExprSingleContext exprSingle() throws RecognitionException { ExprSingleContext _localctx = new ExprSingleContext(_ctx, getState()); enterRule(_localctx, 46, RULE_exprSingle); try { - setState(408); + setState(430); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,30,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(401); + setState(417); flowrExpr(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(402); + setState(418); quantifiedExpr(); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(403); + setState(419); switchExpr(); } break; case 4: enterOuterAlt(_localctx, 4); { - setState(404); + setState(420); typeSwitchExpr(); } break; case 5: enterOuterAlt(_localctx, 5); { - setState(405); + setState(421); ifExpr(); } break; case 6: enterOuterAlt(_localctx, 6); { - setState(406); + setState(422); tryCatchExpr(); } break; case 7: enterOuterAlt(_localctx, 7); { - setState(407); + setState(423); + insertExpr(); + } + break; + case 8: + enterOuterAlt(_localctx, 8); + { + setState(424); + deleteExpr(); + } + break; + case 9: + enterOuterAlt(_localctx, 9); + { + setState(425); + renameExpr(); + } + break; + case 10: + enterOuterAlt(_localctx, 10); + { + setState(426); + replaceExpr(); + } + break; + case 11: + enterOuterAlt(_localctx, 11); + { + setState(427); + transformExpr(); + } + break; + case 12: + enterOuterAlt(_localctx, 12); + { + setState(428); + appendExpr(); + } + break; + case 13: + enterOuterAlt(_localctx, 13); + { + setState(429); orExpr(); } break; @@ -2114,66 +2195,66 @@ public final FlowrExprContext flowrExpr() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(412); + setState(434); _errHandler.sync(this); switch (_input.LA(1)) { case Kfor: { - setState(410); + setState(432); ((FlowrExprContext)_localctx).start_for = forClause(); } break; case Klet: { - setState(411); + setState(433); ((FlowrExprContext)_localctx).start_let = letClause(); } break; default: throw new NoViableAltException(this); } - setState(422); + setState(444); _errHandler.sync(this); _la = _input.LA(1); - while (((((_la - 62)) & ~0x3f) == 0 && ((1L << (_la - 62)) & ((1L << (Kfor - 62)) | (1L << (Klet - 62)) | (1L << (Kwhere - 62)) | (1L << (Kgroup - 62)) | (1L << (Korder - 62)) | (1L << (Kcount - 62)) | (1L << (Kstable - 62)))) != 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(420); + setState(442); _errHandler.sync(this); switch (_input.LA(1)) { case Kfor: { - setState(414); + setState(436); forClause(); } break; case Kwhere: { - setState(415); + setState(437); whereClause(); } break; case Klet: { - setState(416); + setState(438); letClause(); } break; case Kgroup: { - setState(417); + setState(439); groupByClause(); } break; case Korder: case Kstable: { - setState(418); + setState(440); orderByClause(); } break; case Kcount: { - setState(419); + setState(441); countClause(); } break; @@ -2181,13 +2262,13 @@ public final FlowrExprContext flowrExpr() throws RecognitionException { throw new NoViableAltException(this); } } - setState(424); + setState(446); _errHandler.sync(this); _la = _input.LA(1); } - setState(425); + setState(447); match(Kreturn); - setState(426); + setState(448); ((FlowrExprContext)_localctx).return_expr = exprSingle(); } } @@ -2230,25 +2311,25 @@ public final ForClauseContext forClause() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(428); + setState(450); match(Kfor); - setState(429); + setState(451); ((ForClauseContext)_localctx).forVar = forVar(); ((ForClauseContext)_localctx).vars.add(((ForClauseContext)_localctx).forVar); - setState(434); + setState(456); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__19) { { { - setState(430); + setState(452); match(T__19); - setState(431); + setState(453); ((ForClauseContext)_localctx).forVar = forVar(); ((ForClauseContext)_localctx).vars.add(((ForClauseContext)_localctx).forVar); } } - setState(436); + setState(458); _errHandler.sync(this); _la = _input.LA(1); } @@ -2306,47 +2387,47 @@ public final ForVarContext forVar() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(437); + setState(459); ((ForVarContext)_localctx).var_ref = varRef(); - setState(440); + setState(462); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kas) { { - setState(438); + setState(460); match(Kas); - setState(439); + setState(461); ((ForVarContext)_localctx).seq = sequenceType(); } } - setState(444); + setState(466); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kallowing) { { - setState(442); + setState(464); ((ForVarContext)_localctx).flag = match(Kallowing); - setState(443); + setState(465); match(Kempty); } } - setState(448); + setState(470); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kat) { { - setState(446); + setState(468); match(Kat); - setState(447); + setState(469); ((ForVarContext)_localctx).at = varRef(); } } - setState(450); + setState(472); match(Kin); - setState(451); + setState(473); ((ForVarContext)_localctx).ex = exprSingle(); } } @@ -2389,25 +2470,25 @@ public final LetClauseContext letClause() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(453); + setState(475); match(Klet); - setState(454); + setState(476); ((LetClauseContext)_localctx).letVar = letVar(); ((LetClauseContext)_localctx).vars.add(((LetClauseContext)_localctx).letVar); - setState(459); + setState(481); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__19) { { { - setState(455); + setState(477); match(T__19); - setState(456); + setState(478); ((LetClauseContext)_localctx).letVar = letVar(); ((LetClauseContext)_localctx).vars.add(((LetClauseContext)_localctx).letVar); } } - setState(461); + setState(483); _errHandler.sync(this); _la = _input.LA(1); } @@ -2456,23 +2537,23 @@ public final LetVarContext letVar() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(462); + setState(484); ((LetVarContext)_localctx).var_ref = varRef(); - setState(465); + setState(487); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kas) { { - setState(463); + setState(485); match(Kas); - setState(464); + setState(486); ((LetVarContext)_localctx).seq = sequenceType(); } } - setState(467); + setState(489); match(T__20); - setState(468); + setState(490); ((LetVarContext)_localctx).ex = exprSingle(); } } @@ -2509,9 +2590,9 @@ public final WhereClauseContext whereClause() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(470); + setState(492); match(Kwhere); - setState(471); + setState(493); exprSingle(); } } @@ -2555,27 +2636,27 @@ public final GroupByClauseContext groupByClause() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(473); + setState(495); match(Kgroup); - setState(474); + setState(496); match(Kby); - setState(475); + setState(497); ((GroupByClauseContext)_localctx).groupByVar = groupByVar(); ((GroupByClauseContext)_localctx).vars.add(((GroupByClauseContext)_localctx).groupByVar); - setState(480); + setState(502); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__19) { { { - setState(476); + setState(498); match(T__19); - setState(477); + setState(499); ((GroupByClauseContext)_localctx).groupByVar = groupByVar(); ((GroupByClauseContext)_localctx).vars.add(((GroupByClauseContext)_localctx).groupByVar); } } - setState(482); + setState(504); _errHandler.sync(this); _la = _input.LA(1); } @@ -2630,40 +2711,40 @@ public final GroupByVarContext groupByVar() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(483); + setState(505); ((GroupByVarContext)_localctx).var_ref = varRef(); - setState(490); + setState(512); _errHandler.sync(this); _la = _input.LA(1); if (_la==T__20 || _la==Kas) { { - setState(486); + setState(508); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kas) { { - setState(484); + setState(506); match(Kas); - setState(485); + setState(507); ((GroupByVarContext)_localctx).seq = sequenceType(); } } - setState(488); + setState(510); ((GroupByVarContext)_localctx).decl = match(T__20); - setState(489); + setState(511); ((GroupByVarContext)_localctx).ex = exprSingle(); } } - setState(494); + setState(516); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kcollation) { { - setState(492); + setState(514); match(Kcollation); - setState(493); + setState(515); ((GroupByVarContext)_localctx).uri = uriLiteral(); } } @@ -2710,15 +2791,15 @@ public final OrderByClauseContext orderByClause() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(501); + setState(523); _errHandler.sync(this); switch (_input.LA(1)) { case Korder: { { - setState(496); + setState(518); match(Korder); - setState(497); + setState(519); match(Kby); } } @@ -2726,11 +2807,11 @@ public final OrderByClauseContext orderByClause() throws RecognitionException { case Kstable: { { - setState(498); + setState(520); ((OrderByClauseContext)_localctx).stb = match(Kstable); - setState(499); + setState(521); match(Korder); - setState(500); + setState(522); match(Kby); } } @@ -2738,21 +2819,21 @@ public final OrderByClauseContext orderByClause() throws RecognitionException { default: throw new NoViableAltException(this); } - setState(503); + setState(525); orderByExpr(); - setState(508); + setState(530); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__19) { { { - setState(504); + setState(526); match(T__19); - setState(505); + setState(527); orderByExpr(); } } - setState(510); + setState(532); _errHandler.sync(this); _la = _input.LA(1); } @@ -2805,20 +2886,20 @@ public final OrderByExprContext orderByExpr() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(511); + setState(533); ((OrderByExprContext)_localctx).ex = exprSingle(); - setState(514); + setState(536); _errHandler.sync(this); switch (_input.LA(1)) { case Kascending: { - setState(512); + setState(534); match(Kascending); } break; case Kdescending: { - setState(513); + setState(535); ((OrderByExprContext)_localctx).desc = match(Kdescending); } break; @@ -2837,25 +2918,25 @@ public final OrderByExprContext orderByExpr() throws RecognitionException { default: break; } - setState(521); + setState(543); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kempty) { { - setState(516); + setState(538); match(Kempty); - setState(519); + setState(541); _errHandler.sync(this); switch (_input.LA(1)) { case Kgreatest: { - setState(517); + setState(539); ((OrderByExprContext)_localctx).gr = match(Kgreatest); } break; case Kleast: { - setState(518); + setState(540); ((OrderByExprContext)_localctx).ls = match(Kleast); } break; @@ -2865,14 +2946,14 @@ public final OrderByExprContext orderByExpr() throws RecognitionException { } } - setState(525); + setState(547); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kcollation) { { - setState(523); + setState(545); match(Kcollation); - setState(524); + setState(546); ((OrderByExprContext)_localctx).uril = uriLiteral(); } } @@ -2912,9 +2993,9 @@ public final CountClauseContext countClause() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(527); + setState(549); match(Kcount); - setState(528); + setState(550); varRef(); } } @@ -2964,47 +3045,47 @@ public final QuantifiedExprContext quantifiedExpr() throws RecognitionException try { enterOuterAlt(_localctx, 1); { - setState(532); + setState(554); _errHandler.sync(this); switch (_input.LA(1)) { case Ksome: { - setState(530); + setState(552); ((QuantifiedExprContext)_localctx).so = match(Ksome); } break; case Kevery: { - setState(531); + setState(553); ((QuantifiedExprContext)_localctx).ev = match(Kevery); } break; default: throw new NoViableAltException(this); } - setState(534); + setState(556); ((QuantifiedExprContext)_localctx).quantifiedExprVar = quantifiedExprVar(); ((QuantifiedExprContext)_localctx).vars.add(((QuantifiedExprContext)_localctx).quantifiedExprVar); - setState(539); + setState(561); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__19) { { { - setState(535); + setState(557); match(T__19); - setState(536); + setState(558); ((QuantifiedExprContext)_localctx).quantifiedExprVar = quantifiedExprVar(); ((QuantifiedExprContext)_localctx).vars.add(((QuantifiedExprContext)_localctx).quantifiedExprVar); } } - setState(541); + setState(563); _errHandler.sync(this); _la = _input.LA(1); } - setState(542); + setState(564); match(Ksatisfies); - setState(543); + setState(565); exprSingle(); } } @@ -3049,23 +3130,23 @@ public final QuantifiedExprVarContext quantifiedExprVar() throws RecognitionExce try { enterOuterAlt(_localctx, 1); { - setState(545); + setState(567); varRef(); - setState(548); + setState(570); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kas) { { - setState(546); + setState(568); match(Kas); - setState(547); + setState(569); sequenceType(); } } - setState(550); + setState(572); match(Kin); - setState(551); + setState(573); exprSingle(); } } @@ -3118,34 +3199,34 @@ public final SwitchExprContext switchExpr() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(553); + setState(575); match(Kswitch); - setState(554); + setState(576); match(T__23); - setState(555); + setState(577); ((SwitchExprContext)_localctx).cond = expr(); - setState(556); + setState(578); match(T__24); - setState(558); + setState(580); _errHandler.sync(this); _la = _input.LA(1); do { { { - setState(557); + setState(579); ((SwitchExprContext)_localctx).switchCaseClause = switchCaseClause(); ((SwitchExprContext)_localctx).cases.add(((SwitchExprContext)_localctx).switchCaseClause); } } - setState(560); + setState(582); _errHandler.sync(this); _la = _input.LA(1); } while ( _la==Kcase ); - setState(562); + setState(584); match(Kdefault); - setState(563); + setState(585); match(Kreturn); - setState(564); + setState(586); ((SwitchExprContext)_localctx).def = exprSingle(); } } @@ -3193,26 +3274,26 @@ public final SwitchCaseClauseContext switchCaseClause() throws RecognitionExcept try { enterOuterAlt(_localctx, 1); { - setState(568); + setState(590); _errHandler.sync(this); _la = _input.LA(1); do { { { - setState(566); + setState(588); match(Kcase); - setState(567); + setState(589); ((SwitchCaseClauseContext)_localctx).exprSingle = exprSingle(); ((SwitchCaseClauseContext)_localctx).cond.add(((SwitchCaseClauseContext)_localctx).exprSingle); } } - setState(570); + setState(592); _errHandler.sync(this); _la = _input.LA(1); } while ( _la==Kcase ); - setState(572); + setState(594); match(Kreturn); - setState(573); + setState(595); ((SwitchCaseClauseContext)_localctx).ret = exprSingle(); } } @@ -3269,44 +3350,44 @@ public final TypeSwitchExprContext typeSwitchExpr() throws RecognitionException try { enterOuterAlt(_localctx, 1); { - setState(575); + setState(597); match(Ktypeswitch); - setState(576); + setState(598); match(T__23); - setState(577); + setState(599); ((TypeSwitchExprContext)_localctx).cond = expr(); - setState(578); + setState(600); match(T__24); - setState(580); + setState(602); _errHandler.sync(this); _la = _input.LA(1); do { { { - setState(579); + setState(601); ((TypeSwitchExprContext)_localctx).caseClause = caseClause(); ((TypeSwitchExprContext)_localctx).cses.add(((TypeSwitchExprContext)_localctx).caseClause); } } - setState(582); + setState(604); _errHandler.sync(this); _la = _input.LA(1); } while ( _la==Kcase ); - setState(584); + setState(606); match(Kdefault); - setState(586); + setState(608); _errHandler.sync(this); _la = _input.LA(1); - if (_la==T__32) { + if (_la==T__31) { { - setState(585); + setState(607); ((TypeSwitchExprContext)_localctx).var_ref = varRef(); } } - setState(588); + setState(610); match(Kreturn); - setState(589); + setState(611); ((TypeSwitchExprContext)_localctx).def = exprSingle(); } } @@ -3359,43 +3440,43 @@ public final CaseClauseContext caseClause() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(591); + setState(613); match(Kcase); - setState(595); + setState(617); _errHandler.sync(this); _la = _input.LA(1); - if (_la==T__32) { + if (_la==T__31) { { - setState(592); + setState(614); ((CaseClauseContext)_localctx).var_ref = varRef(); - setState(593); + setState(615); match(Kas); } } - setState(597); + setState(619); ((CaseClauseContext)_localctx).sequenceType = sequenceType(); ((CaseClauseContext)_localctx).union.add(((CaseClauseContext)_localctx).sequenceType); - setState(602); + setState(624); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__33) { + while (_la==T__32) { { { - setState(598); - match(T__33); - setState(599); + setState(620); + match(T__32); + setState(621); ((CaseClauseContext)_localctx).sequenceType = sequenceType(); ((CaseClauseContext)_localctx).union.add(((CaseClauseContext)_localctx).sequenceType); } } - setState(604); + setState(626); _errHandler.sync(this); _la = _input.LA(1); } - setState(605); + setState(627); match(Kreturn); - setState(606); + setState(628); ((CaseClauseContext)_localctx).ret = exprSingle(); } } @@ -3443,21 +3524,21 @@ public final IfExprContext ifExpr() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(608); + setState(630); match(Kif); - setState(609); + setState(631); match(T__23); - setState(610); + setState(632); ((IfExprContext)_localctx).test_condition = expr(); - setState(611); + setState(633); match(T__24); - setState(612); + setState(634); match(Kthen); - setState(613); + setState(635); ((IfExprContext)_localctx).branch = exprSingle(); - setState(614); + setState(636); match(Kelse); - setState(615); + setState(637); ((IfExprContext)_localctx).else_branch = exprSingle(); } } @@ -3504,15 +3585,15 @@ public final TryCatchExprContext tryCatchExpr() throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(617); + setState(639); match(Ktry); - setState(618); + setState(640); match(T__25); - setState(619); + setState(641); ((TryCatchExprContext)_localctx).try_expression = expr(); - setState(620); + setState(642); match(T__26); - setState(622); + setState(644); _errHandler.sync(this); _alt = 1; do { @@ -3520,7 +3601,7 @@ public final TryCatchExprContext tryCatchExpr() throws RecognitionException { case 1: { { - setState(621); + setState(643); ((TryCatchExprContext)_localctx).catchClause = catchClause(); ((TryCatchExprContext)_localctx).catches.add(((TryCatchExprContext)_localctx).catchClause); } @@ -3529,7 +3610,7 @@ public final TryCatchExprContext tryCatchExpr() throws RecognitionException { default: throw new NoViableAltException(this); } - setState(624); + setState(646); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,59,_ctx); } while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ); @@ -3547,7 +3628,7 @@ public final TryCatchExprContext tryCatchExpr() throws RecognitionException { } public static class CatchClauseContext extends ParserRuleContext { - public Token s35; + public Token s34; public List jokers = new ArrayList(); public QnameContext qname; public List errors = new ArrayList(); @@ -3580,16 +3661,16 @@ public final CatchClauseContext catchClause() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(626); + setState(648); match(Kcatch); - setState(629); + setState(651); _errHandler.sync(this); switch (_input.LA(1)) { - case T__34: + case T__33: { - setState(627); - ((CatchClauseContext)_localctx).s35 = match(T__34); - ((CatchClauseContext)_localctx).jokers.add(((CatchClauseContext)_localctx).s35); + setState(649); + ((CatchClauseContext)_localctx).s34 = match(T__33); + ((CatchClauseContext)_localctx).jokers.add(((CatchClauseContext)_localctx).s34); } break; case Kfor: @@ -3644,10 +3725,22 @@ public final CatchClauseContext catchClause() throws RecognitionException { case Kcontext: case Kitem: case Kvariable: + case Kinsert: + case Kdelete: + case Krename: + case Kreplace: + case Kcopy: + case Kmodify: + case Kappend: + case Kinto: + case Kvalue: + case Kjson: + case Kwith: + case Kposition: case NullLiteral: case NCName: { - setState(628); + setState(650); ((CatchClauseContext)_localctx).qname = qname(); ((CatchClauseContext)_localctx).errors.add(((CatchClauseContext)_localctx).qname); } @@ -3655,22 +3748,22 @@ public final CatchClauseContext catchClause() throws RecognitionException { default: throw new NoViableAltException(this); } - setState(638); + setState(660); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__33) { + while (_la==T__32) { { { - setState(631); - match(T__33); - setState(634); + setState(653); + match(T__32); + setState(656); _errHandler.sync(this); switch (_input.LA(1)) { - case T__34: + case T__33: { - setState(632); - ((CatchClauseContext)_localctx).s35 = match(T__34); - ((CatchClauseContext)_localctx).jokers.add(((CatchClauseContext)_localctx).s35); + setState(654); + ((CatchClauseContext)_localctx).s34 = match(T__33); + ((CatchClauseContext)_localctx).jokers.add(((CatchClauseContext)_localctx).s34); } break; case Kfor: @@ -3725,10 +3818,22 @@ public final CatchClauseContext catchClause() throws RecognitionException { case Kcontext: case Kitem: case Kvariable: + case Kinsert: + case Kdelete: + case Krename: + case Kreplace: + case Kcopy: + case Kmodify: + case Kappend: + case Kinto: + case Kvalue: + case Kjson: + case Kwith: + case Kposition: case NullLiteral: case NCName: { - setState(633); + setState(655); ((CatchClauseContext)_localctx).qname = qname(); ((CatchClauseContext)_localctx).errors.add(((CatchClauseContext)_localctx).qname); } @@ -3738,15 +3843,15 @@ public final CatchClauseContext catchClause() throws RecognitionException { } } } - setState(640); + setState(662); _errHandler.sync(this); _la = _input.LA(1); } - setState(641); + setState(663); match(T__25); - setState(642); + setState(664); ((CatchClauseContext)_localctx).catch_expression = expr(); - setState(643); + setState(665); match(T__26); } } @@ -3793,24 +3898,24 @@ public final OrExprContext orExpr() throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(645); + setState(667); ((OrExprContext)_localctx).main_expr = andExpr(); - setState(650); + setState(672); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,63,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(646); + setState(668); match(Kor); - setState(647); + setState(669); ((OrExprContext)_localctx).andExpr = andExpr(); ((OrExprContext)_localctx).rhs.add(((OrExprContext)_localctx).andExpr); } } } - setState(652); + setState(674); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,63,_ctx); } @@ -3859,24 +3964,24 @@ public final AndExprContext andExpr() throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(653); + setState(675); ((AndExprContext)_localctx).main_expr = notExpr(); - setState(658); + setState(680); _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(654); + setState(676); match(Kand); - setState(655); + setState(677); ((AndExprContext)_localctx).notExpr = notExpr(); ((AndExprContext)_localctx).rhs.add(((AndExprContext)_localctx).notExpr); } } } - setState(660); + setState(682); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,64,_ctx); } @@ -3918,18 +4023,18 @@ public final NotExprContext notExpr() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(662); + setState(684); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,65,_ctx) ) { case 1: { - setState(661); + setState(683); ((NotExprContext)_localctx).Knot = match(Knot); ((NotExprContext)_localctx).op.add(((NotExprContext)_localctx).Knot); } break; } - setState(664); + setState(686); ((NotExprContext)_localctx).main_expr = comparisonExpr(); } } @@ -3946,20 +4051,20 @@ public final NotExprContext notExpr() throws RecognitionException { public static class ComparisonExprContext extends ParserRuleContext { public StringConcatExprContext main_expr; - public Token s36; + public Token s35; public List op = new ArrayList(); + public Token s36; public Token s37; public Token s38; public Token s39; public Token s40; - public Token s41; public Token s4; + public Token s41; public Token s42; public Token s43; public Token s44; public Token s45; - public Token s46; - public Token _tset1256; + public Token _tset1280; public StringConcatExprContext stringConcatExpr; public List rhs = new ArrayList(); public List stringConcatExpr() { @@ -3986,26 +4091,26 @@ public final ComparisonExprContext comparisonExpr() throws RecognitionException try { enterOuterAlt(_localctx, 1); { - setState(666); + setState(688); ((ComparisonExprContext)_localctx).main_expr = stringConcatExpr(); - setState(669); + setState(691); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__3) | (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) | (1L << T__45))) != 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(667); - ((ComparisonExprContext)_localctx)._tset1256 = _input.LT(1); + setState(689); + ((ComparisonExprContext)_localctx)._tset1280 = _input.LT(1); _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__3) | (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) | (1L << T__45))) != 0)) ) { - ((ComparisonExprContext)_localctx)._tset1256 = (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)._tset1280 = (Token)_errHandler.recoverInline(this); } else { if ( _input.LA(1)==Token.EOF ) matchedEOF = true; _errHandler.reportMatch(this); consume(); } - ((ComparisonExprContext)_localctx).op.add(((ComparisonExprContext)_localctx)._tset1256); - setState(668); + ((ComparisonExprContext)_localctx).op.add(((ComparisonExprContext)_localctx)._tset1280); + setState(690); ((ComparisonExprContext)_localctx).stringConcatExpr = stringConcatExpr(); ((ComparisonExprContext)_localctx).rhs.add(((ComparisonExprContext)_localctx).stringConcatExpr); } @@ -4052,22 +4157,22 @@ public final StringConcatExprContext stringConcatExpr() throws RecognitionExcept try { enterOuterAlt(_localctx, 1); { - setState(671); + setState(693); ((StringConcatExprContext)_localctx).main_expr = rangeExpr(); - setState(676); + setState(698); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__46) { + while (_la==T__45) { { { - setState(672); - match(T__46); - setState(673); + setState(694); + match(T__45); + setState(695); ((StringConcatExprContext)_localctx).rangeExpr = rangeExpr(); ((StringConcatExprContext)_localctx).rhs.add(((StringConcatExprContext)_localctx).rangeExpr); } } - setState(678); + setState(700); _errHandler.sync(this); _la = _input.LA(1); } @@ -4112,16 +4217,16 @@ public final RangeExprContext rangeExpr() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(679); + setState(701); ((RangeExprContext)_localctx).main_expr = additiveExpr(); - setState(682); + setState(704); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,68,_ctx) ) { case 1: { - setState(680); + setState(702); match(Kto); - setState(681); + setState(703); ((RangeExprContext)_localctx).additiveExpr = additiveExpr(); ((RangeExprContext)_localctx).rhs.add(((RangeExprContext)_localctx).additiveExpr); } @@ -4142,10 +4247,10 @@ public final RangeExprContext rangeExpr() throws RecognitionException { public static class AdditiveExprContext extends ParserRuleContext { public MultiplicativeExprContext main_expr; - public Token s48; + public Token s47; public List op = new ArrayList(); - public Token s49; - public Token _tset1365; + public Token s48; + public Token _tset1389; public MultiplicativeExprContext multiplicativeExpr; public List rhs = new ArrayList(); public List multiplicativeExpr() { @@ -4173,34 +4278,34 @@ public final AdditiveExprContext additiveExpr() throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(684); + setState(706); ((AdditiveExprContext)_localctx).main_expr = multiplicativeExpr(); - setState(689); + setState(711); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,69,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { { - setState(685); - ((AdditiveExprContext)_localctx)._tset1365 = _input.LT(1); + setState(707); + ((AdditiveExprContext)_localctx)._tset1389 = _input.LT(1); _la = _input.LA(1); - if ( !(_la==T__47 || _la==T__48) ) { - ((AdditiveExprContext)_localctx)._tset1365 = (Token)_errHandler.recoverInline(this); + if ( !(_la==T__46 || _la==T__47) ) { + ((AdditiveExprContext)_localctx)._tset1389 = (Token)_errHandler.recoverInline(this); } else { if ( _input.LA(1)==Token.EOF ) matchedEOF = true; _errHandler.reportMatch(this); consume(); } - ((AdditiveExprContext)_localctx).op.add(((AdditiveExprContext)_localctx)._tset1365); - setState(686); + ((AdditiveExprContext)_localctx).op.add(((AdditiveExprContext)_localctx)._tset1389); + setState(708); ((AdditiveExprContext)_localctx).multiplicativeExpr = multiplicativeExpr(); ((AdditiveExprContext)_localctx).rhs.add(((AdditiveExprContext)_localctx).multiplicativeExpr); } } } - setState(691); + setState(713); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,69,_ctx); } @@ -4219,12 +4324,12 @@ public final AdditiveExprContext additiveExpr() throws RecognitionException { public static class MultiplicativeExprContext extends ParserRuleContext { public InstanceOfExprContext main_expr; - public Token s35; + public Token s34; public List op = new ArrayList(); + public Token s49; public Token s50; public Token s51; - public Token s52; - public Token _tset1393; + public Token _tset1417; public InstanceOfExprContext instanceOfExpr; public List rhs = new ArrayList(); public List instanceOfExpr() { @@ -4251,32 +4356,32 @@ public final MultiplicativeExprContext multiplicativeExpr() throws RecognitionEx try { enterOuterAlt(_localctx, 1); { - setState(692); + setState(714); ((MultiplicativeExprContext)_localctx).main_expr = instanceOfExpr(); - setState(697); + setState(719); _errHandler.sync(this); _la = _input.LA(1); - while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__34) | (1L << T__49) | (1L << T__50) | (1L << T__51))) != 0)) { + while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__33) | (1L << T__48) | (1L << T__49) | (1L << T__50))) != 0)) { { { - setState(693); - ((MultiplicativeExprContext)_localctx)._tset1393 = _input.LT(1); + setState(715); + ((MultiplicativeExprContext)_localctx)._tset1417 = _input.LT(1); _la = _input.LA(1); - if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__34) | (1L << T__49) | (1L << T__50) | (1L << T__51))) != 0)) ) { - ((MultiplicativeExprContext)_localctx)._tset1393 = (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)._tset1417 = (Token)_errHandler.recoverInline(this); } else { if ( _input.LA(1)==Token.EOF ) matchedEOF = true; _errHandler.reportMatch(this); consume(); } - ((MultiplicativeExprContext)_localctx).op.add(((MultiplicativeExprContext)_localctx)._tset1393); - setState(694); + ((MultiplicativeExprContext)_localctx).op.add(((MultiplicativeExprContext)_localctx)._tset1417); + setState(716); ((MultiplicativeExprContext)_localctx).instanceOfExpr = instanceOfExpr(); ((MultiplicativeExprContext)_localctx).rhs.add(((MultiplicativeExprContext)_localctx).instanceOfExpr); } } - setState(699); + setState(721); _errHandler.sync(this); _la = _input.LA(1); } @@ -4321,18 +4426,18 @@ public final InstanceOfExprContext instanceOfExpr() throws RecognitionException try { enterOuterAlt(_localctx, 1); { - setState(700); + setState(722); ((InstanceOfExprContext)_localctx).main_expr = isStaticallyExpr(); - setState(704); + setState(726); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,71,_ctx) ) { case 1: { - setState(701); + setState(723); match(Kinstance); - setState(702); + setState(724); match(Kof); - setState(703); + setState(725); ((InstanceOfExprContext)_localctx).seq = sequenceType(); } break; @@ -4378,18 +4483,18 @@ public final IsStaticallyExprContext isStaticallyExpr() throws RecognitionExcept try { enterOuterAlt(_localctx, 1); { - setState(706); + setState(728); ((IsStaticallyExprContext)_localctx).main_expr = treatExpr(); - setState(710); + setState(732); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,72,_ctx) ) { case 1: { - setState(707); + setState(729); match(Kis); - setState(708); + setState(730); match(Kstatically); - setState(709); + setState(731); ((IsStaticallyExprContext)_localctx).seq = sequenceType(); } break; @@ -4435,18 +4540,18 @@ public final TreatExprContext treatExpr() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(712); + setState(734); ((TreatExprContext)_localctx).main_expr = castableExpr(); - setState(716); + setState(738); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,73,_ctx) ) { case 1: { - setState(713); + setState(735); match(Ktreat); - setState(714); + setState(736); match(Kas); - setState(715); + setState(737); ((TreatExprContext)_localctx).seq = sequenceType(); } break; @@ -4492,18 +4597,18 @@ public final CastableExprContext castableExpr() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(718); + setState(740); ((CastableExprContext)_localctx).main_expr = castExpr(); - setState(722); + setState(744); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,74,_ctx) ) { case 1: { - setState(719); + setState(741); match(Kcastable); - setState(720); + setState(742); match(Kas); - setState(721); + setState(743); ((CastableExprContext)_localctx).single = singleType(); } break; @@ -4549,18 +4654,18 @@ public final CastExprContext castExpr() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(724); + setState(746); ((CastExprContext)_localctx).main_expr = arrowExpr(); - setState(728); + setState(750); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,75,_ctx) ) { case 1: { - setState(725); + setState(747); match(Kcast); - setState(726); + setState(748); match(Kas); - setState(727); + setState(749); ((CastExprContext)_localctx).single = singleType(); } break; @@ -4617,9 +4722,9 @@ public final ArrowExprContext arrowExpr() throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(730); + setState(752); ((ArrowExprContext)_localctx).main_expr = unaryExpr(); - setState(739); + setState(761); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,76,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { @@ -4627,21 +4732,21 @@ public final ArrowExprContext arrowExpr() throws RecognitionException { { { { - setState(731); + setState(753); match(T__3); - setState(732); - match(T__44); + setState(754); + match(T__43); } - setState(734); + setState(756); ((ArrowExprContext)_localctx).arrowFunctionSpecifier = arrowFunctionSpecifier(); ((ArrowExprContext)_localctx).function.add(((ArrowExprContext)_localctx).arrowFunctionSpecifier); - setState(735); + setState(757); ((ArrowExprContext)_localctx).argumentList = argumentList(); ((ArrowExprContext)_localctx).arguments.add(((ArrowExprContext)_localctx).argumentList); } } } - setState(741); + setState(763); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,76,_ctx); } @@ -4683,7 +4788,7 @@ public final ArrowFunctionSpecifierContext arrowFunctionSpecifier() throws Recog ArrowFunctionSpecifierContext _localctx = new ArrowFunctionSpecifierContext(_ctx, getState()); enterRule(_localctx, 116, RULE_arrowFunctionSpecifier); try { - setState(745); + setState(767); _errHandler.sync(this); switch (_input.LA(1)) { case Kfor: @@ -4738,25 +4843,37 @@ public final ArrowFunctionSpecifierContext arrowFunctionSpecifier() throws Recog case Kcontext: case Kitem: case Kvariable: + case Kinsert: + case Kdelete: + case Krename: + case Kreplace: + case Kcopy: + case Kmodify: + case Kappend: + case Kinto: + case Kvalue: + case Kjson: + case Kwith: + case Kposition: case NullLiteral: case NCName: enterOuterAlt(_localctx, 1); { - setState(742); + setState(764); qname(); } break; - case T__32: + case T__31: enterOuterAlt(_localctx, 2); { - setState(743); + setState(765); varRef(); } break; case T__23: enterOuterAlt(_localctx, 3); { - setState(744); + setState(766); parenthesizedExpr(); } break; @@ -4776,10 +4893,10 @@ public final ArrowFunctionSpecifierContext arrowFunctionSpecifier() throws Recog } public static class UnaryExprContext extends ParserRuleContext { - public Token s49; - public List op = new ArrayList(); public Token s48; - public Token _tset1572; + public List op = new ArrayList(); + public Token s47; + public Token _tset1596; public ValueExprContext main_expr; public ValueExprContext valueExpr() { return getRuleContext(ValueExprContext.class,0); @@ -4802,31 +4919,31 @@ public final UnaryExprContext unaryExpr() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(750); + setState(772); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__47 || _la==T__48) { + while (_la==T__46 || _la==T__47) { { { - setState(747); - ((UnaryExprContext)_localctx)._tset1572 = _input.LT(1); + setState(769); + ((UnaryExprContext)_localctx)._tset1596 = _input.LT(1); _la = _input.LA(1); - if ( !(_la==T__47 || _la==T__48) ) { - ((UnaryExprContext)_localctx)._tset1572 = (Token)_errHandler.recoverInline(this); + if ( !(_la==T__46 || _la==T__47) ) { + ((UnaryExprContext)_localctx)._tset1596 = (Token)_errHandler.recoverInline(this); } else { if ( _input.LA(1)==Token.EOF ) matchedEOF = true; _errHandler.reportMatch(this); consume(); } - ((UnaryExprContext)_localctx).op.add(((UnaryExprContext)_localctx)._tset1572); + ((UnaryExprContext)_localctx).op.add(((UnaryExprContext)_localctx)._tset1596); } } - setState(752); + setState(774); _errHandler.sync(this); _la = _input.LA(1); } - setState(753); + setState(775); ((UnaryExprContext)_localctx).main_expr = valueExpr(); } } @@ -4865,17 +4982,17 @@ public final ValueExprContext valueExpr() throws RecognitionException { ValueExprContext _localctx = new ValueExprContext(_ctx, getState()); enterRule(_localctx, 120, RULE_valueExpr); try { - setState(757); + setState(779); _errHandler.sync(this); switch (_input.LA(1)) { case T__5: case T__22: case T__23: case T__25: - case T__32: - case T__54: - case T__57: - case T__59: + case T__31: + case T__53: + case T__56: + case T__58: case Kfor: case Klet: case Kwhere: @@ -4928,20 +5045,32 @@ public final ValueExprContext valueExpr() throws RecognitionException { case Kcontext: case Kitem: case Kvariable: + case Kinsert: + case Kdelete: + case Krename: + case Kreplace: + case Kcopy: + case Kmodify: + case Kappend: + case Kinto: + case Kvalue: + case Kjson: + case Kwith: + case Kposition: case STRING: case NullLiteral: case Literal: case NCName: enterOuterAlt(_localctx, 1); { - setState(755); + setState(777); ((ValueExprContext)_localctx).simpleMap_expr = simpleMapExpr(); } break; - case T__52: + case T__51: enterOuterAlt(_localctx, 2); { - setState(756); + setState(778); ((ValueExprContext)_localctx).validate_expr = validateExpr(); } break; @@ -4985,17 +5114,17 @@ public final ValidateExprContext validateExpr() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(759); - match(T__52); - setState(760); + setState(781); + match(T__51); + setState(782); match(Ktype); - setState(761); + setState(783); sequenceType(); - setState(762); + setState(784); match(T__25); - setState(763); + setState(785); expr(); - setState(764); + setState(786); match(T__26); } } @@ -5038,22 +5167,22 @@ public final SimpleMapExprContext simpleMapExpr() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(766); + setState(788); ((SimpleMapExprContext)_localctx).main_expr = postFixExpr(); - setState(771); + setState(793); _errHandler.sync(this); _la = _input.LA(1); - while (_la==T__53) { + while (_la==T__52) { { { - setState(767); - match(T__53); - setState(768); + setState(789); + match(T__52); + setState(790); ((SimpleMapExprContext)_localctx).postFixExpr = postFixExpr(); ((SimpleMapExprContext)_localctx).map_expr.add(((SimpleMapExprContext)_localctx).postFixExpr); } } - setState(773); + setState(795); _errHandler.sync(this); _la = _input.LA(1); } @@ -5123,51 +5252,51 @@ public final PostFixExprContext postFixExpr() throws RecognitionException { int _alt; enterOuterAlt(_localctx, 1); { - setState(774); + setState(796); ((PostFixExprContext)_localctx).main_expr = primaryExpr(); - setState(782); + setState(804); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,82,_ctx); while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) { if ( _alt==1 ) { { - setState(780); + setState(802); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,81,_ctx) ) { case 1: { - setState(775); + setState(797); arrayLookup(); } break; case 2: { - setState(776); + setState(798); predicate(); } break; case 3: { - setState(777); + setState(799); objectLookup(); } break; case 4: { - setState(778); + setState(800); arrayUnboxing(); } break; case 5: { - setState(779); + setState(801); argumentList(); } break; } } } - setState(784); + setState(806); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,82,_ctx); } @@ -5205,16 +5334,16 @@ public final ArrayLookupContext arrayLookup() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(785); + setState(807); + match(T__53); + setState(808); + match(T__53); + setState(809); + expr(); + setState(810); match(T__54); - setState(786); + setState(811); match(T__54); - setState(787); - expr(); - setState(788); - match(T__55); - setState(789); - match(T__55); } } catch (RecognitionException re) { @@ -5246,10 +5375,10 @@ public final ArrayUnboxingContext arrayUnboxing() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(791); + setState(813); + match(T__53); + setState(814); match(T__54); - setState(792); - match(T__55); } } catch (RecognitionException re) { @@ -5284,12 +5413,12 @@ public final PredicateContext predicate() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(794); - match(T__54); - setState(795); + setState(816); + match(T__53); + setState(817); expr(); - setState(796); - match(T__55); + setState(818); + match(T__54); } } catch (RecognitionException re) { @@ -5343,9 +5472,9 @@ public final ObjectLookupContext objectLookup() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(798); - match(T__56); - setState(805); + setState(820); + match(T__55); + setState(827); _errHandler.sync(this); switch (_input.LA(1)) { case Kfor: @@ -5400,39 +5529,51 @@ public final ObjectLookupContext objectLookup() throws RecognitionException { case Kcontext: case Kitem: case Kvariable: + case Kinsert: + case Kdelete: + case Krename: + case Kreplace: + case Kcopy: + case Kmodify: + case Kappend: + case Kinto: + case Kvalue: + case Kjson: + case Kwith: + case Kposition: case NullLiteral: { - setState(799); + setState(821); ((ObjectLookupContext)_localctx).kw = keyWords(); } break; case STRING: { - setState(800); + setState(822); ((ObjectLookupContext)_localctx).lt = stringLiteral(); } break; case NCName: { - setState(801); + setState(823); ((ObjectLookupContext)_localctx).nc = match(NCName); } break; case T__23: { - setState(802); + setState(824); ((ObjectLookupContext)_localctx).pe = parenthesizedExpr(); } break; - case T__32: + case T__31: { - setState(803); + setState(825); ((ObjectLookupContext)_localctx).vr = varRef(); } break; - case T__57: + case T__56: { - setState(804); + setState(826); ((ObjectLookupContext)_localctx).ci = contextItemExpr(); } break; @@ -5502,104 +5643,104 @@ public final PrimaryExprContext primaryExpr() throws RecognitionException { PrimaryExprContext _localctx = new PrimaryExprContext(_ctx, getState()); enterRule(_localctx, 136, RULE_primaryExpr); try { - setState(821); + setState(843); _errHandler.sync(this); switch ( getInterpreter().adaptivePredict(_input,84,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(807); + setState(829); match(NullLiteral); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(808); + setState(830); match(Ktrue); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(809); + setState(831); match(Kfalse); } break; case 4: enterOuterAlt(_localctx, 4); { - setState(810); + setState(832); match(Literal); } break; case 5: enterOuterAlt(_localctx, 5); { - setState(811); + setState(833); stringLiteral(); } break; case 6: enterOuterAlt(_localctx, 6); { - setState(812); + setState(834); varRef(); } break; case 7: enterOuterAlt(_localctx, 7); { - setState(813); + setState(835); parenthesizedExpr(); } break; case 8: enterOuterAlt(_localctx, 8); { - setState(814); + setState(836); contextItemExpr(); } break; case 9: enterOuterAlt(_localctx, 9); { - setState(815); + setState(837); objectConstructor(); } break; case 10: enterOuterAlt(_localctx, 10); { - setState(816); + setState(838); functionCall(); } break; case 11: enterOuterAlt(_localctx, 11); { - setState(817); + setState(839); orderedExpr(); } break; case 12: enterOuterAlt(_localctx, 12); { - setState(818); + setState(840); unorderedExpr(); } break; case 13: enterOuterAlt(_localctx, 13); { - setState(819); + setState(841); arrayConstructor(); } break; case 14: enterOuterAlt(_localctx, 14); { - setState(820); + setState(842); functionItemExpr(); } break; @@ -5638,9 +5779,9 @@ public final VarRefContext varRef() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(823); - match(T__32); - setState(824); + setState(845); + match(T__31); + setState(846); ((VarRefContext)_localctx).var_name = qname(); } } @@ -5677,19 +5818,19 @@ public final ParenthesizedExprContext parenthesizedExpr() throws RecognitionExce try { enterOuterAlt(_localctx, 1); { - setState(826); + setState(848); match(T__23); - setState(828); + setState(850); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__5) | (1L << T__22) | (1L << T__23) | (1L << T__25) | (1L << T__32) | (1L << T__47) | (1L << T__48) | (1L << T__52) | (1L << T__54) | (1L << T__57) | (1L << T__59) | (1L << Kfor) | (1L << Klet))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kwhere - 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 << (Kunordered - 64)) | (1L << (Ktrue - 64)) | (1L << (Kfalse - 64)) | (1L << (Ktype - 64)) | (1L << (Kdeclare - 64)) | (1L << (Kcontext - 64)) | (1L << (Kitem - 64)) | (1L << (Kvariable - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__5) | (1L << T__22) | (1L << T__23) | (1L << T__25) | (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 << (Kunordered - 64)) | (1L << (Ktrue - 64)) | (1L << (Kfalse - 64)) | (1L << (Ktype - 64)) | (1L << (Kdeclare - 64)) | (1L << (Kcontext - 64)) | (1L << (Kitem - 64)) | (1L << (Kvariable - 64)) | (1L << (Kinsert - 64)) | (1L << (Kdelete - 64)) | (1L << (Krename - 64)) | (1L << (Kreplace - 64)) | (1L << (Kcopy - 64)) | (1L << (Kmodify - 64)) | (1L << (Kappend - 64)) | (1L << (Kinto - 64)) | (1L << (Kvalue - 64)) | (1L << (Kjson - 64)) | (1L << (Kwith - 64)) | (1L << (Kposition - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)))) != 0) || _la==Literal || _la==NCName) { { - setState(827); + setState(849); expr(); } } - setState(830); + setState(852); match(T__24); } } @@ -5722,8 +5863,8 @@ public final ContextItemExprContext contextItemExpr() throws RecognitionExceptio try { enterOuterAlt(_localctx, 1); { - setState(832); - match(T__57); + setState(854); + match(T__56); } } catch (RecognitionException re) { @@ -5758,13 +5899,13 @@ public final OrderedExprContext orderedExpr() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(834); + setState(856); match(T__5); - setState(835); + setState(857); match(T__25); - setState(836); + setState(858); expr(); - setState(837); + setState(859); match(T__26); } } @@ -5780,7 +5921,6 @@ public final OrderedExprContext orderedExpr() throws RecognitionException { } public static class UnorderedExprContext extends ParserRuleContext { - public TerminalNode Kunordered() { return getToken(JsoniqParser.Kunordered, 0); } public ExprContext expr() { return getRuleContext(ExprContext.class,0); } @@ -5801,13 +5941,13 @@ public final UnorderedExprContext unorderedExpr() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(839); + setState(861); match(Kunordered); - setState(840); + setState(862); match(T__25); - setState(841); + setState(863); expr(); - setState(842); + setState(864); match(T__26); } } @@ -5847,9 +5987,9 @@ public final FunctionCallContext functionCall() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(844); + setState(866); ((FunctionCallContext)_localctx).fn_name = qname(); - setState(845); + setState(867); argumentList(); } } @@ -5891,34 +6031,34 @@ public final ArgumentListContext argumentList() throws RecognitionException { try { enterOuterAlt(_localctx, 1); { - setState(847); + setState(869); match(T__23); - setState(854); + setState(876); _errHandler.sync(this); _la = _input.LA(1); - while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__5) | (1L << T__22) | (1L << T__23) | (1L << T__25) | (1L << T__32) | (1L << T__47) | (1L << T__48) | (1L << T__52) | (1L << T__54) | (1L << T__57) | (1L << T__59) | (1L << Kfor) | (1L << Klet))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kwhere - 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 << (Kunordered - 64)) | (1L << (Ktrue - 64)) | (1L << (Kfalse - 64)) | (1L << (Ktype - 64)) | (1L << (Kdeclare - 64)) | (1L << (Kcontext - 64)) | (1L << (Kitem - 64)) | (1L << (Kvariable - 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__5) | (1L << T__22) | (1L << T__23) | (1L << T__25) | (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 << (Kunordered - 64)) | (1L << (Ktrue - 64)) | (1L << (Kfalse - 64)) | (1L << (Ktype - 64)) | (1L << (Kdeclare - 64)) | (1L << (Kcontext - 64)) | (1L << (Kitem - 64)) | (1L << (Kvariable - 64)) | (1L << (Kinsert - 64)) | (1L << (Kdelete - 64)) | (1L << (Krename - 64)) | (1L << (Kreplace - 64)) | (1L << (Kcopy - 64)) | (1L << (Kmodify - 64)) | (1L << (Kappend - 64)) | (1L << (Kinto - 64)) | (1L << (Kvalue - 64)) | (1L << (Kjson - 64)) | (1L << (Kwith - 64)) | (1L << (Kposition - 64)) | (1L << (STRING - 64)) | (1L << (ArgumentPlaceholder - 64)) | (1L << (NullLiteral - 64)))) != 0) || _la==Literal || _la==NCName) { { { - setState(848); + setState(870); ((ArgumentListContext)_localctx).argument = argument(); ((ArgumentListContext)_localctx).args.add(((ArgumentListContext)_localctx).argument); - setState(850); + setState(872); _errHandler.sync(this); _la = _input.LA(1); if (_la==T__19) { { - setState(849); + setState(871); match(T__19); } } } } - setState(856); + setState(878); _errHandler.sync(this); _la = _input.LA(1); } - setState(857); + setState(879); match(T__24); } } @@ -5953,20 +6093,20 @@ public final ArgumentContext argument() throws RecognitionException { ArgumentContext _localctx = new ArgumentContext(_ctx, getState()); enterRule(_localctx, 152, RULE_argument); try { - setState(861); + setState(883); _errHandler.sync(this); switch (_input.LA(1)) { case T__5: case T__22: case T__23: case T__25: - case T__32: + case T__31: + case T__46: case T__47: - case T__48: - case T__52: - case T__54: - case T__57: - case T__59: + case T__51: + case T__53: + case T__56: + case T__58: case Kfor: case Klet: case Kwhere: @@ -6019,20 +6159,32 @@ public final ArgumentContext argument() throws RecognitionException { case Kcontext: case Kitem: case Kvariable: + case Kinsert: + case Kdelete: + case Krename: + case Kreplace: + case Kcopy: + case Kmodify: + case Kappend: + case Kinto: + case Kvalue: + case Kjson: + case Kwith: + case Kposition: case STRING: case NullLiteral: case Literal: case NCName: enterOuterAlt(_localctx, 1); { - setState(859); + setState(881); exprSingle(); } break; case ArgumentPlaceholder: enterOuterAlt(_localctx, 2); { - setState(860); + setState(882); match(ArgumentPlaceholder); } break; @@ -6073,7 +6225,7 @@ public final FunctionItemExprContext functionItemExpr() throws RecognitionExcept FunctionItemExprContext _localctx = new FunctionItemExprContext(_ctx, getState()); enterRule(_localctx, 154, RULE_functionItemExpr); try { - setState(865); + setState(887); _errHandler.sync(this); switch (_input.LA(1)) { case Kfor: @@ -6128,18 +6280,30 @@ public final FunctionItemExprContext functionItemExpr() throws RecognitionExcept case Kcontext: case Kitem: case Kvariable: + case Kinsert: + case Kdelete: + case Krename: + case Kreplace: + case Kcopy: + case Kmodify: + case Kappend: + case Kinto: + case Kvalue: + case Kjson: + case Kwith: + case Kposition: case NullLiteral: case NCName: enterOuterAlt(_localctx, 1); { - setState(863); + setState(885); namedFunctionRef(); } break; case T__22: enterOuterAlt(_localctx, 2); { - setState(864); + setState(886); inlineFunctionExpr(); } break; @@ -6182,11 +6346,11 @@ public final NamedFunctionRefContext namedFunctionRef() throws RecognitionExcept try { enterOuterAlt(_localctx, 1); { - setState(867); + setState(889); ((NamedFunctionRefContext)_localctx).fn_name = qname(); - setState(868); - match(T__58); - setState(869); + setState(890); + match(T__57); + setState(891); ((NamedFunctionRefContext)_localctx).arity = match(Literal); } } @@ -6232,48 +6396,48 @@ public final InlineFunctionExprContext inlineFunctionExpr() throws RecognitionEx try { enterOuterAlt(_localctx, 1); { - setState(871); + setState(893); match(T__22); - setState(872); + setState(894); match(T__23); - setState(874); + setState(896); _errHandler.sync(this); _la = _input.LA(1); - if (_la==T__32) { + if (_la==T__31) { { - setState(873); + setState(895); paramList(); } } - setState(876); + setState(898); match(T__24); - setState(879); + setState(901); _errHandler.sync(this); _la = _input.LA(1); if (_la==Kas) { { - setState(877); + setState(899); match(Kas); - setState(878); + setState(900); ((InlineFunctionExprContext)_localctx).return_type = sequenceType(); } } { - setState(881); + setState(903); match(T__25); - setState(883); + setState(905); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__5) | (1L << T__22) | (1L << T__23) | (1L << T__25) | (1L << T__32) | (1L << T__47) | (1L << T__48) | (1L << T__52) | (1L << T__54) | (1L << T__57) | (1L << T__59) | (1L << Kfor) | (1L << Klet))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kwhere - 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 << (Kunordered - 64)) | (1L << (Ktrue - 64)) | (1L << (Kfalse - 64)) | (1L << (Ktype - 64)) | (1L << (Kdeclare - 64)) | (1L << (Kcontext - 64)) | (1L << (Kitem - 64)) | (1L << (Kvariable - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__5) | (1L << T__22) | (1L << T__23) | (1L << T__25) | (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 << (Kunordered - 64)) | (1L << (Ktrue - 64)) | (1L << (Kfalse - 64)) | (1L << (Ktype - 64)) | (1L << (Kdeclare - 64)) | (1L << (Kcontext - 64)) | (1L << (Kitem - 64)) | (1L << (Kvariable - 64)) | (1L << (Kinsert - 64)) | (1L << (Kdelete - 64)) | (1L << (Krename - 64)) | (1L << (Kreplace - 64)) | (1L << (Kcopy - 64)) | (1L << (Kmodify - 64)) | (1L << (Kappend - 64)) | (1L << (Kinto - 64)) | (1L << (Kvalue - 64)) | (1L << (Kjson - 64)) | (1L << (Kwith - 64)) | (1L << (Kposition - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)))) != 0) || _la==Literal || _la==NCName) { { - setState(882); + setState(904); ((InlineFunctionExprContext)_localctx).fn_body = expr(); } } - setState(885); + setState(907); match(T__26); } } @@ -6289,18 +6453,541 @@ public final InlineFunctionExprContext inlineFunctionExpr() throws RecognitionEx return _localctx; } + public static class InsertExprContext extends ParserRuleContext { + public ExprSingleContext to_insert_expr; + public ExprSingleContext main_expr; + public ExprSingleContext pos_expr; + public TerminalNode Kinsert() { return getToken(JsoniqParser.Kinsert, 0); } + public TerminalNode Kjson() { return getToken(JsoniqParser.Kjson, 0); } + public TerminalNode Kinto() { return getToken(JsoniqParser.Kinto, 0); } + public List exprSingle() { + return getRuleContexts(ExprSingleContext.class); + } + public ExprSingleContext exprSingle(int i) { + return getRuleContext(ExprSingleContext.class,i); + } + public TerminalNode Kat() { return getToken(JsoniqParser.Kat, 0); } + public TerminalNode Kposition() { return getToken(JsoniqParser.Kposition, 0); } + public List pairConstructor() { + return getRuleContexts(PairConstructorContext.class); + } + public PairConstructorContext pairConstructor(int i) { + return getRuleContext(PairConstructorContext.class,i); + } + public InsertExprContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_insertExpr; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JsoniqVisitor ) return ((JsoniqVisitor)visitor).visitInsertExpr(this); + else return visitor.visitChildren(this); + } + } + + public final InsertExprContext insertExpr() throws RecognitionException { + InsertExprContext _localctx = new InsertExprContext(_ctx, getState()); + enterRule(_localctx, 160, RULE_insertExpr); + int _la; + try { + setState(932); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,95,_ctx) ) { + case 1: + enterOuterAlt(_localctx, 1); + { + setState(909); + match(Kinsert); + setState(910); + match(Kjson); + setState(911); + ((InsertExprContext)_localctx).to_insert_expr = exprSingle(); + setState(912); + match(Kinto); + setState(913); + ((InsertExprContext)_localctx).main_expr = exprSingle(); + setState(917); + _errHandler.sync(this); + switch ( getInterpreter().adaptivePredict(_input,93,_ctx) ) { + case 1: + { + setState(914); + match(Kat); + setState(915); + match(Kposition); + setState(916); + ((InsertExprContext)_localctx).pos_expr = exprSingle(); + } + break; + } + } + break; + case 2: + enterOuterAlt(_localctx, 2); + { + setState(919); + match(Kinsert); + setState(920); + match(Kjson); + setState(921); + pairConstructor(); + setState(926); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==T__19) { + { + { + setState(922); + match(T__19); + setState(923); + pairConstructor(); + } + } + setState(928); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(929); + match(Kinto); + setState(930); + ((InsertExprContext)_localctx).main_expr = exprSingle(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class DeleteExprContext extends ParserRuleContext { + public TerminalNode Kdelete() { return getToken(JsoniqParser.Kdelete, 0); } + public TerminalNode Kjson() { return getToken(JsoniqParser.Kjson, 0); } + public UpdateLocatorContext updateLocator() { + return getRuleContext(UpdateLocatorContext.class,0); + } + public DeleteExprContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_deleteExpr; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JsoniqVisitor ) return ((JsoniqVisitor)visitor).visitDeleteExpr(this); + else return visitor.visitChildren(this); + } + } + + public final DeleteExprContext deleteExpr() throws RecognitionException { + DeleteExprContext _localctx = new DeleteExprContext(_ctx, getState()); + enterRule(_localctx, 162, RULE_deleteExpr); + try { + enterOuterAlt(_localctx, 1); + { + setState(934); + match(Kdelete); + setState(935); + match(Kjson); + setState(936); + updateLocator(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class RenameExprContext extends ParserRuleContext { + public ExprSingleContext name_expr; + public TerminalNode Krename() { return getToken(JsoniqParser.Krename, 0); } + public TerminalNode Kjson() { return getToken(JsoniqParser.Kjson, 0); } + public UpdateLocatorContext updateLocator() { + return getRuleContext(UpdateLocatorContext.class,0); + } + public TerminalNode Kas() { return getToken(JsoniqParser.Kas, 0); } + public ExprSingleContext exprSingle() { + return getRuleContext(ExprSingleContext.class,0); + } + public RenameExprContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_renameExpr; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JsoniqVisitor ) return ((JsoniqVisitor)visitor).visitRenameExpr(this); + else return visitor.visitChildren(this); + } + } + + public final RenameExprContext renameExpr() throws RecognitionException { + RenameExprContext _localctx = new RenameExprContext(_ctx, getState()); + enterRule(_localctx, 164, RULE_renameExpr); + try { + enterOuterAlt(_localctx, 1); + { + setState(938); + match(Krename); + setState(939); + match(Kjson); + setState(940); + updateLocator(); + setState(941); + match(Kas); + setState(942); + ((RenameExprContext)_localctx).name_expr = exprSingle(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class ReplaceExprContext extends ParserRuleContext { + public ExprSingleContext replacer_expr; + public TerminalNode Kreplace() { return getToken(JsoniqParser.Kreplace, 0); } + public TerminalNode Kjson() { return getToken(JsoniqParser.Kjson, 0); } + public TerminalNode Kvalue() { return getToken(JsoniqParser.Kvalue, 0); } + public TerminalNode Kof() { return getToken(JsoniqParser.Kof, 0); } + public UpdateLocatorContext updateLocator() { + return getRuleContext(UpdateLocatorContext.class,0); + } + public TerminalNode Kwith() { return getToken(JsoniqParser.Kwith, 0); } + public ExprSingleContext exprSingle() { + return getRuleContext(ExprSingleContext.class,0); + } + public ReplaceExprContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_replaceExpr; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JsoniqVisitor ) return ((JsoniqVisitor)visitor).visitReplaceExpr(this); + else return visitor.visitChildren(this); + } + } + + public final ReplaceExprContext replaceExpr() throws RecognitionException { + ReplaceExprContext _localctx = new ReplaceExprContext(_ctx, getState()); + enterRule(_localctx, 166, RULE_replaceExpr); + try { + enterOuterAlt(_localctx, 1); + { + setState(944); + match(Kreplace); + setState(945); + match(Kjson); + setState(946); + match(Kvalue); + setState(947); + match(Kof); + setState(948); + updateLocator(); + setState(949); + match(Kwith); + setState(950); + ((ReplaceExprContext)_localctx).replacer_expr = exprSingle(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class TransformExprContext extends ParserRuleContext { + public ExprSingleContext mod_expr; + public ExprSingleContext ret_expr; + public TerminalNode Kcopy() { return getToken(JsoniqParser.Kcopy, 0); } + public TerminalNode Kjson() { return getToken(JsoniqParser.Kjson, 0); } + public List copyDecl() { + return getRuleContexts(CopyDeclContext.class); + } + public CopyDeclContext copyDecl(int i) { + return getRuleContext(CopyDeclContext.class,i); + } + public TerminalNode Kmodify() { return getToken(JsoniqParser.Kmodify, 0); } + public TerminalNode Kreturn() { return getToken(JsoniqParser.Kreturn, 0); } + public List exprSingle() { + return getRuleContexts(ExprSingleContext.class); + } + public ExprSingleContext exprSingle(int i) { + return getRuleContext(ExprSingleContext.class,i); + } + public TransformExprContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_transformExpr; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JsoniqVisitor ) return ((JsoniqVisitor)visitor).visitTransformExpr(this); + else return visitor.visitChildren(this); + } + } + + public final TransformExprContext transformExpr() throws RecognitionException { + TransformExprContext _localctx = new TransformExprContext(_ctx, getState()); + enterRule(_localctx, 168, RULE_transformExpr); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(952); + match(Kcopy); + setState(953); + match(Kjson); + setState(954); + copyDecl(); + setState(959); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==T__19) { + { + { + setState(955); + match(T__19); + setState(956); + copyDecl(); + } + } + setState(961); + _errHandler.sync(this); + _la = _input.LA(1); + } + setState(962); + match(Kmodify); + setState(963); + ((TransformExprContext)_localctx).mod_expr = exprSingle(); + setState(964); + match(Kreturn); + setState(965); + ((TransformExprContext)_localctx).ret_expr = exprSingle(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class AppendExprContext extends ParserRuleContext { + public ExprSingleContext to_append_expr; + public ExprSingleContext array_expr; + public TerminalNode Kappend() { return getToken(JsoniqParser.Kappend, 0); } + public TerminalNode Kjson() { return getToken(JsoniqParser.Kjson, 0); } + public TerminalNode Kinto() { return getToken(JsoniqParser.Kinto, 0); } + public List exprSingle() { + return getRuleContexts(ExprSingleContext.class); + } + public ExprSingleContext exprSingle(int i) { + return getRuleContext(ExprSingleContext.class,i); + } + public AppendExprContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_appendExpr; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JsoniqVisitor ) return ((JsoniqVisitor)visitor).visitAppendExpr(this); + else return visitor.visitChildren(this); + } + } + + public final AppendExprContext appendExpr() throws RecognitionException { + AppendExprContext _localctx = new AppendExprContext(_ctx, getState()); + enterRule(_localctx, 170, RULE_appendExpr); + try { + enterOuterAlt(_localctx, 1); + { + setState(967); + match(Kappend); + setState(968); + match(Kjson); + setState(969); + ((AppendExprContext)_localctx).to_append_expr = exprSingle(); + setState(970); + match(Kinto); + setState(971); + ((AppendExprContext)_localctx).array_expr = exprSingle(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class UpdateLocatorContext extends ParserRuleContext { + public PrimaryExprContext main_expr; + public PrimaryExprContext primaryExpr() { + return getRuleContext(PrimaryExprContext.class,0); + } + public List arrayLookup() { + return getRuleContexts(ArrayLookupContext.class); + } + public ArrayLookupContext arrayLookup(int i) { + return getRuleContext(ArrayLookupContext.class,i); + } + public List objectLookup() { + return getRuleContexts(ObjectLookupContext.class); + } + public ObjectLookupContext objectLookup(int i) { + return getRuleContext(ObjectLookupContext.class,i); + } + public UpdateLocatorContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_updateLocator; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JsoniqVisitor ) return ((JsoniqVisitor)visitor).visitUpdateLocator(this); + else return visitor.visitChildren(this); + } + } + + public final UpdateLocatorContext updateLocator() throws RecognitionException { + UpdateLocatorContext _localctx = new UpdateLocatorContext(_ctx, getState()); + enterRule(_localctx, 172, RULE_updateLocator); + try { + int _alt; + enterOuterAlt(_localctx, 1); + { + setState(973); + ((UpdateLocatorContext)_localctx).main_expr = primaryExpr(); + setState(976); + _errHandler.sync(this); + _alt = 1; + do { + switch (_alt) { + case 1: + { + setState(976); + _errHandler.sync(this); + switch (_input.LA(1)) { + case T__53: + { + setState(974); + arrayLookup(); + } + break; + case T__55: + { + setState(975); + objectLookup(); + } + break; + default: + throw new NoViableAltException(this); + } + } + break; + default: + throw new NoViableAltException(this); + } + setState(978); + _errHandler.sync(this); + _alt = getInterpreter().adaptivePredict(_input,98,_ctx); + } while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static class CopyDeclContext extends ParserRuleContext { + public VarRefContext var_ref; + public ExprSingleContext src_expr; + public VarRefContext varRef() { + return getRuleContext(VarRefContext.class,0); + } + public ExprSingleContext exprSingle() { + return getRuleContext(ExprSingleContext.class,0); + } + public CopyDeclContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_copyDecl; } + @Override + public T accept(ParseTreeVisitor visitor) { + if ( visitor instanceof JsoniqVisitor ) return ((JsoniqVisitor)visitor).visitCopyDecl(this); + else return visitor.visitChildren(this); + } + } + + public final CopyDeclContext copyDecl() throws RecognitionException { + CopyDeclContext _localctx = new CopyDeclContext(_ctx, getState()); + enterRule(_localctx, 174, RULE_copyDecl); + try { + enterOuterAlt(_localctx, 1); + { + setState(980); + ((CopyDeclContext)_localctx).var_ref = varRef(); + setState(981); + match(T__20); + setState(982); + ((CopyDeclContext)_localctx).src_expr = exprSingle(); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + public static class SequenceTypeContext extends ParserRuleContext { public ItemTypeContext item; - public Token s115; + public Token s126; public List question = new ArrayList(); - public Token s35; + public Token s34; public List star = new ArrayList(); - public Token s48; + public Token s47; public List plus = new ArrayList(); public ItemTypeContext itemType() { return getRuleContext(ItemTypeContext.class,0); } - public TerminalNode ArgumentPlaceholder() { return getToken(JsoniqParser.ArgumentPlaceholder, 0); } public SequenceTypeContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); } @@ -6314,17 +7001,17 @@ public T accept(ParseTreeVisitor visitor) { public final SequenceTypeContext sequenceType() throws RecognitionException { SequenceTypeContext _localctx = new SequenceTypeContext(_ctx, getState()); - enterRule(_localctx, 160, RULE_sequenceType); + enterRule(_localctx, 176, RULE_sequenceType); try { - setState(895); + setState(992); _errHandler.sync(this); switch (_input.LA(1)) { case T__23: enterOuterAlt(_localctx, 1); { - setState(887); + setState(984); match(T__23); - setState(888); + setState(985); match(T__24); } break; @@ -6381,34 +7068,46 @@ public final SequenceTypeContext sequenceType() throws RecognitionException { case Kcontext: case Kitem: case Kvariable: + case Kinsert: + case Kdelete: + case Krename: + case Kreplace: + case Kcopy: + case Kmodify: + case Kappend: + case Kinto: + case Kvalue: + case Kjson: + case Kwith: + case Kposition: case NullLiteral: case NCName: enterOuterAlt(_localctx, 2); { - setState(889); + setState(986); ((SequenceTypeContext)_localctx).item = itemType(); - setState(893); + setState(990); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,93,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,99,_ctx) ) { case 1: { - setState(890); - ((SequenceTypeContext)_localctx).s115 = match(ArgumentPlaceholder); - ((SequenceTypeContext)_localctx).question.add(((SequenceTypeContext)_localctx).s115); + setState(987); + ((SequenceTypeContext)_localctx).s126 = match(ArgumentPlaceholder); + ((SequenceTypeContext)_localctx).question.add(((SequenceTypeContext)_localctx).s126); } break; case 2: { - setState(891); - ((SequenceTypeContext)_localctx).s35 = match(T__34); - ((SequenceTypeContext)_localctx).star.add(((SequenceTypeContext)_localctx).s35); + setState(988); + ((SequenceTypeContext)_localctx).s34 = match(T__33); + ((SequenceTypeContext)_localctx).star.add(((SequenceTypeContext)_localctx).s34); } break; case 3: { - setState(892); - ((SequenceTypeContext)_localctx).s48 = match(T__47); - ((SequenceTypeContext)_localctx).plus.add(((SequenceTypeContext)_localctx).s48); + setState(989); + ((SequenceTypeContext)_localctx).s47 = match(T__46); + ((SequenceTypeContext)_localctx).plus.add(((SequenceTypeContext)_localctx).s47); } break; } @@ -6430,7 +7129,7 @@ public final SequenceTypeContext sequenceType() throws RecognitionException { } public static class ObjectConstructorContext extends ParserRuleContext { - public Token s60; + public Token s59; public List merge_operator = new ArrayList(); public List pairConstructor() { return getRuleContexts(PairConstructorContext.class); @@ -6454,57 +7153,57 @@ public T accept(ParseTreeVisitor visitor) { public final ObjectConstructorContext objectConstructor() throws RecognitionException { ObjectConstructorContext _localctx = new ObjectConstructorContext(_ctx, getState()); - enterRule(_localctx, 162, RULE_objectConstructor); + enterRule(_localctx, 178, RULE_objectConstructor); int _la; try { - setState(913); + setState(1010); _errHandler.sync(this); switch (_input.LA(1)) { case T__25: enterOuterAlt(_localctx, 1); { - setState(897); + setState(994); match(T__25); - setState(906); + setState(1003); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__5) | (1L << T__22) | (1L << T__23) | (1L << T__25) | (1L << T__32) | (1L << T__47) | (1L << T__48) | (1L << T__52) | (1L << T__54) | (1L << T__57) | (1L << T__59) | (1L << Kfor) | (1L << Klet))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kwhere - 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 << (Kunordered - 64)) | (1L << (Ktrue - 64)) | (1L << (Kfalse - 64)) | (1L << (Ktype - 64)) | (1L << (Kdeclare - 64)) | (1L << (Kcontext - 64)) | (1L << (Kitem - 64)) | (1L << (Kvariable - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__5) | (1L << T__22) | (1L << T__23) | (1L << T__25) | (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 << (Kunordered - 64)) | (1L << (Ktrue - 64)) | (1L << (Kfalse - 64)) | (1L << (Ktype - 64)) | (1L << (Kdeclare - 64)) | (1L << (Kcontext - 64)) | (1L << (Kitem - 64)) | (1L << (Kvariable - 64)) | (1L << (Kinsert - 64)) | (1L << (Kdelete - 64)) | (1L << (Krename - 64)) | (1L << (Kreplace - 64)) | (1L << (Kcopy - 64)) | (1L << (Kmodify - 64)) | (1L << (Kappend - 64)) | (1L << (Kinto - 64)) | (1L << (Kvalue - 64)) | (1L << (Kjson - 64)) | (1L << (Kwith - 64)) | (1L << (Kposition - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)))) != 0) || _la==Literal || _la==NCName) { { - setState(898); + setState(995); pairConstructor(); - setState(903); + setState(1000); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__19) { { { - setState(899); + setState(996); match(T__19); - setState(900); + setState(997); pairConstructor(); } } - setState(905); + setState(1002); _errHandler.sync(this); _la = _input.LA(1); } } } - setState(908); + setState(1005); match(T__26); } break; - case T__59: + case T__58: enterOuterAlt(_localctx, 2); { - setState(909); - ((ObjectConstructorContext)_localctx).s60 = match(T__59); - ((ObjectConstructorContext)_localctx).merge_operator.add(((ObjectConstructorContext)_localctx).s60); - setState(910); + setState(1006); + ((ObjectConstructorContext)_localctx).s59 = match(T__58); + ((ObjectConstructorContext)_localctx).merge_operator.add(((ObjectConstructorContext)_localctx).s59); + setState(1007); expr(); - setState(911); - match(T__60); + setState(1008); + match(T__59); } break; default: @@ -6543,29 +7242,29 @@ public T accept(ParseTreeVisitor visitor) { public final ItemTypeContext itemType() throws RecognitionException { ItemTypeContext _localctx = new ItemTypeContext(_ctx, getState()); - enterRule(_localctx, 164, RULE_itemType); + enterRule(_localctx, 180, RULE_itemType); try { - setState(918); + setState(1015); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,98,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,104,_ctx) ) { case 1: enterOuterAlt(_localctx, 1); { - setState(915); + setState(1012); qname(); } break; case 2: enterOuterAlt(_localctx, 2); { - setState(916); + setState(1013); match(NullLiteral); } break; case 3: enterOuterAlt(_localctx, 3); { - setState(917); + setState(1014); functionTest(); } break; @@ -6602,22 +7301,22 @@ public T accept(ParseTreeVisitor visitor) { public final FunctionTestContext functionTest() throws RecognitionException { FunctionTestContext _localctx = new FunctionTestContext(_ctx, getState()); - enterRule(_localctx, 166, RULE_functionTest); + enterRule(_localctx, 182, RULE_functionTest); try { enterOuterAlt(_localctx, 1); { - setState(922); + setState(1019); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,99,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,105,_ctx) ) { case 1: { - setState(920); + setState(1017); anyFunctionTest(); } break; case 2: { - setState(921); + setState(1018); typedFunctionTest(); } break; @@ -6649,17 +7348,17 @@ public T accept(ParseTreeVisitor visitor) { public final AnyFunctionTestContext anyFunctionTest() throws RecognitionException { AnyFunctionTestContext _localctx = new AnyFunctionTestContext(_ctx, getState()); - enterRule(_localctx, 168, RULE_anyFunctionTest); + enterRule(_localctx, 184, RULE_anyFunctionTest); try { enterOuterAlt(_localctx, 1); { - setState(924); + setState(1021); match(T__22); - setState(925); + setState(1022); match(T__23); - setState(926); - match(T__34); - setState(927); + setState(1023); + match(T__33); + setState(1024); match(T__24); } } @@ -6678,7 +7377,6 @@ public static class TypedFunctionTestContext extends ParserRuleContext { public SequenceTypeContext sequenceType; public List st = new ArrayList(); public SequenceTypeContext rt; - public TerminalNode Kas() { return getToken(JsoniqParser.Kas, 0); } public List sequenceType() { return getRuleContexts(SequenceTypeContext.class); } @@ -6698,48 +7396,48 @@ public T accept(ParseTreeVisitor visitor) { public final TypedFunctionTestContext typedFunctionTest() throws RecognitionException { TypedFunctionTestContext _localctx = new TypedFunctionTestContext(_ctx, getState()); - enterRule(_localctx, 170, RULE_typedFunctionTest); + enterRule(_localctx, 186, RULE_typedFunctionTest); int _la; try { enterOuterAlt(_localctx, 1); { - setState(929); + setState(1026); match(T__22); - setState(930); + setState(1027); match(T__23); - setState(939); + setState(1036); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__22) | (1L << T__23) | (1L << Kfor) | (1L << Klet))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kwhere - 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 << (Kunordered - 64)) | (1L << (Ktrue - 64)) | (1L << (Kfalse - 64)) | (1L << (Ktype - 64)) | (1L << (Kdeclare - 64)) | (1L << (Kcontext - 64)) | (1L << (Kitem - 64)) | (1L << (Kvariable - 64)) | (1L << (NullLiteral - 64)) | (1L << (NCName - 64)))) != 0)) { + if (((((_la - 23)) & ~0x3f) == 0 && ((1L << (_la - 23)) & ((1L << (T__22 - 23)) | (1L << (T__23 - 23)) | (1L << (Kfor - 23)) | (1L << (Klet - 23)) | (1L << (Kwhere - 23)) | (1L << (Kgroup - 23)) | (1L << (Kby - 23)) | (1L << (Korder - 23)) | (1L << (Kreturn - 23)) | (1L << (Kif - 23)) | (1L << (Kin - 23)) | (1L << (Kas - 23)) | (1L << (Kat - 23)) | (1L << (Kallowing - 23)) | (1L << (Kempty - 23)) | (1L << (Kcount - 23)) | (1L << (Kstable - 23)) | (1L << (Kascending - 23)) | (1L << (Kdescending - 23)) | (1L << (Ksome - 23)) | (1L << (Kevery - 23)) | (1L << (Ksatisfies - 23)) | (1L << (Kcollation - 23)) | (1L << (Kgreatest - 23)) | (1L << (Kleast - 23)) | (1L << (Kswitch - 23)) | (1L << (Kcase - 23)) | (1L << (Ktry - 23)))) != 0) || ((((_la - 87)) & ~0x3f) == 0 && ((1L << (_la - 87)) & ((1L << (Kcatch - 87)) | (1L << (Kdefault - 87)) | (1L << (Kthen - 87)) | (1L << (Kelse - 87)) | (1L << (Ktypeswitch - 87)) | (1L << (Kor - 87)) | (1L << (Kand - 87)) | (1L << (Knot - 87)) | (1L << (Kto - 87)) | (1L << (Kinstance - 87)) | (1L << (Kof - 87)) | (1L << (Kstatically - 87)) | (1L << (Kis - 87)) | (1L << (Ktreat - 87)) | (1L << (Kcast - 87)) | (1L << (Kcastable - 87)) | (1L << (Kversion - 87)) | (1L << (Kjsoniq - 87)) | (1L << (Kunordered - 87)) | (1L << (Ktrue - 87)) | (1L << (Kfalse - 87)) | (1L << (Ktype - 87)) | (1L << (Kdeclare - 87)) | (1L << (Kcontext - 87)) | (1L << (Kitem - 87)) | (1L << (Kvariable - 87)) | (1L << (Kinsert - 87)) | (1L << (Kdelete - 87)) | (1L << (Krename - 87)) | (1L << (Kreplace - 87)) | (1L << (Kcopy - 87)) | (1L << (Kmodify - 87)) | (1L << (Kappend - 87)) | (1L << (Kinto - 87)) | (1L << (Kvalue - 87)) | (1L << (Kjson - 87)) | (1L << (Kwith - 87)) | (1L << (Kposition - 87)) | (1L << (NullLiteral - 87)) | (1L << (NCName - 87)))) != 0)) { { - setState(931); + setState(1028); ((TypedFunctionTestContext)_localctx).sequenceType = sequenceType(); ((TypedFunctionTestContext)_localctx).st.add(((TypedFunctionTestContext)_localctx).sequenceType); - setState(936); + setState(1033); _errHandler.sync(this); _la = _input.LA(1); while (_la==T__19) { { { - setState(932); + setState(1029); match(T__19); - setState(933); + setState(1030); ((TypedFunctionTestContext)_localctx).sequenceType = sequenceType(); ((TypedFunctionTestContext)_localctx).st.add(((TypedFunctionTestContext)_localctx).sequenceType); } } - setState(938); + setState(1035); _errHandler.sync(this); _la = _input.LA(1); } } } - setState(941); + setState(1038); match(T__24); - setState(942); + setState(1039); match(Kas); - setState(943); + setState(1040); ((TypedFunctionTestContext)_localctx).rt = sequenceType(); } } @@ -6756,12 +7454,11 @@ public final TypedFunctionTestContext typedFunctionTest() throws RecognitionExce public static class SingleTypeContext extends ParserRuleContext { public ItemTypeContext item; - public Token s115; + public Token s126; public List question = new ArrayList(); public ItemTypeContext itemType() { return getRuleContext(ItemTypeContext.class,0); } - public TerminalNode ArgumentPlaceholder() { return getToken(JsoniqParser.ArgumentPlaceholder, 0); } public SingleTypeContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); } @@ -6775,20 +7472,20 @@ public T accept(ParseTreeVisitor visitor) { public final SingleTypeContext singleType() throws RecognitionException { SingleTypeContext _localctx = new SingleTypeContext(_ctx, getState()); - enterRule(_localctx, 172, RULE_singleType); + enterRule(_localctx, 188, RULE_singleType); try { enterOuterAlt(_localctx, 1); { - setState(945); + setState(1042); ((SingleTypeContext)_localctx).item = itemType(); - setState(947); + setState(1044); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,102,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,108,_ctx) ) { case 1: { - setState(946); - ((SingleTypeContext)_localctx).s115 = match(ArgumentPlaceholder); - ((SingleTypeContext)_localctx).question.add(((SingleTypeContext)_localctx).s115); + setState(1043); + ((SingleTypeContext)_localctx).s126 = match(ArgumentPlaceholder); + ((SingleTypeContext)_localctx).question.add(((SingleTypeContext)_localctx).s126); } break; } @@ -6809,7 +7506,6 @@ public static class PairConstructorContext extends ParserRuleContext { public ExprSingleContext lhs; public Token name; public ExprSingleContext rhs; - public TerminalNode ArgumentPlaceholder() { return getToken(JsoniqParser.ArgumentPlaceholder, 0); } public List exprSingle() { return getRuleContexts(ExprSingleContext.class); } @@ -6830,28 +7526,28 @@ public T accept(ParseTreeVisitor visitor) { public final PairConstructorContext pairConstructor() throws RecognitionException { PairConstructorContext _localctx = new PairConstructorContext(_ctx, getState()); - enterRule(_localctx, 174, RULE_pairConstructor); + enterRule(_localctx, 190, RULE_pairConstructor); int _la; try { enterOuterAlt(_localctx, 1); { - setState(951); + setState(1048); _errHandler.sync(this); - switch ( getInterpreter().adaptivePredict(_input,103,_ctx) ) { + switch ( getInterpreter().adaptivePredict(_input,109,_ctx) ) { case 1: { - setState(949); + setState(1046); ((PairConstructorContext)_localctx).lhs = exprSingle(); } break; case 2: { - setState(950); + setState(1047); ((PairConstructorContext)_localctx).name = match(NCName); } break; } - setState(953); + setState(1050); _la = _input.LA(1); if ( !(_la==T__7 || _la==ArgumentPlaceholder) ) { _errHandler.recoverInline(this); @@ -6861,7 +7557,7 @@ public final PairConstructorContext pairConstructor() throws RecognitionExceptio _errHandler.reportMatch(this); consume(); } - setState(954); + setState(1051); ((PairConstructorContext)_localctx).rhs = exprSingle(); } } @@ -6893,25 +7589,25 @@ public T accept(ParseTreeVisitor visitor) { public final ArrayConstructorContext arrayConstructor() throws RecognitionException { ArrayConstructorContext _localctx = new ArrayConstructorContext(_ctx, getState()); - enterRule(_localctx, 176, RULE_arrayConstructor); + enterRule(_localctx, 192, RULE_arrayConstructor); int _la; try { enterOuterAlt(_localctx, 1); { - setState(956); - match(T__54); - setState(958); + setState(1053); + match(T__53); + setState(1055); _errHandler.sync(this); _la = _input.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__5) | (1L << T__22) | (1L << T__23) | (1L << T__25) | (1L << T__32) | (1L << T__47) | (1L << T__48) | (1L << T__52) | (1L << T__54) | (1L << T__57) | (1L << T__59) | (1L << Kfor) | (1L << Klet))) != 0) || ((((_la - 64)) & ~0x3f) == 0 && ((1L << (_la - 64)) & ((1L << (Kwhere - 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 << (Kunordered - 64)) | (1L << (Ktrue - 64)) | (1L << (Kfalse - 64)) | (1L << (Ktype - 64)) | (1L << (Kdeclare - 64)) | (1L << (Kcontext - 64)) | (1L << (Kitem - 64)) | (1L << (Kvariable - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)) | (1L << (Literal - 64)) | (1L << (NCName - 64)))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__5) | (1L << T__22) | (1L << T__23) | (1L << T__25) | (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 << (Kunordered - 64)) | (1L << (Ktrue - 64)) | (1L << (Kfalse - 64)) | (1L << (Ktype - 64)) | (1L << (Kdeclare - 64)) | (1L << (Kcontext - 64)) | (1L << (Kitem - 64)) | (1L << (Kvariable - 64)) | (1L << (Kinsert - 64)) | (1L << (Kdelete - 64)) | (1L << (Krename - 64)) | (1L << (Kreplace - 64)) | (1L << (Kcopy - 64)) | (1L << (Kmodify - 64)) | (1L << (Kappend - 64)) | (1L << (Kinto - 64)) | (1L << (Kvalue - 64)) | (1L << (Kjson - 64)) | (1L << (Kwith - 64)) | (1L << (Kposition - 64)) | (1L << (STRING - 64)) | (1L << (NullLiteral - 64)))) != 0) || _la==Literal || _la==NCName) { { - setState(957); + setState(1054); expr(); } } - setState(960); - match(T__55); + setState(1057); + match(T__54); } } catch (RecognitionException re) { @@ -6942,11 +7638,11 @@ public T accept(ParseTreeVisitor visitor) { public final UriLiteralContext uriLiteral() throws RecognitionException { UriLiteralContext _localctx = new UriLiteralContext(_ctx, getState()); - enterRule(_localctx, 178, RULE_uriLiteral); + enterRule(_localctx, 194, RULE_uriLiteral); try { enterOuterAlt(_localctx, 1); { - setState(962); + setState(1059); stringLiteral(); } } @@ -6976,11 +7672,11 @@ public T accept(ParseTreeVisitor visitor) { public final StringLiteralContext stringLiteral() throws RecognitionException { StringLiteralContext _localctx = new StringLiteralContext(_ctx, getState()); - enterRule(_localctx, 180, RULE_stringLiteral); + enterRule(_localctx, 196, RULE_stringLiteral); try { enterOuterAlt(_localctx, 1); { - setState(964); + setState(1061); match(STRING); } } @@ -7049,6 +7745,18 @@ public static class KeyWordsContext extends ParserRuleContext { public TerminalNode Ktrue() { return getToken(JsoniqParser.Ktrue, 0); } public TerminalNode Kfalse() { return getToken(JsoniqParser.Kfalse, 0); } public TerminalNode Ktype() { return getToken(JsoniqParser.Ktype, 0); } + public TerminalNode Kinsert() { return getToken(JsoniqParser.Kinsert, 0); } + public TerminalNode Kdelete() { return getToken(JsoniqParser.Kdelete, 0); } + public TerminalNode Krename() { return getToken(JsoniqParser.Krename, 0); } + public TerminalNode Kreplace() { return getToken(JsoniqParser.Kreplace, 0); } + public TerminalNode Kappend() { return getToken(JsoniqParser.Kappend, 0); } + public TerminalNode Kcopy() { return getToken(JsoniqParser.Kcopy, 0); } + public TerminalNode Kmodify() { return getToken(JsoniqParser.Kmodify, 0); } + public TerminalNode Kjson() { return getToken(JsoniqParser.Kjson, 0); } + public TerminalNode Kinto() { return getToken(JsoniqParser.Kinto, 0); } + public TerminalNode Kvalue() { return getToken(JsoniqParser.Kvalue, 0); } + public TerminalNode Kwith() { return getToken(JsoniqParser.Kwith, 0); } + public TerminalNode Kposition() { return getToken(JsoniqParser.Kposition, 0); } public KeyWordsContext(ParserRuleContext parent, int invokingState) { super(parent, invokingState); } @@ -7062,14 +7770,14 @@ public T accept(ParseTreeVisitor visitor) { public final KeyWordsContext keyWords() throws RecognitionException { KeyWordsContext _localctx = new KeyWordsContext(_ctx, getState()); - enterRule(_localctx, 182, RULE_keyWords); + enterRule(_localctx, 198, RULE_keyWords); int _la; try { enterOuterAlt(_localctx, 1); { - setState(966); + setState(1063); _la = _input.LA(1); - if ( !(((((_la - 62)) & ~0x3f) == 0 && ((1L << (_la - 62)) & ((1L << (Kfor - 62)) | (1L << (Klet - 62)) | (1L << (Kwhere - 62)) | (1L << (Kgroup - 62)) | (1L << (Kby - 62)) | (1L << (Korder - 62)) | (1L << (Kreturn - 62)) | (1L << (Kif - 62)) | (1L << (Kin - 62)) | (1L << (Kas - 62)) | (1L << (Kat - 62)) | (1L << (Kallowing - 62)) | (1L << (Kempty - 62)) | (1L << (Kcount - 62)) | (1L << (Kstable - 62)) | (1L << (Kascending - 62)) | (1L << (Kdescending - 62)) | (1L << (Ksome - 62)) | (1L << (Kevery - 62)) | (1L << (Ksatisfies - 62)) | (1L << (Kcollation - 62)) | (1L << (Kgreatest - 62)) | (1L << (Kleast - 62)) | (1L << (Kswitch - 62)) | (1L << (Kcase - 62)) | (1L << (Ktry - 62)) | (1L << (Kcatch - 62)) | (1L << (Kdefault - 62)) | (1L << (Kthen - 62)) | (1L << (Kelse - 62)) | (1L << (Ktypeswitch - 62)) | (1L << (Kor - 62)) | (1L << (Kand - 62)) | (1L << (Knot - 62)) | (1L << (Kto - 62)) | (1L << (Kinstance - 62)) | (1L << (Kof - 62)) | (1L << (Kstatically - 62)) | (1L << (Kis - 62)) | (1L << (Ktreat - 62)) | (1L << (Kcast - 62)) | (1L << (Kcastable - 62)) | (1L << (Kversion - 62)) | (1L << (Kjsoniq - 62)) | (1L << (Kunordered - 62)) | (1L << (Ktrue - 62)) | (1L << (Kfalse - 62)) | (1L << (Ktype - 62)) | (1L << (Kdeclare - 62)) | (1L << (Kcontext - 62)) | (1L << (Kitem - 62)) | (1L << (Kvariable - 62)) | (1L << (NullLiteral - 62)))) != 0)) ) { + if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((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 << (Kunordered - 64)) | (1L << (Ktrue - 64)) | (1L << (Kfalse - 64)) | (1L << (Ktype - 64)) | (1L << (Kdeclare - 64)) | (1L << (Kcontext - 64)) | (1L << (Kitem - 64)) | (1L << (Kvariable - 64)) | (1L << (Kinsert - 64)) | (1L << (Kdelete - 64)) | (1L << (Krename - 64)) | (1L << (Kreplace - 64)) | (1L << (Kcopy - 64)) | (1L << (Kmodify - 64)) | (1L << (Kappend - 64)) | (1L << (Kinto - 64)) | (1L << (Kvalue - 64)) | (1L << (Kjson - 64)) | (1L << (Kwith - 64)) | (1L << (Kposition - 64)) | (1L << (NullLiteral - 64)))) != 0)) ) { _errHandler.recoverInline(this); } else { @@ -7091,8 +7799,8 @@ public final KeyWordsContext keyWords() throws RecognitionException { } public static final String _serializedATN = - "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\177\u03cb\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"+ + "\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\u008a\u042c\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"+ "\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+ @@ -7101,359 +7809,396 @@ 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[\4\\\t\\\4]\t]\3\2\3\2\3\2\3"+ - "\3\3\3\3\3\3\3\3\3\5\3\u00c3\n\3\3\3\3\3\5\3\u00c7\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\u00d7\n\6\3\6\3\6\7\6\u00db"+ - "\n\6\f\6\16\6\u00de\13\6\3\6\3\6\3\6\7\6\u00e3\n\6\f\6\16\6\u00e6\13\6"+ - "\3\7\3\7\3\7\3\7\5\7\u00ec\n\7\3\b\3\b\3\b\3\b\3\b\3\b\3\t\3\t\3\t\3\t"+ - "\5\t\u00f8\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\u010e\n\r\3\r\3\r\3\r\3\r\7\r\u0114\n"+ - "\r\f\r\16\r\u0117\13\r\3\16\3\16\5\16\u011b\n\16\3\16\5\16\u011e\n\16"+ - "\3\16\3\16\5\16\u0122\n\16\3\17\3\17\3\20\3\20\3\20\3\20\3\20\5\20\u012b"+ - "\n\20\3\20\3\20\3\20\3\20\3\20\7\20\u0132\n\20\f\20\16\20\u0135\13\20"+ - "\5\20\u0137\n\20\3\21\3\21\3\21\3\21\3\21\5\21\u013e\n\21\3\21\3\21\3"+ - "\21\3\21\3\21\5\21\u0145\n\21\5\21\u0147\n\21\3\22\3\22\3\22\3\22\3\22"+ - "\5\22\u014e\n\22\3\22\3\22\3\22\3\22\3\22\5\22\u0155\n\22\5\22\u0157\n"+ - "\22\3\23\3\23\3\23\3\23\3\23\5\23\u015e\n\23\3\23\3\23\3\23\5\23\u0163"+ - "\n\23\3\23\3\23\5\23\u0167\n\23\3\23\3\23\5\23\u016b\n\23\3\24\3\24\3"+ - "\24\3\24\3\24\5\24\u0172\n\24\3\24\3\24\3\25\3\25\3\25\3\25\3\25\3\25"+ - "\5\25\u017c\n\25\3\26\3\26\3\26\7\26\u0181\n\26\f\26\16\26\u0184\13\26"+ - "\3\27\3\27\3\27\3\27\5\27\u018a\n\27\3\30\3\30\3\30\7\30\u018f\n\30\f"+ - "\30\16\30\u0192\13\30\3\31\3\31\3\31\3\31\3\31\3\31\3\31\5\31\u019b\n"+ - "\31\3\32\3\32\5\32\u019f\n\32\3\32\3\32\3\32\3\32\3\32\3\32\7\32\u01a7"+ - "\n\32\f\32\16\32\u01aa\13\32\3\32\3\32\3\32\3\33\3\33\3\33\3\33\7\33\u01b3"+ - "\n\33\f\33\16\33\u01b6\13\33\3\34\3\34\3\34\5\34\u01bb\n\34\3\34\3\34"+ - "\5\34\u01bf\n\34\3\34\3\34\5\34\u01c3\n\34\3\34\3\34\3\34\3\35\3\35\3"+ - "\35\3\35\7\35\u01cc\n\35\f\35\16\35\u01cf\13\35\3\36\3\36\3\36\5\36\u01d4"+ - "\n\36\3\36\3\36\3\36\3\37\3\37\3\37\3 \3 \3 \3 \3 \7 \u01e1\n \f \16 "+ - "\u01e4\13 \3!\3!\3!\5!\u01e9\n!\3!\3!\5!\u01ed\n!\3!\3!\5!\u01f1\n!\3"+ - "\"\3\"\3\"\3\"\3\"\5\"\u01f8\n\"\3\"\3\"\3\"\7\"\u01fd\n\"\f\"\16\"\u0200"+ - "\13\"\3#\3#\3#\5#\u0205\n#\3#\3#\3#\5#\u020a\n#\5#\u020c\n#\3#\3#\5#\u0210"+ - "\n#\3$\3$\3$\3%\3%\5%\u0217\n%\3%\3%\3%\7%\u021c\n%\f%\16%\u021f\13%\3"+ - "%\3%\3%\3&\3&\3&\5&\u0227\n&\3&\3&\3&\3\'\3\'\3\'\3\'\3\'\6\'\u0231\n"+ - "\'\r\'\16\'\u0232\3\'\3\'\3\'\3\'\3(\3(\6(\u023b\n(\r(\16(\u023c\3(\3"+ - "(\3(\3)\3)\3)\3)\3)\6)\u0247\n)\r)\16)\u0248\3)\3)\5)\u024d\n)\3)\3)\3"+ - ")\3*\3*\3*\3*\5*\u0256\n*\3*\3*\3*\7*\u025b\n*\f*\16*\u025e\13*\3*\3*"+ - "\3*\3+\3+\3+\3+\3+\3+\3+\3+\3+\3,\3,\3,\3,\3,\6,\u0271\n,\r,\16,\u0272"+ - "\3-\3-\3-\5-\u0278\n-\3-\3-\3-\5-\u027d\n-\7-\u027f\n-\f-\16-\u0282\13"+ - "-\3-\3-\3-\3-\3.\3.\3.\7.\u028b\n.\f.\16.\u028e\13.\3/\3/\3/\7/\u0293"+ - "\n/\f/\16/\u0296\13/\3\60\5\60\u0299\n\60\3\60\3\60\3\61\3\61\3\61\5\61"+ - "\u02a0\n\61\3\62\3\62\3\62\7\62\u02a5\n\62\f\62\16\62\u02a8\13\62\3\63"+ - "\3\63\3\63\5\63\u02ad\n\63\3\64\3\64\3\64\7\64\u02b2\n\64\f\64\16\64\u02b5"+ - "\13\64\3\65\3\65\3\65\7\65\u02ba\n\65\f\65\16\65\u02bd\13\65\3\66\3\66"+ - "\3\66\3\66\5\66\u02c3\n\66\3\67\3\67\3\67\3\67\5\67\u02c9\n\67\38\38\3"+ - "8\38\58\u02cf\n8\39\39\39\39\59\u02d5\n9\3:\3:\3:\3:\5:\u02db\n:\3;\3"+ - ";\3;\3;\3;\3;\3;\7;\u02e4\n;\f;\16;\u02e7\13;\3<\3<\3<\5<\u02ec\n<\3="+ - "\7=\u02ef\n=\f=\16=\u02f2\13=\3=\3=\3>\3>\5>\u02f8\n>\3?\3?\3?\3?\3?\3"+ - "?\3?\3@\3@\3@\7@\u0304\n@\f@\16@\u0307\13@\3A\3A\3A\3A\3A\3A\7A\u030f"+ - "\nA\fA\16A\u0312\13A\3B\3B\3B\3B\3B\3B\3C\3C\3C\3D\3D\3D\3D\3E\3E\3E\3"+ - "E\3E\3E\3E\5E\u0328\nE\3F\3F\3F\3F\3F\3F\3F\3F\3F\3F\3F\3F\3F\3F\5F\u0338"+ - "\nF\3G\3G\3G\3H\3H\5H\u033f\nH\3H\3H\3I\3I\3J\3J\3J\3J\3J\3K\3K\3K\3K"+ - "\3K\3L\3L\3L\3M\3M\3M\5M\u0355\nM\7M\u0357\nM\fM\16M\u035a\13M\3M\3M\3"+ - "N\3N\5N\u0360\nN\3O\3O\5O\u0364\nO\3P\3P\3P\3P\3Q\3Q\3Q\5Q\u036d\nQ\3"+ - "Q\3Q\3Q\5Q\u0372\nQ\3Q\3Q\5Q\u0376\nQ\3Q\3Q\3R\3R\3R\3R\3R\3R\5R\u0380"+ - "\nR\5R\u0382\nR\3S\3S\3S\3S\7S\u0388\nS\fS\16S\u038b\13S\5S\u038d\nS\3"+ - "S\3S\3S\3S\3S\5S\u0394\nS\3T\3T\3T\5T\u0399\nT\3U\3U\5U\u039d\nU\3V\3"+ - "V\3V\3V\3V\3W\3W\3W\3W\3W\7W\u03a9\nW\fW\16W\u03ac\13W\5W\u03ae\nW\3W"+ - "\3W\3W\3W\3X\3X\5X\u03b6\nX\3Y\3Y\5Y\u03ba\nY\3Y\3Y\3Y\3Z\3Z\5Z\u03c1"+ - "\nZ\3Z\3Z\3[\3[\3\\\3\\\3]\3]\3]\2\2^\2\4\6\b\n\f\16\20\22\24\26\30\32"+ - "\34\36 \"$&(*,.\60\62\64\668:<>@BDFHJLNPRTVXZ\\^`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\u00b6\u00b8\2\n\4\2\b\bll\3\2UV\3\2\13\24\4\2\6\6&\60\3\2"+ - "\62\63\4\2%%\64\66\4\2\n\nuu\4\2@svv\2\u03fe\2\u00ba\3\2\2\2\4\u00c2\3"+ - "\2\2\2\6\u00c8\3\2\2\2\b\u00cb\3\2\2\2\n\u00dc\3\2\2\2\f\u00eb\3\2\2\2"+ - "\16\u00ed\3\2\2\2\20\u00f7\3\2\2\2\22\u00f9\3\2\2\2\24\u00fe\3\2\2\2\26"+ - "\u0102\3\2\2\2\30\u0108\3\2\2\2\32\u011d\3\2\2\2\34\u0123\3\2\2\2\36\u0125"+ - "\3\2\2\2 \u0138\3\2\2\2\"\u0148\3\2\2\2$\u0158\3\2\2\2&\u016c\3\2\2\2"+ - "(\u017b\3\2\2\2*\u017d\3\2\2\2,\u0185\3\2\2\2.\u018b\3\2\2\2\60\u019a"+ - "\3\2\2\2\62\u019e\3\2\2\2\64\u01ae\3\2\2\2\66\u01b7\3\2\2\28\u01c7\3\2"+ - "\2\2:\u01d0\3\2\2\2<\u01d8\3\2\2\2>\u01db\3\2\2\2@\u01e5\3\2\2\2B\u01f7"+ - "\3\2\2\2D\u0201\3\2\2\2F\u0211\3\2\2\2H\u0216\3\2\2\2J\u0223\3\2\2\2L"+ - "\u022b\3\2\2\2N\u023a\3\2\2\2P\u0241\3\2\2\2R\u0251\3\2\2\2T\u0262\3\2"+ - "\2\2V\u026b\3\2\2\2X\u0274\3\2\2\2Z\u0287\3\2\2\2\\\u028f\3\2\2\2^\u0298"+ - "\3\2\2\2`\u029c\3\2\2\2b\u02a1\3\2\2\2d\u02a9\3\2\2\2f\u02ae\3\2\2\2h"+ - "\u02b6\3\2\2\2j\u02be\3\2\2\2l\u02c4\3\2\2\2n\u02ca\3\2\2\2p\u02d0\3\2"+ - "\2\2r\u02d6\3\2\2\2t\u02dc\3\2\2\2v\u02eb\3\2\2\2x\u02f0\3\2\2\2z\u02f7"+ - "\3\2\2\2|\u02f9\3\2\2\2~\u0300\3\2\2\2\u0080\u0308\3\2\2\2\u0082\u0313"+ - "\3\2\2\2\u0084\u0319\3\2\2\2\u0086\u031c\3\2\2\2\u0088\u0320\3\2\2\2\u008a"+ - "\u0337\3\2\2\2\u008c\u0339\3\2\2\2\u008e\u033c\3\2\2\2\u0090\u0342\3\2"+ - "\2\2\u0092\u0344\3\2\2\2\u0094\u0349\3\2\2\2\u0096\u034e\3\2\2\2\u0098"+ - "\u0351\3\2\2\2\u009a\u035f\3\2\2\2\u009c\u0363\3\2\2\2\u009e\u0365\3\2"+ - "\2\2\u00a0\u0369\3\2\2\2\u00a2\u0381\3\2\2\2\u00a4\u0393\3\2\2\2\u00a6"+ - "\u0398\3\2\2\2\u00a8\u039c\3\2\2\2\u00aa\u039e\3\2\2\2\u00ac\u03a3\3\2"+ - "\2\2\u00ae\u03b3\3\2\2\2\u00b0\u03b9\3\2\2\2\u00b2\u03be\3\2\2\2\u00b4"+ - "\u03c4\3\2\2\2\u00b6\u03c6\3\2\2\2\u00b8\u03c8\3\2\2\2\u00ba\u00bb\5\4"+ - "\3\2\u00bb\u00bc\7\2\2\3\u00bc\3\3\2\2\2\u00bd\u00be\7k\2\2\u00be\u00bf"+ - "\7j\2\2\u00bf\u00c0\5\u00b6\\\2\u00c0\u00c1\7\3\2\2\u00c1\u00c3\3\2\2"+ - "\2\u00c2\u00bd\3\2\2\2\u00c2\u00c3\3\2\2\2\u00c3\u00c6\3\2\2\2\u00c4\u00c7"+ - "\5\b\5\2\u00c5\u00c7\5\6\4\2\u00c6\u00c4\3\2\2\2\u00c6\u00c5\3\2\2\2\u00c7"+ - "\5\3\2\2\2\u00c8\u00c9\5\n\6\2\u00c9\u00ca\5.\30\2\u00ca\7\3\2\2\2\u00cb"+ - "\u00cc\7\4\2\2\u00cc\u00cd\7\5\2\2\u00cd\u00ce\7}\2\2\u00ce\u00cf\7\6"+ - "\2\2\u00cf\u00d0\5\u00b4[\2\u00d0\u00d1\7\3\2\2\u00d1\u00d2\5\n\6\2\u00d2"+ - "\t\3\2\2\2\u00d3\u00d7\5\f\7\2\u00d4\u00d7\5\16\b\2\u00d5\u00d7\5\36\20"+ - "\2\u00d6\u00d3\3\2\2\2\u00d6\u00d4\3\2\2\2\u00d6\u00d5\3\2\2\2\u00d7\u00d8"+ - "\3\2\2\2\u00d8\u00d9\7\3\2\2\u00d9\u00db\3\2\2\2\u00da\u00d6\3\2\2\2\u00db"+ - "\u00de\3\2\2\2\u00dc\u00da\3\2\2\2\u00dc\u00dd\3\2\2\2\u00dd\u00e4\3\2"+ - "\2\2\u00de\u00dc\3\2\2\2\u00df\u00e0\5\20\t\2\u00e0\u00e1\7\3\2\2\u00e1"+ - "\u00e3\3\2\2\2\u00e2\u00df\3\2\2\2\u00e3\u00e6\3\2\2\2\u00e4\u00e2\3\2"+ - "\2\2\u00e4\u00e5\3\2\2\2\u00e5\13\3\2\2\2\u00e6\u00e4\3\2\2\2\u00e7\u00ec"+ - "\5\22\n\2\u00e8\u00ec\5\24\13\2\u00e9\u00ec\5\26\f\2\u00ea\u00ec\5\30"+ - "\r\2\u00eb\u00e7\3\2\2\2\u00eb\u00e8\3\2\2\2\u00eb\u00e9\3\2\2\2\u00eb"+ - "\u00ea\3\2\2\2\u00ec\r\3\2\2\2\u00ed\u00ee\7p\2\2\u00ee\u00ef\7\5\2\2"+ - "\u00ef\u00f0\7}\2\2\u00f0\u00f1\7\6\2\2\u00f1\u00f2\5\u00b4[\2\u00f2\17"+ - "\3\2\2\2\u00f3\u00f8\5$\23\2\u00f4\u00f8\5 \21\2\u00f5\u00f8\5&\24\2\u00f6"+ - "\u00f8\5\"\22\2\u00f7\u00f3\3\2\2\2\u00f7\u00f4\3\2\2\2\u00f7\u00f5\3"+ - "\2\2\2\u00f7\u00f6\3\2\2\2\u00f8\21\3\2\2\2\u00f9\u00fa\7p\2\2\u00fa\u00fb"+ - "\7[\2\2\u00fb\u00fc\7T\2\2\u00fc\u00fd\5\u00b4[\2\u00fd\23\3\2\2\2\u00fe"+ - "\u00ff\7p\2\2\u00ff\u0100\7\7\2\2\u0100\u0101\t\2\2\2\u0101\25\3\2\2\2"+ - "\u0102\u0103\7p\2\2\u0103\u0104\7[\2\2\u0104\u0105\7E\2\2\u0105\u0106"+ - "\7L\2\2\u0106\u0107\t\3\2\2\u0107\27\3\2\2\2\u0108\u010d\7p\2\2\u0109"+ - "\u010a\7\t\2\2\u010a\u010e\5\32\16\2\u010b\u010c\7[\2\2\u010c\u010e\7"+ - "\t\2\2\u010d\u0109\3\2\2\2\u010d\u010b\3\2\2\2\u010e\u0115\3\2\2\2\u010f"+ - "\u0110\5\34\17\2\u0110\u0111\7\6\2\2\u0111\u0112\5\u00b6\\\2\u0112\u0114"+ - "\3\2\2\2\u0113\u010f\3\2\2\2\u0114\u0117\3\2\2\2\u0115\u0113\3\2\2\2\u0115"+ - "\u0116\3\2\2\2\u0116\31\3\2\2\2\u0117\u0115\3\2\2\2\u0118\u011b\7}\2\2"+ - "\u0119\u011b\5\u00b8]\2\u011a\u0118\3\2\2\2\u011a\u0119\3\2\2\2\u011b"+ - "\u011c\3\2\2\2\u011c\u011e\7\n\2\2\u011d\u011a\3\2\2\2\u011d\u011e\3\2"+ - "\2\2\u011e\u0121\3\2\2\2\u011f\u0122\7}\2\2\u0120\u0122\5\u00b8]\2\u0121"+ - "\u011f\3\2\2\2\u0121\u0120\3\2\2\2\u0122\33\3\2\2\2\u0123\u0124\t\4\2"+ - "\2\u0124\35\3\2\2\2\u0125\u0126\7\25\2\2\u0126\u012a\7\4\2\2\u0127\u0128"+ - "\7\5\2\2\u0128\u0129\7}\2\2\u0129\u012b\7\6\2\2\u012a\u0127\3\2\2\2\u012a"+ - "\u012b\3\2\2\2\u012b\u012c\3\2\2\2\u012c\u0136\5\u00b4[\2\u012d\u012e"+ - "\7J\2\2\u012e\u0133\5\u00b4[\2\u012f\u0130\7\26\2\2\u0130\u0132\5\u00b4"+ - "[\2\u0131\u012f\3\2\2\2\u0132\u0135\3\2\2\2\u0133\u0131\3\2\2\2\u0133"+ - "\u0134\3\2\2\2\u0134\u0137\3\2\2\2\u0135\u0133\3\2\2\2\u0136\u012d\3\2"+ - "\2\2\u0136\u0137\3\2\2\2\u0137\37\3\2\2\2\u0138\u0139\7p\2\2\u0139\u013a"+ - "\7s\2\2\u013a\u013d\5\u008cG\2\u013b\u013c\7I\2\2\u013c\u013e\5\u00a2"+ - "R\2\u013d\u013b\3\2\2\2\u013d\u013e\3\2\2\2\u013e\u0146\3\2\2\2\u013f"+ - "\u0140\7\27\2\2\u0140\u0147\5\60\31\2\u0141\u0144\7\30\2\2\u0142\u0143"+ - "\7\27\2\2\u0143\u0145\5\60\31\2\u0144\u0142\3\2\2\2\u0144\u0145\3\2\2"+ - "\2\u0145\u0147\3\2\2\2\u0146\u013f\3\2\2\2\u0146\u0141\3\2\2\2\u0147!"+ - "\3\2\2\2\u0148\u0149\7p\2\2\u0149\u014a\7q\2\2\u014a\u014d\7r\2\2\u014b"+ - "\u014c\7I\2\2\u014c\u014e\5\u00a2R\2\u014d\u014b\3\2\2\2\u014d\u014e\3"+ - "\2\2\2\u014e\u0156\3\2\2\2\u014f\u0150\7\27\2\2\u0150\u0157\5\60\31\2"+ - "\u0151\u0154\7\30\2\2\u0152\u0153\7\27\2\2\u0153\u0155\5\60\31\2\u0154"+ - "\u0152\3\2\2\2\u0154\u0155\3\2\2\2\u0155\u0157\3\2\2\2\u0156\u014f\3\2"+ - "\2\2\u0156\u0151\3\2\2\2\u0157#\3\2\2\2\u0158\u0159\7p\2\2\u0159\u015a"+ - "\7\31\2\2\u015a\u015b\5\32\16\2\u015b\u015d\7\32\2\2\u015c\u015e\5*\26"+ - "\2\u015d\u015c\3\2\2\2\u015d\u015e\3\2\2\2\u015e\u015f\3\2\2\2\u015f\u0162"+ - "\7\33\2\2\u0160\u0161\7I\2\2\u0161\u0163\5\u00a2R\2\u0162\u0160\3\2\2"+ - "\2\u0162\u0163\3\2\2\2\u0163\u016a\3\2\2\2\u0164\u0166\7\34\2\2\u0165"+ - "\u0167\5.\30\2\u0166\u0165\3\2\2\2\u0166\u0167\3\2\2\2\u0167\u0168\3\2"+ - "\2\2\u0168\u016b\7\35\2\2\u0169\u016b\7\30\2\2\u016a\u0164\3\2\2\2\u016a"+ - "\u0169\3\2\2\2\u016b%\3\2\2\2\u016c\u016d\7p\2\2\u016d\u016e\7o\2\2\u016e"+ - "\u016f\5\32\16\2\u016f\u0171\7I\2\2\u0170\u0172\5(\25\2\u0171\u0170\3"+ - "\2\2\2\u0171\u0172\3\2\2\2\u0172\u0173\3\2\2\2\u0173\u0174\5\60\31\2\u0174"+ - "\'\3\2\2\2\u0175\u0176\7\36\2\2\u0176\u017c\7\37\2\2\u0177\u0178\7\36"+ - "\2\2\u0178\u017c\7 \2\2\u0179\u017a\7!\2\2\u017a\u017c\7\"\2\2\u017b\u0175"+ - "\3\2\2\2\u017b\u0177\3\2\2\2\u017b\u0179\3\2\2\2\u017c)\3\2\2\2\u017d"+ - "\u0182\5,\27\2\u017e\u017f\7\26\2\2\u017f\u0181\5,\27\2\u0180\u017e\3"+ - "\2\2\2\u0181\u0184\3\2\2\2\u0182\u0180\3\2\2\2\u0182\u0183\3\2\2\2\u0183"+ - "+\3\2\2\2\u0184\u0182\3\2\2\2\u0185\u0186\7#\2\2\u0186\u0189\5\32\16\2"+ - "\u0187\u0188\7I\2\2\u0188\u018a\5\u00a2R\2\u0189\u0187\3\2\2\2\u0189\u018a"+ - "\3\2\2\2\u018a-\3\2\2\2\u018b\u0190\5\60\31\2\u018c\u018d\7\26\2\2\u018d"+ - "\u018f\5\60\31\2\u018e\u018c\3\2\2\2\u018f\u0192\3\2\2\2\u0190\u018e\3"+ - "\2\2\2\u0190\u0191\3\2\2\2\u0191/\3\2\2\2\u0192\u0190\3\2\2\2\u0193\u019b"+ - "\5\62\32\2\u0194\u019b\5H%\2\u0195\u019b\5L\'\2\u0196\u019b\5P)\2\u0197"+ - "\u019b\5T+\2\u0198\u019b\5V,\2\u0199\u019b\5Z.\2\u019a\u0193\3\2\2\2\u019a"+ - "\u0194\3\2\2\2\u019a\u0195\3\2\2\2\u019a\u0196\3\2\2\2\u019a\u0197\3\2"+ - "\2\2\u019a\u0198\3\2\2\2\u019a\u0199\3\2\2\2\u019b\61\3\2\2\2\u019c\u019f"+ - "\5\64\33\2\u019d\u019f\58\35\2\u019e\u019c\3\2\2\2\u019e\u019d\3\2\2\2"+ - "\u019f\u01a8\3\2\2\2\u01a0\u01a7\5\64\33\2\u01a1\u01a7\5<\37\2\u01a2\u01a7"+ - "\58\35\2\u01a3\u01a7\5> \2\u01a4\u01a7\5B\"\2\u01a5\u01a7\5F$\2\u01a6"+ - "\u01a0\3\2\2\2\u01a6\u01a1\3\2\2\2\u01a6\u01a2\3\2\2\2\u01a6\u01a3\3\2"+ - "\2\2\u01a6\u01a4\3\2\2\2\u01a6\u01a5\3\2\2\2\u01a7\u01aa\3\2\2\2\u01a8"+ - "\u01a6\3\2\2\2\u01a8\u01a9\3\2\2\2\u01a9\u01ab\3\2\2\2\u01aa\u01a8\3\2"+ - "\2\2\u01ab\u01ac\7F\2\2\u01ac\u01ad\5\60\31\2\u01ad\63\3\2\2\2\u01ae\u01af"+ - "\7@\2\2\u01af\u01b4\5\66\34\2\u01b0\u01b1\7\26\2\2\u01b1\u01b3\5\66\34"+ - "\2\u01b2\u01b0\3\2\2\2\u01b3\u01b6\3\2\2\2\u01b4\u01b2\3\2\2\2\u01b4\u01b5"+ - "\3\2\2\2\u01b5\65\3\2\2\2\u01b6\u01b4\3\2\2\2\u01b7\u01ba\5\u008cG\2\u01b8"+ - "\u01b9\7I\2\2\u01b9\u01bb\5\u00a2R\2\u01ba\u01b8\3\2\2\2\u01ba\u01bb\3"+ - "\2\2\2\u01bb\u01be\3\2\2\2\u01bc\u01bd\7K\2\2\u01bd\u01bf\7L\2\2\u01be"+ - "\u01bc\3\2\2\2\u01be\u01bf\3\2\2\2\u01bf\u01c2\3\2\2\2\u01c0\u01c1\7J"+ - "\2\2\u01c1\u01c3\5\u008cG\2\u01c2\u01c0\3\2\2\2\u01c2\u01c3\3\2\2\2\u01c3"+ - "\u01c4\3\2\2\2\u01c4\u01c5\7H\2\2\u01c5\u01c6\5\60\31\2\u01c6\67\3\2\2"+ - "\2\u01c7\u01c8\7A\2\2\u01c8\u01cd\5:\36\2\u01c9\u01ca\7\26\2\2\u01ca\u01cc"+ - "\5:\36\2\u01cb\u01c9\3\2\2\2\u01cc\u01cf\3\2\2\2\u01cd\u01cb\3\2\2\2\u01cd"+ - "\u01ce\3\2\2\2\u01ce9\3\2\2\2\u01cf\u01cd\3\2\2\2\u01d0\u01d3\5\u008c"+ - "G\2\u01d1\u01d2\7I\2\2\u01d2\u01d4\5\u00a2R\2\u01d3\u01d1\3\2\2\2\u01d3"+ - "\u01d4\3\2\2\2\u01d4\u01d5\3\2\2\2\u01d5\u01d6\7\27\2\2\u01d6\u01d7\5"+ - "\60\31\2\u01d7;\3\2\2\2\u01d8\u01d9\7B\2\2\u01d9\u01da\5\60\31\2\u01da"+ - "=\3\2\2\2\u01db\u01dc\7C\2\2\u01dc\u01dd\7D\2\2\u01dd\u01e2\5@!\2\u01de"+ - "\u01df\7\26\2\2\u01df\u01e1\5@!\2\u01e0\u01de\3\2\2\2\u01e1\u01e4\3\2"+ - "\2\2\u01e2\u01e0\3\2\2\2\u01e2\u01e3\3\2\2\2\u01e3?\3\2\2\2\u01e4\u01e2"+ - "\3\2\2\2\u01e5\u01ec\5\u008cG\2\u01e6\u01e7\7I\2\2\u01e7\u01e9\5\u00a2"+ - "R\2\u01e8\u01e6\3\2\2\2\u01e8\u01e9\3\2\2\2\u01e9\u01ea\3\2\2\2\u01ea"+ - "\u01eb\7\27\2\2\u01eb\u01ed\5\60\31\2\u01ec\u01e8\3\2\2\2\u01ec\u01ed"+ - "\3\2\2\2\u01ed\u01f0\3\2\2\2\u01ee\u01ef\7T\2\2\u01ef\u01f1\5\u00b4[\2"+ - "\u01f0\u01ee\3\2\2\2\u01f0\u01f1\3\2\2\2\u01f1A\3\2\2\2\u01f2\u01f3\7"+ - "E\2\2\u01f3\u01f8\7D\2\2\u01f4\u01f5\7N\2\2\u01f5\u01f6\7E\2\2\u01f6\u01f8"+ - "\7D\2\2\u01f7\u01f2\3\2\2\2\u01f7\u01f4\3\2\2\2\u01f8\u01f9\3\2\2\2\u01f9"+ - "\u01fe\5D#\2\u01fa\u01fb\7\26\2\2\u01fb\u01fd\5D#\2\u01fc\u01fa\3\2\2"+ - "\2\u01fd\u0200\3\2\2\2\u01fe\u01fc\3\2\2\2\u01fe\u01ff\3\2\2\2\u01ffC"+ - "\3\2\2\2\u0200\u01fe\3\2\2\2\u0201\u0204\5\60\31\2\u0202\u0205\7O\2\2"+ - "\u0203\u0205\7P\2\2\u0204\u0202\3\2\2\2\u0204\u0203\3\2\2\2\u0204\u0205"+ - "\3\2\2\2\u0205\u020b\3\2\2\2\u0206\u0209\7L\2\2\u0207\u020a\7U\2\2\u0208"+ - "\u020a\7V\2\2\u0209\u0207\3\2\2\2\u0209\u0208\3\2\2\2\u020a\u020c\3\2"+ - "\2\2\u020b\u0206\3\2\2\2\u020b\u020c\3\2\2\2\u020c\u020f\3\2\2\2\u020d"+ - "\u020e\7T\2\2\u020e\u0210\5\u00b4[\2\u020f\u020d\3\2\2\2\u020f\u0210\3"+ - "\2\2\2\u0210E\3\2\2\2\u0211\u0212\7M\2\2\u0212\u0213\5\u008cG\2\u0213"+ - "G\3\2\2\2\u0214\u0217\7Q\2\2\u0215\u0217\7R\2\2\u0216\u0214\3\2\2\2\u0216"+ - "\u0215\3\2\2\2\u0217\u0218\3\2\2\2\u0218\u021d\5J&\2\u0219\u021a\7\26"+ - "\2\2\u021a\u021c\5J&\2\u021b\u0219\3\2\2\2\u021c\u021f\3\2\2\2\u021d\u021b"+ - "\3\2\2\2\u021d\u021e\3\2\2\2\u021e\u0220\3\2\2\2\u021f\u021d\3\2\2\2\u0220"+ - "\u0221\7S\2\2\u0221\u0222\5\60\31\2\u0222I\3\2\2\2\u0223\u0226\5\u008c"+ - "G\2\u0224\u0225\7I\2\2\u0225\u0227\5\u00a2R\2\u0226\u0224\3\2\2\2\u0226"+ - "\u0227\3\2\2\2\u0227\u0228\3\2\2\2\u0228\u0229\7H\2\2\u0229\u022a\5\60"+ - "\31\2\u022aK\3\2\2\2\u022b\u022c\7W\2\2\u022c\u022d\7\32\2\2\u022d\u022e"+ - "\5.\30\2\u022e\u0230\7\33\2\2\u022f\u0231\5N(\2\u0230\u022f\3\2\2\2\u0231"+ - "\u0232\3\2\2\2\u0232\u0230\3\2\2\2\u0232\u0233\3\2\2\2\u0233\u0234\3\2"+ - "\2\2\u0234\u0235\7[\2\2\u0235\u0236\7F\2\2\u0236\u0237\5\60\31\2\u0237"+ - "M\3\2\2\2\u0238\u0239\7X\2\2\u0239\u023b\5\60\31\2\u023a\u0238\3\2\2\2"+ - "\u023b\u023c\3\2\2\2\u023c\u023a\3\2\2\2\u023c\u023d\3\2\2\2\u023d\u023e"+ - "\3\2\2\2\u023e\u023f\7F\2\2\u023f\u0240\5\60\31\2\u0240O\3\2\2\2\u0241"+ - "\u0242\7^\2\2\u0242\u0243\7\32\2\2\u0243\u0244\5.\30\2\u0244\u0246\7\33"+ - "\2\2\u0245\u0247\5R*\2\u0246\u0245\3\2\2\2\u0247\u0248\3\2\2\2\u0248\u0246"+ - "\3\2\2\2\u0248\u0249\3\2\2\2\u0249\u024a\3\2\2\2\u024a\u024c\7[\2\2\u024b"+ - "\u024d\5\u008cG\2\u024c\u024b\3\2\2\2\u024c\u024d\3\2\2\2\u024d\u024e"+ - "\3\2\2\2\u024e\u024f\7F\2\2\u024f\u0250\5\60\31\2\u0250Q\3\2\2\2\u0251"+ - "\u0255\7X\2\2\u0252\u0253\5\u008cG\2\u0253\u0254\7I\2\2\u0254\u0256\3"+ - "\2\2\2\u0255\u0252\3\2\2\2\u0255\u0256\3\2\2\2\u0256\u0257\3\2\2\2\u0257"+ - "\u025c\5\u00a2R\2\u0258\u0259\7$\2\2\u0259\u025b\5\u00a2R\2\u025a\u0258"+ - "\3\2\2\2\u025b\u025e\3\2\2\2\u025c\u025a\3\2\2\2\u025c\u025d\3\2\2\2\u025d"+ - "\u025f\3\2\2\2\u025e\u025c\3\2\2\2\u025f\u0260\7F\2\2\u0260\u0261\5\60"+ - "\31\2\u0261S\3\2\2\2\u0262\u0263\7G\2\2\u0263\u0264\7\32\2\2\u0264\u0265"+ - "\5.\30\2\u0265\u0266\7\33\2\2\u0266\u0267\7\\\2\2\u0267\u0268\5\60\31"+ - "\2\u0268\u0269\7]\2\2\u0269\u026a\5\60\31\2\u026aU\3\2\2\2\u026b\u026c"+ - "\7Y\2\2\u026c\u026d\7\34\2\2\u026d\u026e\5.\30\2\u026e\u0270\7\35\2\2"+ - "\u026f\u0271\5X-\2\u0270\u026f\3\2\2\2\u0271\u0272\3\2\2\2\u0272\u0270"+ - "\3\2\2\2\u0272\u0273\3\2\2\2\u0273W\3\2\2\2\u0274\u0277\7Z\2\2\u0275\u0278"+ - "\7%\2\2\u0276\u0278\5\32\16\2\u0277\u0275\3\2\2\2\u0277\u0276\3\2\2\2"+ - "\u0278\u0280\3\2\2\2\u0279\u027c\7$\2\2\u027a\u027d\7%\2\2\u027b\u027d"+ - "\5\32\16\2\u027c\u027a\3\2\2\2\u027c\u027b\3\2\2\2\u027d\u027f\3\2\2\2"+ - "\u027e\u0279\3\2\2\2\u027f\u0282\3\2\2\2\u0280\u027e\3\2\2\2\u0280\u0281"+ - "\3\2\2\2\u0281\u0283\3\2\2\2\u0282\u0280\3\2\2\2\u0283\u0284\7\34\2\2"+ - "\u0284\u0285\5.\30\2\u0285\u0286\7\35\2\2\u0286Y\3\2\2\2\u0287\u028c\5"+ - "\\/\2\u0288\u0289\7_\2\2\u0289\u028b\5\\/\2\u028a\u0288\3\2\2\2\u028b"+ - "\u028e\3\2\2\2\u028c\u028a\3\2\2\2\u028c\u028d\3\2\2\2\u028d[\3\2\2\2"+ - "\u028e\u028c\3\2\2\2\u028f\u0294\5^\60\2\u0290\u0291\7`\2\2\u0291\u0293"+ - "\5^\60\2\u0292\u0290\3\2\2\2\u0293\u0296\3\2\2\2\u0294\u0292\3\2\2\2\u0294"+ - "\u0295\3\2\2\2\u0295]\3\2\2\2\u0296\u0294\3\2\2\2\u0297\u0299\7a\2\2\u0298"+ - "\u0297\3\2\2\2\u0298\u0299\3\2\2\2\u0299\u029a\3\2\2\2\u029a\u029b\5`"+ - "\61\2\u029b_\3\2\2\2\u029c\u029f\5b\62\2\u029d\u029e\t\5\2\2\u029e\u02a0"+ - "\5b\62\2\u029f\u029d\3\2\2\2\u029f\u02a0\3\2\2\2\u02a0a\3\2\2\2\u02a1"+ - "\u02a6\5d\63\2\u02a2\u02a3\7\61\2\2\u02a3\u02a5\5d\63\2\u02a4\u02a2\3"+ - "\2\2\2\u02a5\u02a8\3\2\2\2\u02a6\u02a4\3\2\2\2\u02a6\u02a7\3\2\2\2\u02a7"+ - "c\3\2\2\2\u02a8\u02a6\3\2\2\2\u02a9\u02ac\5f\64\2\u02aa\u02ab\7b\2\2\u02ab"+ - "\u02ad\5f\64\2\u02ac\u02aa\3\2\2\2\u02ac\u02ad\3\2\2\2\u02ade\3\2\2\2"+ - "\u02ae\u02b3\5h\65\2\u02af\u02b0\t\6\2\2\u02b0\u02b2\5h\65\2\u02b1\u02af"+ - "\3\2\2\2\u02b2\u02b5\3\2\2\2\u02b3\u02b1\3\2\2\2\u02b3\u02b4\3\2\2\2\u02b4"+ - "g\3\2\2\2\u02b5\u02b3\3\2\2\2\u02b6\u02bb\5j\66\2\u02b7\u02b8\t\7\2\2"+ - "\u02b8\u02ba\5j\66\2\u02b9\u02b7\3\2\2\2\u02ba\u02bd\3\2\2\2\u02bb\u02b9"+ - "\3\2\2\2\u02bb\u02bc\3\2\2\2\u02bci\3\2\2\2\u02bd\u02bb\3\2\2\2\u02be"+ - "\u02c2\5l\67\2\u02bf\u02c0\7c\2\2\u02c0\u02c1\7d\2\2\u02c1\u02c3\5\u00a2"+ - "R\2\u02c2\u02bf\3\2\2\2\u02c2\u02c3\3\2\2\2\u02c3k\3\2\2\2\u02c4\u02c8"+ - "\5n8\2\u02c5\u02c6\7f\2\2\u02c6\u02c7\7e\2\2\u02c7\u02c9\5\u00a2R\2\u02c8"+ - "\u02c5\3\2\2\2\u02c8\u02c9\3\2\2\2\u02c9m\3\2\2\2\u02ca\u02ce\5p9\2\u02cb"+ - "\u02cc\7g\2\2\u02cc\u02cd\7I\2\2\u02cd\u02cf\5\u00a2R\2\u02ce\u02cb\3"+ - "\2\2\2\u02ce\u02cf\3\2\2\2\u02cfo\3\2\2\2\u02d0\u02d4\5r:\2\u02d1\u02d2"+ - "\7i\2\2\u02d2\u02d3\7I\2\2\u02d3\u02d5\5\u00aeX\2\u02d4\u02d1\3\2\2\2"+ - "\u02d4\u02d5\3\2\2\2\u02d5q\3\2\2\2\u02d6\u02da\5t;\2\u02d7\u02d8\7h\2"+ - "\2\u02d8\u02d9\7I\2\2\u02d9\u02db\5\u00aeX\2\u02da\u02d7\3\2\2\2\u02da"+ - "\u02db\3\2\2\2\u02dbs\3\2\2\2\u02dc\u02e5\5x=\2\u02dd\u02de\7\6\2\2\u02de"+ - "\u02df\7/\2\2\u02df\u02e0\3\2\2\2\u02e0\u02e1\5v<\2\u02e1\u02e2\5\u0098"+ - "M\2\u02e2\u02e4\3\2\2\2\u02e3\u02dd\3\2\2\2\u02e4\u02e7\3\2\2\2\u02e5"+ - "\u02e3\3\2\2\2\u02e5\u02e6\3\2\2\2\u02e6u\3\2\2\2\u02e7\u02e5\3\2\2\2"+ - "\u02e8\u02ec\5\32\16\2\u02e9\u02ec\5\u008cG\2\u02ea\u02ec\5\u008eH\2\u02eb"+ - "\u02e8\3\2\2\2\u02eb\u02e9\3\2\2\2\u02eb\u02ea\3\2\2\2\u02ecw\3\2\2\2"+ - "\u02ed\u02ef\t\6\2\2\u02ee\u02ed\3\2\2\2\u02ef\u02f2\3\2\2\2\u02f0\u02ee"+ - "\3\2\2\2\u02f0\u02f1\3\2\2\2\u02f1\u02f3\3\2\2\2\u02f2\u02f0\3\2\2\2\u02f3"+ - "\u02f4\5z>\2\u02f4y\3\2\2\2\u02f5\u02f8\5~@\2\u02f6\u02f8\5|?\2\u02f7"+ - "\u02f5\3\2\2\2\u02f7\u02f6\3\2\2\2\u02f8{\3\2\2\2\u02f9\u02fa\7\67\2\2"+ - "\u02fa\u02fb\7o\2\2\u02fb\u02fc\5\u00a2R\2\u02fc\u02fd\7\34\2\2\u02fd"+ - "\u02fe\5.\30\2\u02fe\u02ff\7\35\2\2\u02ff}\3\2\2\2\u0300\u0305\5\u0080"+ - "A\2\u0301\u0302\78\2\2\u0302\u0304\5\u0080A\2\u0303\u0301\3\2\2\2\u0304"+ - "\u0307\3\2\2\2\u0305\u0303\3\2\2\2\u0305\u0306\3\2\2\2\u0306\177\3\2\2"+ - "\2\u0307\u0305\3\2\2\2\u0308\u0310\5\u008aF\2\u0309\u030f\5\u0082B\2\u030a"+ - "\u030f\5\u0086D\2\u030b\u030f\5\u0088E\2\u030c\u030f\5\u0084C\2\u030d"+ - "\u030f\5\u0098M\2\u030e\u0309\3\2\2\2\u030e\u030a\3\2\2\2\u030e\u030b"+ - "\3\2\2\2\u030e\u030c\3\2\2\2\u030e\u030d\3\2\2\2\u030f\u0312\3\2\2\2\u0310"+ - "\u030e\3\2\2\2\u0310\u0311\3\2\2\2\u0311\u0081\3\2\2\2\u0312\u0310\3\2"+ - "\2\2\u0313\u0314\79\2\2\u0314\u0315\79\2\2\u0315\u0316\5.\30\2\u0316\u0317"+ - "\7:\2\2\u0317\u0318\7:\2\2\u0318\u0083\3\2\2\2\u0319\u031a\79\2\2\u031a"+ - "\u031b\7:\2\2\u031b\u0085\3\2\2\2\u031c\u031d\79\2\2\u031d\u031e\5.\30"+ - "\2\u031e\u031f\7:\2\2\u031f\u0087\3\2\2\2\u0320\u0327\7;\2\2\u0321\u0328"+ - "\5\u00b8]\2\u0322\u0328\5\u00b6\\\2\u0323\u0328\7}\2\2\u0324\u0328\5\u008e"+ - "H\2\u0325\u0328\5\u008cG\2\u0326\u0328\5\u0090I\2\u0327\u0321\3\2\2\2"+ - "\u0327\u0322\3\2\2\2\u0327\u0323\3\2\2\2\u0327\u0324\3\2\2\2\u0327\u0325"+ - "\3\2\2\2\u0327\u0326\3\2\2\2\u0328\u0089\3\2\2\2\u0329\u0338\7v\2\2\u032a"+ - "\u0338\7m\2\2\u032b\u0338\7n\2\2\u032c\u0338\7w\2\2\u032d\u0338\5\u00b6"+ - "\\\2\u032e\u0338\5\u008cG\2\u032f\u0338\5\u008eH\2\u0330\u0338\5\u0090"+ - "I\2\u0331\u0338\5\u00a4S\2\u0332\u0338\5\u0096L\2\u0333\u0338\5\u0092"+ - "J\2\u0334\u0338\5\u0094K\2\u0335\u0338\5\u00b2Z\2\u0336\u0338\5\u009c"+ - "O\2\u0337\u0329\3\2\2\2\u0337\u032a\3\2\2\2\u0337\u032b\3\2\2\2\u0337"+ - "\u032c\3\2\2\2\u0337\u032d\3\2\2\2\u0337\u032e\3\2\2\2\u0337\u032f\3\2"+ - "\2\2\u0337\u0330\3\2\2\2\u0337\u0331\3\2\2\2\u0337\u0332\3\2\2\2\u0337"+ - "\u0333\3\2\2\2\u0337\u0334\3\2\2\2\u0337\u0335\3\2\2\2\u0337\u0336\3\2"+ - "\2\2\u0338\u008b\3\2\2\2\u0339\u033a\7#\2\2\u033a\u033b\5\32\16\2\u033b"+ - "\u008d\3\2\2\2\u033c\u033e\7\32\2\2\u033d\u033f\5.\30\2\u033e\u033d\3"+ - "\2\2\2\u033e\u033f\3\2\2\2\u033f\u0340\3\2\2\2\u0340\u0341\7\33\2\2\u0341"+ - "\u008f\3\2\2\2\u0342\u0343\7<\2\2\u0343\u0091\3\2\2\2\u0344\u0345\7\b"+ - "\2\2\u0345\u0346\7\34\2\2\u0346\u0347\5.\30\2\u0347\u0348\7\35\2\2\u0348"+ - "\u0093\3\2\2\2\u0349\u034a\7l\2\2\u034a\u034b\7\34\2\2\u034b\u034c\5."+ - "\30\2\u034c\u034d\7\35\2\2\u034d\u0095\3\2\2\2\u034e\u034f\5\32\16\2\u034f"+ - "\u0350\5\u0098M\2\u0350\u0097\3\2\2\2\u0351\u0358\7\32\2\2\u0352\u0354"+ - "\5\u009aN\2\u0353\u0355\7\26\2\2\u0354\u0353\3\2\2\2\u0354\u0355\3\2\2"+ - "\2\u0355\u0357\3\2\2\2\u0356\u0352\3\2\2\2\u0357\u035a\3\2\2\2\u0358\u0356"+ - "\3\2\2\2\u0358\u0359\3\2\2\2\u0359\u035b\3\2\2\2\u035a\u0358\3\2\2\2\u035b"+ - "\u035c\7\33\2\2\u035c\u0099\3\2\2\2\u035d\u0360\5\60\31\2\u035e\u0360"+ - "\7u\2\2\u035f\u035d\3\2\2\2\u035f\u035e\3\2\2\2\u0360\u009b\3\2\2\2\u0361"+ - "\u0364\5\u009eP\2\u0362\u0364\5\u00a0Q\2\u0363\u0361\3\2\2\2\u0363\u0362"+ - "\3\2\2\2\u0364\u009d\3\2\2\2\u0365\u0366\5\32\16\2\u0366\u0367\7=\2\2"+ - "\u0367\u0368\7w\2\2\u0368\u009f\3\2\2\2\u0369\u036a\7\31\2\2\u036a\u036c"+ - "\7\32\2\2\u036b\u036d\5*\26\2\u036c\u036b\3\2\2\2\u036c\u036d\3\2\2\2"+ - "\u036d\u036e\3\2\2\2\u036e\u0371\7\33\2\2\u036f\u0370\7I\2\2\u0370\u0372"+ - "\5\u00a2R\2\u0371\u036f\3\2\2\2\u0371\u0372\3\2\2\2\u0372\u0373\3\2\2"+ - "\2\u0373\u0375\7\34\2\2\u0374\u0376\5.\30\2\u0375\u0374\3\2\2\2\u0375"+ - "\u0376\3\2\2\2\u0376\u0377\3\2\2\2\u0377\u0378\7\35\2\2\u0378\u00a1\3"+ - "\2\2\2\u0379\u037a\7\32\2\2\u037a\u0382\7\33\2\2\u037b\u037f\5\u00a6T"+ - "\2\u037c\u0380\7u\2\2\u037d\u0380\7%\2\2\u037e\u0380\7\62\2\2\u037f\u037c"+ - "\3\2\2\2\u037f\u037d\3\2\2\2\u037f\u037e\3\2\2\2\u037f\u0380\3\2\2\2\u0380"+ - "\u0382\3\2\2\2\u0381\u0379\3\2\2\2\u0381\u037b\3\2\2\2\u0382\u00a3\3\2"+ - "\2\2\u0383\u038c\7\34\2\2\u0384\u0389\5\u00b0Y\2\u0385\u0386\7\26\2\2"+ - "\u0386\u0388\5\u00b0Y\2\u0387\u0385\3\2\2\2\u0388\u038b\3\2\2\2\u0389"+ - "\u0387\3\2\2\2\u0389\u038a\3\2\2\2\u038a\u038d\3\2\2\2\u038b\u0389\3\2"+ - "\2\2\u038c\u0384\3\2\2\2\u038c\u038d\3\2\2\2\u038d\u038e\3\2\2\2\u038e"+ - "\u0394\7\35\2\2\u038f\u0390\7>\2\2\u0390\u0391\5.\30\2\u0391\u0392\7?"+ - "\2\2\u0392\u0394\3\2\2\2\u0393\u0383\3\2\2\2\u0393\u038f\3\2\2\2\u0394"+ - "\u00a5\3\2\2\2\u0395\u0399\5\32\16\2\u0396\u0399\7v\2\2\u0397\u0399\5"+ - "\u00a8U\2\u0398\u0395\3\2\2\2\u0398\u0396\3\2\2\2\u0398\u0397\3\2\2\2"+ - "\u0399\u00a7\3\2\2\2\u039a\u039d\5\u00aaV\2\u039b\u039d\5\u00acW\2\u039c"+ - "\u039a\3\2\2\2\u039c\u039b\3\2\2\2\u039d\u00a9\3\2\2\2\u039e\u039f\7\31"+ - "\2\2\u039f\u03a0\7\32\2\2\u03a0\u03a1\7%\2\2\u03a1\u03a2\7\33\2\2\u03a2"+ - "\u00ab\3\2\2\2\u03a3\u03a4\7\31\2\2\u03a4\u03ad\7\32\2\2\u03a5\u03aa\5"+ - "\u00a2R\2\u03a6\u03a7\7\26\2\2\u03a7\u03a9\5\u00a2R\2\u03a8\u03a6\3\2"+ - "\2\2\u03a9\u03ac\3\2\2\2\u03aa\u03a8\3\2\2\2\u03aa\u03ab\3\2\2\2\u03ab"+ - "\u03ae\3\2\2\2\u03ac\u03aa\3\2\2\2\u03ad\u03a5\3\2\2\2\u03ad\u03ae\3\2"+ - "\2\2\u03ae\u03af\3\2\2\2\u03af\u03b0\7\33\2\2\u03b0\u03b1\7I\2\2\u03b1"+ - "\u03b2\5\u00a2R\2\u03b2\u00ad\3\2\2\2\u03b3\u03b5\5\u00a6T\2\u03b4\u03b6"+ - "\7u\2\2\u03b5\u03b4\3\2\2\2\u03b5\u03b6\3\2\2\2\u03b6\u00af\3\2\2\2\u03b7"+ - "\u03ba\5\60\31\2\u03b8\u03ba\7}\2\2\u03b9\u03b7\3\2\2\2\u03b9\u03b8\3"+ - "\2\2\2\u03ba\u03bb\3\2\2\2\u03bb\u03bc\t\b\2\2\u03bc\u03bd\5\60\31\2\u03bd"+ - "\u00b1\3\2\2\2\u03be\u03c0\79\2\2\u03bf\u03c1\5.\30\2\u03c0\u03bf\3\2"+ - "\2\2\u03c0\u03c1\3\2\2\2\u03c1\u03c2\3\2\2\2\u03c2\u03c3\7:\2\2\u03c3"+ - "\u00b3\3\2\2\2\u03c4\u03c5\5\u00b6\\\2\u03c5\u00b5\3\2\2\2\u03c6\u03c7"+ - "\7t\2\2\u03c7\u00b7\3\2\2\2\u03c8\u03c9\t\t\2\2\u03c9\u00b9\3\2\2\2k\u00c2"+ - "\u00c6\u00d6\u00dc\u00e4\u00eb\u00f7\u010d\u0115\u011a\u011d\u0121\u012a"+ - "\u0133\u0136\u013d\u0144\u0146\u014d\u0154\u0156\u015d\u0162\u0166\u016a"+ - "\u0171\u017b\u0182\u0189\u0190\u019a\u019e\u01a6\u01a8\u01b4\u01ba\u01be"+ - "\u01c2\u01cd\u01d3\u01e2\u01e8\u01ec\u01f0\u01f7\u01fe\u0204\u0209\u020b"+ - "\u020f\u0216\u021d\u0226\u0232\u023c\u0248\u024c\u0255\u025c\u0272\u0277"+ - "\u027c\u0280\u028c\u0294\u0298\u029f\u02a6\u02ac\u02b3\u02bb\u02c2\u02c8"+ - "\u02ce\u02d4\u02da\u02e5\u02eb\u02f0\u02f7\u0305\u030e\u0310\u0327\u0337"+ - "\u033e\u0354\u0358\u035f\u0363\u036c\u0371\u0375\u037f\u0381\u0389\u038c"+ - "\u0393\u0398\u039c\u03aa\u03ad\u03b5\u03b9\u03c0"; + "\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\4]\t]\4^\t^\4_\t_\4"+ + "`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\3\2\3\2\3\2\3\3\3\3\3\3\3\3\3\3\5\3"+ + "\u00d3\n\3\3\3\3\3\5\3\u00d7\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\u00e7\n\6\3\6\3\6\7\6\u00eb\n\6\f\6\16\6\u00ee"+ + "\13\6\3\6\3\6\3\6\7\6\u00f3\n\6\f\6\16\6\u00f6\13\6\3\7\3\7\3\7\3\7\5"+ + "\7\u00fc\n\7\3\b\3\b\3\b\3\b\3\b\3\b\3\t\3\t\3\t\3\t\5\t\u0108\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\u011e\n\r\3\r\3\r\3\r\3\r\7\r\u0124\n\r\f\r\16\r\u0127"+ + "\13\r\3\16\3\16\5\16\u012b\n\16\3\16\5\16\u012e\n\16\3\16\3\16\5\16\u0132"+ + "\n\16\3\17\3\17\3\20\3\20\3\20\3\20\3\20\5\20\u013b\n\20\3\20\3\20\3\20"+ + "\3\20\3\20\7\20\u0142\n\20\f\20\16\20\u0145\13\20\5\20\u0147\n\20\3\21"+ + "\3\21\3\21\3\21\3\21\5\21\u014e\n\21\3\21\3\21\3\21\3\21\3\21\5\21\u0155"+ + "\n\21\5\21\u0157\n\21\3\22\3\22\3\22\3\22\3\22\5\22\u015e\n\22\3\22\3"+ + "\22\3\22\3\22\3\22\5\22\u0165\n\22\5\22\u0167\n\22\3\23\3\23\3\23\3\23"+ + "\3\23\5\23\u016e\n\23\3\23\3\23\3\23\5\23\u0173\n\23\3\23\3\23\5\23\u0177"+ + "\n\23\3\23\3\23\5\23\u017b\n\23\3\24\3\24\3\24\3\24\3\24\5\24\u0182\n"+ + "\24\3\24\3\24\3\25\3\25\3\25\3\25\3\25\3\25\5\25\u018c\n\25\3\26\3\26"+ + "\3\26\7\26\u0191\n\26\f\26\16\26\u0194\13\26\3\27\3\27\3\27\3\27\5\27"+ + "\u019a\n\27\3\30\3\30\3\30\7\30\u019f\n\30\f\30\16\30\u01a2\13\30\3\31"+ + "\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\5\31\u01b1"+ + "\n\31\3\32\3\32\5\32\u01b5\n\32\3\32\3\32\3\32\3\32\3\32\3\32\7\32\u01bd"+ + "\n\32\f\32\16\32\u01c0\13\32\3\32\3\32\3\32\3\33\3\33\3\33\3\33\7\33\u01c9"+ + "\n\33\f\33\16\33\u01cc\13\33\3\34\3\34\3\34\5\34\u01d1\n\34\3\34\3\34"+ + "\5\34\u01d5\n\34\3\34\3\34\5\34\u01d9\n\34\3\34\3\34\3\34\3\35\3\35\3"+ + "\35\3\35\7\35\u01e2\n\35\f\35\16\35\u01e5\13\35\3\36\3\36\3\36\5\36\u01ea"+ + "\n\36\3\36\3\36\3\36\3\37\3\37\3\37\3 \3 \3 \3 \3 \7 \u01f7\n \f \16 "+ + "\u01fa\13 \3!\3!\3!\5!\u01ff\n!\3!\3!\5!\u0203\n!\3!\3!\5!\u0207\n!\3"+ + "\"\3\"\3\"\3\"\3\"\5\"\u020e\n\"\3\"\3\"\3\"\7\"\u0213\n\"\f\"\16\"\u0216"+ + "\13\"\3#\3#\3#\5#\u021b\n#\3#\3#\3#\5#\u0220\n#\5#\u0222\n#\3#\3#\5#\u0226"+ + "\n#\3$\3$\3$\3%\3%\5%\u022d\n%\3%\3%\3%\7%\u0232\n%\f%\16%\u0235\13%\3"+ + "%\3%\3%\3&\3&\3&\5&\u023d\n&\3&\3&\3&\3\'\3\'\3\'\3\'\3\'\6\'\u0247\n"+ + "\'\r\'\16\'\u0248\3\'\3\'\3\'\3\'\3(\3(\6(\u0251\n(\r(\16(\u0252\3(\3"+ + "(\3(\3)\3)\3)\3)\3)\6)\u025d\n)\r)\16)\u025e\3)\3)\5)\u0263\n)\3)\3)\3"+ + ")\3*\3*\3*\3*\5*\u026c\n*\3*\3*\3*\7*\u0271\n*\f*\16*\u0274\13*\3*\3*"+ + "\3*\3+\3+\3+\3+\3+\3+\3+\3+\3+\3,\3,\3,\3,\3,\6,\u0287\n,\r,\16,\u0288"+ + "\3-\3-\3-\5-\u028e\n-\3-\3-\3-\5-\u0293\n-\7-\u0295\n-\f-\16-\u0298\13"+ + "-\3-\3-\3-\3-\3.\3.\3.\7.\u02a1\n.\f.\16.\u02a4\13.\3/\3/\3/\7/\u02a9"+ + "\n/\f/\16/\u02ac\13/\3\60\5\60\u02af\n\60\3\60\3\60\3\61\3\61\3\61\5\61"+ + "\u02b6\n\61\3\62\3\62\3\62\7\62\u02bb\n\62\f\62\16\62\u02be\13\62\3\63"+ + "\3\63\3\63\5\63\u02c3\n\63\3\64\3\64\3\64\7\64\u02c8\n\64\f\64\16\64\u02cb"+ + "\13\64\3\65\3\65\3\65\7\65\u02d0\n\65\f\65\16\65\u02d3\13\65\3\66\3\66"+ + "\3\66\3\66\5\66\u02d9\n\66\3\67\3\67\3\67\3\67\5\67\u02df\n\67\38\38\3"+ + "8\38\58\u02e5\n8\39\39\39\39\59\u02eb\n9\3:\3:\3:\3:\5:\u02f1\n:\3;\3"+ + ";\3;\3;\3;\3;\3;\7;\u02fa\n;\f;\16;\u02fd\13;\3<\3<\3<\5<\u0302\n<\3="+ + "\7=\u0305\n=\f=\16=\u0308\13=\3=\3=\3>\3>\5>\u030e\n>\3?\3?\3?\3?\3?\3"+ + "?\3?\3@\3@\3@\7@\u031a\n@\f@\16@\u031d\13@\3A\3A\3A\3A\3A\3A\7A\u0325"+ + "\nA\fA\16A\u0328\13A\3B\3B\3B\3B\3B\3B\3C\3C\3C\3D\3D\3D\3D\3E\3E\3E\3"+ + "E\3E\3E\3E\5E\u033e\nE\3F\3F\3F\3F\3F\3F\3F\3F\3F\3F\3F\3F\3F\3F\5F\u034e"+ + "\nF\3G\3G\3G\3H\3H\5H\u0355\nH\3H\3H\3I\3I\3J\3J\3J\3J\3J\3K\3K\3K\3K"+ + "\3K\3L\3L\3L\3M\3M\3M\5M\u036b\nM\7M\u036d\nM\fM\16M\u0370\13M\3M\3M\3"+ + "N\3N\5N\u0376\nN\3O\3O\5O\u037a\nO\3P\3P\3P\3P\3Q\3Q\3Q\5Q\u0383\nQ\3"+ + "Q\3Q\3Q\5Q\u0388\nQ\3Q\3Q\5Q\u038c\nQ\3Q\3Q\3R\3R\3R\3R\3R\3R\3R\3R\5"+ + "R\u0398\nR\3R\3R\3R\3R\3R\7R\u039f\nR\fR\16R\u03a2\13R\3R\3R\3R\5R\u03a7"+ + "\nR\3S\3S\3S\3S\3T\3T\3T\3T\3T\3T\3U\3U\3U\3U\3U\3U\3U\3U\3V\3V\3V\3V"+ + "\3V\7V\u03c0\nV\fV\16V\u03c3\13V\3V\3V\3V\3V\3V\3W\3W\3W\3W\3W\3W\3X\3"+ + "X\3X\6X\u03d3\nX\rX\16X\u03d4\3Y\3Y\3Y\3Y\3Z\3Z\3Z\3Z\3Z\3Z\5Z\u03e1\n"+ + "Z\5Z\u03e3\nZ\3[\3[\3[\3[\7[\u03e9\n[\f[\16[\u03ec\13[\5[\u03ee\n[\3["+ + "\3[\3[\3[\3[\5[\u03f5\n[\3\\\3\\\3\\\5\\\u03fa\n\\\3]\3]\5]\u03fe\n]\3"+ + "^\3^\3^\3^\3^\3_\3_\3_\3_\3_\7_\u040a\n_\f_\16_\u040d\13_\5_\u040f\n_"+ + "\3_\3_\3_\3_\3`\3`\5`\u0417\n`\3a\3a\5a\u041b\na\3a\3a\3a\3b\3b\5b\u0422"+ + "\nb\3b\3b\3c\3c\3d\3d\3e\3e\3e\2\2f\2\4\6\b\n\f\16\20\22\24\26\30\32\34"+ + "\36 \"$&(*,.\60\62\64\668:<>@BDFHJLNPRTVXZ\\^`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\u00b6\u00b8\u00ba\u00bc\u00be\u00c0\u00c2\u00c4\u00c6\u00c8\2\n"+ + "\4\2\b\bkk\3\2TU\3\2\13\24\4\2\6\6%/\3\2\61\62\4\2$$\63\65\4\2\n\n\u0080"+ + "\u0080\4\2?~\u0081\u0081\2\u0463\2\u00ca\3\2\2\2\4\u00d2\3\2\2\2\6\u00d8"+ + "\3\2\2\2\b\u00db\3\2\2\2\n\u00ec\3\2\2\2\f\u00fb\3\2\2\2\16\u00fd\3\2"+ + "\2\2\20\u0107\3\2\2\2\22\u0109\3\2\2\2\24\u010e\3\2\2\2\26\u0112\3\2\2"+ + "\2\30\u0118\3\2\2\2\32\u012d\3\2\2\2\34\u0133\3\2\2\2\36\u0135\3\2\2\2"+ + " \u0148\3\2\2\2\"\u0158\3\2\2\2$\u0168\3\2\2\2&\u017c\3\2\2\2(\u018b\3"+ + "\2\2\2*\u018d\3\2\2\2,\u0195\3\2\2\2.\u019b\3\2\2\2\60\u01b0\3\2\2\2\62"+ + "\u01b4\3\2\2\2\64\u01c4\3\2\2\2\66\u01cd\3\2\2\28\u01dd\3\2\2\2:\u01e6"+ + "\3\2\2\2<\u01ee\3\2\2\2>\u01f1\3\2\2\2@\u01fb\3\2\2\2B\u020d\3\2\2\2D"+ + "\u0217\3\2\2\2F\u0227\3\2\2\2H\u022c\3\2\2\2J\u0239\3\2\2\2L\u0241\3\2"+ + "\2\2N\u0250\3\2\2\2P\u0257\3\2\2\2R\u0267\3\2\2\2T\u0278\3\2\2\2V\u0281"+ + "\3\2\2\2X\u028a\3\2\2\2Z\u029d\3\2\2\2\\\u02a5\3\2\2\2^\u02ae\3\2\2\2"+ + "`\u02b2\3\2\2\2b\u02b7\3\2\2\2d\u02bf\3\2\2\2f\u02c4\3\2\2\2h\u02cc\3"+ + "\2\2\2j\u02d4\3\2\2\2l\u02da\3\2\2\2n\u02e0\3\2\2\2p\u02e6\3\2\2\2r\u02ec"+ + "\3\2\2\2t\u02f2\3\2\2\2v\u0301\3\2\2\2x\u0306\3\2\2\2z\u030d\3\2\2\2|"+ + "\u030f\3\2\2\2~\u0316\3\2\2\2\u0080\u031e\3\2\2\2\u0082\u0329\3\2\2\2"+ + "\u0084\u032f\3\2\2\2\u0086\u0332\3\2\2\2\u0088\u0336\3\2\2\2\u008a\u034d"+ + "\3\2\2\2\u008c\u034f\3\2\2\2\u008e\u0352\3\2\2\2\u0090\u0358\3\2\2\2\u0092"+ + "\u035a\3\2\2\2\u0094\u035f\3\2\2\2\u0096\u0364\3\2\2\2\u0098\u0367\3\2"+ + "\2\2\u009a\u0375\3\2\2\2\u009c\u0379\3\2\2\2\u009e\u037b\3\2\2\2\u00a0"+ + "\u037f\3\2\2\2\u00a2\u03a6\3\2\2\2\u00a4\u03a8\3\2\2\2\u00a6\u03ac\3\2"+ + "\2\2\u00a8\u03b2\3\2\2\2\u00aa\u03ba\3\2\2\2\u00ac\u03c9\3\2\2\2\u00ae"+ + "\u03cf\3\2\2\2\u00b0\u03d6\3\2\2\2\u00b2\u03e2\3\2\2\2\u00b4\u03f4\3\2"+ + "\2\2\u00b6\u03f9\3\2\2\2\u00b8\u03fd\3\2\2\2\u00ba\u03ff\3\2\2\2\u00bc"+ + "\u0404\3\2\2\2\u00be\u0414\3\2\2\2\u00c0\u041a\3\2\2\2\u00c2\u041f\3\2"+ + "\2\2\u00c4\u0425\3\2\2\2\u00c6\u0427\3\2\2\2\u00c8\u0429\3\2\2\2\u00ca"+ + "\u00cb\5\4\3\2\u00cb\u00cc\7\2\2\3\u00cc\3\3\2\2\2\u00cd\u00ce\7j\2\2"+ + "\u00ce\u00cf\7i\2\2\u00cf\u00d0\5\u00c6d\2\u00d0\u00d1\7\3\2\2\u00d1\u00d3"+ + "\3\2\2\2\u00d2\u00cd\3\2\2\2\u00d2\u00d3\3\2\2\2\u00d3\u00d6\3\2\2\2\u00d4"+ + "\u00d7\5\b\5\2\u00d5\u00d7\5\6\4\2\u00d6\u00d4\3\2\2\2\u00d6\u00d5\3\2"+ + "\2\2\u00d7\5\3\2\2\2\u00d8\u00d9\5\n\6\2\u00d9\u00da\5.\30\2\u00da\7\3"+ + "\2\2\2\u00db\u00dc\7\4\2\2\u00dc\u00dd\7\5\2\2\u00dd\u00de\7\u0088\2\2"+ + "\u00de\u00df\7\6\2\2\u00df\u00e0\5\u00c4c\2\u00e0\u00e1\7\3\2\2\u00e1"+ + "\u00e2\5\n\6\2\u00e2\t\3\2\2\2\u00e3\u00e7\5\f\7\2\u00e4\u00e7\5\16\b"+ + "\2\u00e5\u00e7\5\36\20\2\u00e6\u00e3\3\2\2\2\u00e6\u00e4\3\2\2\2\u00e6"+ + "\u00e5\3\2\2\2\u00e7\u00e8\3\2\2\2\u00e8\u00e9\7\3\2\2\u00e9\u00eb\3\2"+ + "\2\2\u00ea\u00e6\3\2\2\2\u00eb\u00ee\3\2\2\2\u00ec\u00ea\3\2\2\2\u00ec"+ + "\u00ed\3\2\2\2\u00ed\u00f4\3\2\2\2\u00ee\u00ec\3\2\2\2\u00ef\u00f0\5\20"+ + "\t\2\u00f0\u00f1\7\3\2\2\u00f1\u00f3\3\2\2\2\u00f2\u00ef\3\2\2\2\u00f3"+ + "\u00f6\3\2\2\2\u00f4\u00f2\3\2\2\2\u00f4\u00f5\3\2\2\2\u00f5\13\3\2\2"+ + "\2\u00f6\u00f4\3\2\2\2\u00f7\u00fc\5\22\n\2\u00f8\u00fc\5\24\13\2\u00f9"+ + "\u00fc\5\26\f\2\u00fa\u00fc\5\30\r\2\u00fb\u00f7\3\2\2\2\u00fb\u00f8\3"+ + "\2\2\2\u00fb\u00f9\3\2\2\2\u00fb\u00fa\3\2\2\2\u00fc\r\3\2\2\2\u00fd\u00fe"+ + "\7o\2\2\u00fe\u00ff\7\5\2\2\u00ff\u0100\7\u0088\2\2\u0100\u0101\7\6\2"+ + "\2\u0101\u0102\5\u00c4c\2\u0102\17\3\2\2\2\u0103\u0108\5$\23\2\u0104\u0108"+ + "\5 \21\2\u0105\u0108\5&\24\2\u0106\u0108\5\"\22\2\u0107\u0103\3\2\2\2"+ + "\u0107\u0104\3\2\2\2\u0107\u0105\3\2\2\2\u0107\u0106\3\2\2\2\u0108\21"+ + "\3\2\2\2\u0109\u010a\7o\2\2\u010a\u010b\7Z\2\2\u010b\u010c\7S\2\2\u010c"+ + "\u010d\5\u00c4c\2\u010d\23\3\2\2\2\u010e\u010f\7o\2\2\u010f\u0110\7\7"+ + "\2\2\u0110\u0111\t\2\2\2\u0111\25\3\2\2\2\u0112\u0113\7o\2\2\u0113\u0114"+ + "\7Z\2\2\u0114\u0115\7D\2\2\u0115\u0116\7K\2\2\u0116\u0117\t\3\2\2\u0117"+ + "\27\3\2\2\2\u0118\u011d\7o\2\2\u0119\u011a\7\t\2\2\u011a\u011e\5\32\16"+ + "\2\u011b\u011c\7Z\2\2\u011c\u011e\7\t\2\2\u011d\u0119\3\2\2\2\u011d\u011b"+ + "\3\2\2\2\u011e\u0125\3\2\2\2\u011f\u0120\5\34\17\2\u0120\u0121\7\6\2\2"+ + "\u0121\u0122\5\u00c6d\2\u0122\u0124\3\2\2\2\u0123\u011f\3\2\2\2\u0124"+ + "\u0127\3\2\2\2\u0125\u0123\3\2\2\2\u0125\u0126\3\2\2\2\u0126\31\3\2\2"+ + "\2\u0127\u0125\3\2\2\2\u0128\u012b\7\u0088\2\2\u0129\u012b\5\u00c8e\2"+ + "\u012a\u0128\3\2\2\2\u012a\u0129\3\2\2\2\u012b\u012c\3\2\2\2\u012c\u012e"+ + "\7\n\2\2\u012d\u012a\3\2\2\2\u012d\u012e\3\2\2\2\u012e\u0131\3\2\2\2\u012f"+ + "\u0132\7\u0088\2\2\u0130\u0132\5\u00c8e\2\u0131\u012f\3\2\2\2\u0131\u0130"+ + "\3\2\2\2\u0132\33\3\2\2\2\u0133\u0134\t\4\2\2\u0134\35\3\2\2\2\u0135\u0136"+ + "\7\25\2\2\u0136\u013a\7\4\2\2\u0137\u0138\7\5\2\2\u0138\u0139\7\u0088"+ + "\2\2\u0139\u013b\7\6\2\2\u013a\u0137\3\2\2\2\u013a\u013b\3\2\2\2\u013b"+ + "\u013c\3\2\2\2\u013c\u0146\5\u00c4c\2\u013d\u013e\7I\2\2\u013e\u0143\5"+ + "\u00c4c\2\u013f\u0140\7\26\2\2\u0140\u0142\5\u00c4c\2\u0141\u013f\3\2"+ + "\2\2\u0142\u0145\3\2\2\2\u0143\u0141\3\2\2\2\u0143\u0144\3\2\2\2\u0144"+ + "\u0147\3\2\2\2\u0145\u0143\3\2\2\2\u0146\u013d\3\2\2\2\u0146\u0147\3\2"+ + "\2\2\u0147\37\3\2\2\2\u0148\u0149\7o\2\2\u0149\u014a\7r\2\2\u014a\u014d"+ + "\5\u008cG\2\u014b\u014c\7H\2\2\u014c\u014e\5\u00b2Z\2\u014d\u014b\3\2"+ + "\2\2\u014d\u014e\3\2\2\2\u014e\u0156\3\2\2\2\u014f\u0150\7\27\2\2\u0150"+ + "\u0157\5\60\31\2\u0151\u0154\7\30\2\2\u0152\u0153\7\27\2\2\u0153\u0155"+ + "\5\60\31\2\u0154\u0152\3\2\2\2\u0154\u0155\3\2\2\2\u0155\u0157\3\2\2\2"+ + "\u0156\u014f\3\2\2\2\u0156\u0151\3\2\2\2\u0157!\3\2\2\2\u0158\u0159\7"+ + "o\2\2\u0159\u015a\7p\2\2\u015a\u015d\7q\2\2\u015b\u015c\7H\2\2\u015c\u015e"+ + "\5\u00b2Z\2\u015d\u015b\3\2\2\2\u015d\u015e\3\2\2\2\u015e\u0166\3\2\2"+ + "\2\u015f\u0160\7\27\2\2\u0160\u0167\5\60\31\2\u0161\u0164\7\30\2\2\u0162"+ + "\u0163\7\27\2\2\u0163\u0165\5\60\31\2\u0164\u0162\3\2\2\2\u0164\u0165"+ + "\3\2\2\2\u0165\u0167\3\2\2\2\u0166\u015f\3\2\2\2\u0166\u0161\3\2\2\2\u0167"+ + "#\3\2\2\2\u0168\u0169\7o\2\2\u0169\u016a\7\31\2\2\u016a\u016b\5\32\16"+ + "\2\u016b\u016d\7\32\2\2\u016c\u016e\5*\26\2\u016d\u016c\3\2\2\2\u016d"+ + "\u016e\3\2\2\2\u016e\u016f\3\2\2\2\u016f\u0172\7\33\2\2\u0170\u0171\7"+ + "H\2\2\u0171\u0173\5\u00b2Z\2\u0172\u0170\3\2\2\2\u0172\u0173\3\2\2\2\u0173"+ + "\u017a\3\2\2\2\u0174\u0176\7\34\2\2\u0175\u0177\5.\30\2\u0176\u0175\3"+ + "\2\2\2\u0176\u0177\3\2\2\2\u0177\u0178\3\2\2\2\u0178\u017b\7\35\2\2\u0179"+ + "\u017b\7\30\2\2\u017a\u0174\3\2\2\2\u017a\u0179\3\2\2\2\u017b%\3\2\2\2"+ + "\u017c\u017d\7o\2\2\u017d\u017e\7n\2\2\u017e\u017f\5\32\16\2\u017f\u0181"+ + "\7H\2\2\u0180\u0182\5(\25\2\u0181\u0180\3\2\2\2\u0181\u0182\3\2\2\2\u0182"+ + "\u0183\3\2\2\2\u0183\u0184\5\60\31\2\u0184\'\3\2\2\2\u0185\u0186\7\36"+ + "\2\2\u0186\u018c\7\37\2\2\u0187\u0188\7\36\2\2\u0188\u018c\7 \2\2\u0189"+ + "\u018a\7|\2\2\u018a\u018c\7!\2\2\u018b\u0185\3\2\2\2\u018b\u0187\3\2\2"+ + "\2\u018b\u0189\3\2\2\2\u018c)\3\2\2\2\u018d\u0192\5,\27\2\u018e\u018f"+ + "\7\26\2\2\u018f\u0191\5,\27\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+\3\2\2\2\u0194\u0192\3"+ + "\2\2\2\u0195\u0196\7\"\2\2\u0196\u0199\5\32\16\2\u0197\u0198\7H\2\2\u0198"+ + "\u019a\5\u00b2Z\2\u0199\u0197\3\2\2\2\u0199\u019a\3\2\2\2\u019a-\3\2\2"+ + "\2\u019b\u01a0\5\60\31\2\u019c\u019d\7\26\2\2\u019d\u019f\5\60\31\2\u019e"+ + "\u019c\3\2\2\2\u019f\u01a2\3\2\2\2\u01a0\u019e\3\2\2\2\u01a0\u01a1\3\2"+ + "\2\2\u01a1/\3\2\2\2\u01a2\u01a0\3\2\2\2\u01a3\u01b1\5\62\32\2\u01a4\u01b1"+ + "\5H%\2\u01a5\u01b1\5L\'\2\u01a6\u01b1\5P)\2\u01a7\u01b1\5T+\2\u01a8\u01b1"+ + "\5V,\2\u01a9\u01b1\5\u00a2R\2\u01aa\u01b1\5\u00a4S\2\u01ab\u01b1\5\u00a6"+ + "T\2\u01ac\u01b1\5\u00a8U\2\u01ad\u01b1\5\u00aaV\2\u01ae\u01b1\5\u00ac"+ + "W\2\u01af\u01b1\5Z.\2\u01b0\u01a3\3\2\2\2\u01b0\u01a4\3\2\2\2\u01b0\u01a5"+ + "\3\2\2\2\u01b0\u01a6\3\2\2\2\u01b0\u01a7\3\2\2\2\u01b0\u01a8\3\2\2\2\u01b0"+ + "\u01a9\3\2\2\2\u01b0\u01aa\3\2\2\2\u01b0\u01ab\3\2\2\2\u01b0\u01ac\3\2"+ + "\2\2\u01b0\u01ad\3\2\2\2\u01b0\u01ae\3\2\2\2\u01b0\u01af\3\2\2\2\u01b1"+ + "\61\3\2\2\2\u01b2\u01b5\5\64\33\2\u01b3\u01b5\58\35\2\u01b4\u01b2\3\2"+ + "\2\2\u01b4\u01b3\3\2\2\2\u01b5\u01be\3\2\2\2\u01b6\u01bd\5\64\33\2\u01b7"+ + "\u01bd\5<\37\2\u01b8\u01bd\58\35\2\u01b9\u01bd\5> \2\u01ba\u01bd\5B\""+ + "\2\u01bb\u01bd\5F$\2\u01bc\u01b6\3\2\2\2\u01bc\u01b7\3\2\2\2\u01bc\u01b8"+ + "\3\2\2\2\u01bc\u01b9\3\2\2\2\u01bc\u01ba\3\2\2\2\u01bc\u01bb\3\2\2\2\u01bd"+ + "\u01c0\3\2\2\2\u01be\u01bc\3\2\2\2\u01be\u01bf\3\2\2\2\u01bf\u01c1\3\2"+ + "\2\2\u01c0\u01be\3\2\2\2\u01c1\u01c2\7E\2\2\u01c2\u01c3\5\60\31\2\u01c3"+ + "\63\3\2\2\2\u01c4\u01c5\7?\2\2\u01c5\u01ca\5\66\34\2\u01c6\u01c7\7\26"+ + "\2\2\u01c7\u01c9\5\66\34\2\u01c8\u01c6\3\2\2\2\u01c9\u01cc\3\2\2\2\u01ca"+ + "\u01c8\3\2\2\2\u01ca\u01cb\3\2\2\2\u01cb\65\3\2\2\2\u01cc\u01ca\3\2\2"+ + "\2\u01cd\u01d0\5\u008cG\2\u01ce\u01cf\7H\2\2\u01cf\u01d1\5\u00b2Z\2\u01d0"+ + "\u01ce\3\2\2\2\u01d0\u01d1\3\2\2\2\u01d1\u01d4\3\2\2\2\u01d2\u01d3\7J"+ + "\2\2\u01d3\u01d5\7K\2\2\u01d4\u01d2\3\2\2\2\u01d4\u01d5\3\2\2\2\u01d5"+ + "\u01d8\3\2\2\2\u01d6\u01d7\7I\2\2\u01d7\u01d9\5\u008cG\2\u01d8\u01d6\3"+ + "\2\2\2\u01d8\u01d9\3\2\2\2\u01d9\u01da\3\2\2\2\u01da\u01db\7G\2\2\u01db"+ + "\u01dc\5\60\31\2\u01dc\67\3\2\2\2\u01dd\u01de\7@\2\2\u01de\u01e3\5:\36"+ + "\2\u01df\u01e0\7\26\2\2\u01e0\u01e2\5:\36\2\u01e1\u01df\3\2\2\2\u01e2"+ + "\u01e5\3\2\2\2\u01e3\u01e1\3\2\2\2\u01e3\u01e4\3\2\2\2\u01e49\3\2\2\2"+ + "\u01e5\u01e3\3\2\2\2\u01e6\u01e9\5\u008cG\2\u01e7\u01e8\7H\2\2\u01e8\u01ea"+ + "\5\u00b2Z\2\u01e9\u01e7\3\2\2\2\u01e9\u01ea\3\2\2\2\u01ea\u01eb\3\2\2"+ + "\2\u01eb\u01ec\7\27\2\2\u01ec\u01ed\5\60\31\2\u01ed;\3\2\2\2\u01ee\u01ef"+ + "\7A\2\2\u01ef\u01f0\5\60\31\2\u01f0=\3\2\2\2\u01f1\u01f2\7B\2\2\u01f2"+ + "\u01f3\7C\2\2\u01f3\u01f8\5@!\2\u01f4\u01f5\7\26\2\2\u01f5\u01f7\5@!\2"+ + "\u01f6\u01f4\3\2\2\2\u01f7\u01fa\3\2\2\2\u01f8\u01f6\3\2\2\2\u01f8\u01f9"+ + "\3\2\2\2\u01f9?\3\2\2\2\u01fa\u01f8\3\2\2\2\u01fb\u0202\5\u008cG\2\u01fc"+ + "\u01fd\7H\2\2\u01fd\u01ff\5\u00b2Z\2\u01fe\u01fc\3\2\2\2\u01fe\u01ff\3"+ + "\2\2\2\u01ff\u0200\3\2\2\2\u0200\u0201\7\27\2\2\u0201\u0203\5\60\31\2"+ + "\u0202\u01fe\3\2\2\2\u0202\u0203\3\2\2\2\u0203\u0206\3\2\2\2\u0204\u0205"+ + "\7S\2\2\u0205\u0207\5\u00c4c\2\u0206\u0204\3\2\2\2\u0206\u0207\3\2\2\2"+ + "\u0207A\3\2\2\2\u0208\u0209\7D\2\2\u0209\u020e\7C\2\2\u020a\u020b\7M\2"+ + "\2\u020b\u020c\7D\2\2\u020c\u020e\7C\2\2\u020d\u0208\3\2\2\2\u020d\u020a"+ + "\3\2\2\2\u020e\u020f\3\2\2\2\u020f\u0214\5D#\2\u0210\u0211\7\26\2\2\u0211"+ + "\u0213\5D#\2\u0212\u0210\3\2\2\2\u0213\u0216\3\2\2\2\u0214\u0212\3\2\2"+ + "\2\u0214\u0215\3\2\2\2\u0215C\3\2\2\2\u0216\u0214\3\2\2\2\u0217\u021a"+ + "\5\60\31\2\u0218\u021b\7N\2\2\u0219\u021b\7O\2\2\u021a\u0218\3\2\2\2\u021a"+ + "\u0219\3\2\2\2\u021a\u021b\3\2\2\2\u021b\u0221\3\2\2\2\u021c\u021f\7K"+ + "\2\2\u021d\u0220\7T\2\2\u021e\u0220\7U\2\2\u021f\u021d\3\2\2\2\u021f\u021e"+ + "\3\2\2\2\u0220\u0222\3\2\2\2\u0221\u021c\3\2\2\2\u0221\u0222\3\2\2\2\u0222"+ + "\u0225\3\2\2\2\u0223\u0224\7S\2\2\u0224\u0226\5\u00c4c\2\u0225\u0223\3"+ + "\2\2\2\u0225\u0226\3\2\2\2\u0226E\3\2\2\2\u0227\u0228\7L\2\2\u0228\u0229"+ + "\5\u008cG\2\u0229G\3\2\2\2\u022a\u022d\7P\2\2\u022b\u022d\7Q\2\2\u022c"+ + "\u022a\3\2\2\2\u022c\u022b\3\2\2\2\u022d\u022e\3\2\2\2\u022e\u0233\5J"+ + "&\2\u022f\u0230\7\26\2\2\u0230\u0232\5J&\2\u0231\u022f\3\2\2\2\u0232\u0235"+ + "\3\2\2\2\u0233\u0231\3\2\2\2\u0233\u0234\3\2\2\2\u0234\u0236\3\2\2\2\u0235"+ + "\u0233\3\2\2\2\u0236\u0237\7R\2\2\u0237\u0238\5\60\31\2\u0238I\3\2\2\2"+ + "\u0239\u023c\5\u008cG\2\u023a\u023b\7H\2\2\u023b\u023d\5\u00b2Z\2\u023c"+ + "\u023a\3\2\2\2\u023c\u023d\3\2\2\2\u023d\u023e\3\2\2\2\u023e\u023f\7G"+ + "\2\2\u023f\u0240\5\60\31\2\u0240K\3\2\2\2\u0241\u0242\7V\2\2\u0242\u0243"+ + "\7\32\2\2\u0243\u0244\5.\30\2\u0244\u0246\7\33\2\2\u0245\u0247\5N(\2\u0246"+ + "\u0245\3\2\2\2\u0247\u0248\3\2\2\2\u0248\u0246\3\2\2\2\u0248\u0249\3\2"+ + "\2\2\u0249\u024a\3\2\2\2\u024a\u024b\7Z\2\2\u024b\u024c\7E\2\2\u024c\u024d"+ + "\5\60\31\2\u024dM\3\2\2\2\u024e\u024f\7W\2\2\u024f\u0251\5\60\31\2\u0250"+ + "\u024e\3\2\2\2\u0251\u0252\3\2\2\2\u0252\u0250\3\2\2\2\u0252\u0253\3\2"+ + "\2\2\u0253\u0254\3\2\2\2\u0254\u0255\7E\2\2\u0255\u0256\5\60\31\2\u0256"+ + "O\3\2\2\2\u0257\u0258\7]\2\2\u0258\u0259\7\32\2\2\u0259\u025a\5.\30\2"+ + "\u025a\u025c\7\33\2\2\u025b\u025d\5R*\2\u025c\u025b\3\2\2\2\u025d\u025e"+ + "\3\2\2\2\u025e\u025c\3\2\2\2\u025e\u025f\3\2\2\2\u025f\u0260\3\2\2\2\u0260"+ + "\u0262\7Z\2\2\u0261\u0263\5\u008cG\2\u0262\u0261\3\2\2\2\u0262\u0263\3"+ + "\2\2\2\u0263\u0264\3\2\2\2\u0264\u0265\7E\2\2\u0265\u0266\5\60\31\2\u0266"+ + "Q\3\2\2\2\u0267\u026b\7W\2\2\u0268\u0269\5\u008cG\2\u0269\u026a\7H\2\2"+ + "\u026a\u026c\3\2\2\2\u026b\u0268\3\2\2\2\u026b\u026c\3\2\2\2\u026c\u026d"+ + "\3\2\2\2\u026d\u0272\5\u00b2Z\2\u026e\u026f\7#\2\2\u026f\u0271\5\u00b2"+ + "Z\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\u0273\u0275\3\2\2\2\u0274\u0272\3\2\2\2\u0275\u0276\7E"+ + "\2\2\u0276\u0277\5\60\31\2\u0277S\3\2\2\2\u0278\u0279\7F\2\2\u0279\u027a"+ + "\7\32\2\2\u027a\u027b\5.\30\2\u027b\u027c\7\33\2\2\u027c\u027d\7[\2\2"+ + "\u027d\u027e\5\60\31\2\u027e\u027f\7\\\2\2\u027f\u0280\5\60\31\2\u0280"+ + "U\3\2\2\2\u0281\u0282\7X\2\2\u0282\u0283\7\34\2\2\u0283\u0284\5.\30\2"+ + "\u0284\u0286\7\35\2\2\u0285\u0287\5X-\2\u0286\u0285\3\2\2\2\u0287\u0288"+ + "\3\2\2\2\u0288\u0286\3\2\2\2\u0288\u0289\3\2\2\2\u0289W\3\2\2\2\u028a"+ + "\u028d\7Y\2\2\u028b\u028e\7$\2\2\u028c\u028e\5\32\16\2\u028d\u028b\3\2"+ + "\2\2\u028d\u028c\3\2\2\2\u028e\u0296\3\2\2\2\u028f\u0292\7#\2\2\u0290"+ + "\u0293\7$\2\2\u0291\u0293\5\32\16\2\u0292\u0290\3\2\2\2\u0292\u0291\3"+ + "\2\2\2\u0293\u0295\3\2\2\2\u0294\u028f\3\2\2\2\u0295\u0298\3\2\2\2\u0296"+ + "\u0294\3\2\2\2\u0296\u0297\3\2\2\2\u0297\u0299\3\2\2\2\u0298\u0296\3\2"+ + "\2\2\u0299\u029a\7\34\2\2\u029a\u029b\5.\30\2\u029b\u029c\7\35\2\2\u029c"+ + "Y\3\2\2\2\u029d\u02a2\5\\/\2\u029e\u029f\7^\2\2\u029f\u02a1\5\\/\2\u02a0"+ + "\u029e\3\2\2\2\u02a1\u02a4\3\2\2\2\u02a2\u02a0\3\2\2\2\u02a2\u02a3\3\2"+ + "\2\2\u02a3[\3\2\2\2\u02a4\u02a2\3\2\2\2\u02a5\u02aa\5^\60\2\u02a6\u02a7"+ + "\7_\2\2\u02a7\u02a9\5^\60\2\u02a8\u02a6\3\2\2\2\u02a9\u02ac\3\2\2\2\u02aa"+ + "\u02a8\3\2\2\2\u02aa\u02ab\3\2\2\2\u02ab]\3\2\2\2\u02ac\u02aa\3\2\2\2"+ + "\u02ad\u02af\7`\2\2\u02ae\u02ad\3\2\2\2\u02ae\u02af\3\2\2\2\u02af\u02b0"+ + "\3\2\2\2\u02b0\u02b1\5`\61\2\u02b1_\3\2\2\2\u02b2\u02b5\5b\62\2\u02b3"+ + "\u02b4\t\5\2\2\u02b4\u02b6\5b\62\2\u02b5\u02b3\3\2\2\2\u02b5\u02b6\3\2"+ + "\2\2\u02b6a\3\2\2\2\u02b7\u02bc\5d\63\2\u02b8\u02b9\7\60\2\2\u02b9\u02bb"+ + "\5d\63\2\u02ba\u02b8\3\2\2\2\u02bb\u02be\3\2\2\2\u02bc\u02ba\3\2\2\2\u02bc"+ + "\u02bd\3\2\2\2\u02bdc\3\2\2\2\u02be\u02bc\3\2\2\2\u02bf\u02c2\5f\64\2"+ + "\u02c0\u02c1\7a\2\2\u02c1\u02c3\5f\64\2\u02c2\u02c0\3\2\2\2\u02c2\u02c3"+ + "\3\2\2\2\u02c3e\3\2\2\2\u02c4\u02c9\5h\65\2\u02c5\u02c6\t\6\2\2\u02c6"+ + "\u02c8\5h\65\2\u02c7\u02c5\3\2\2\2\u02c8\u02cb\3\2\2\2\u02c9\u02c7\3\2"+ + "\2\2\u02c9\u02ca\3\2\2\2\u02cag\3\2\2\2\u02cb\u02c9\3\2\2\2\u02cc\u02d1"+ + "\5j\66\2\u02cd\u02ce\t\7\2\2\u02ce\u02d0\5j\66\2\u02cf\u02cd\3\2\2\2\u02d0"+ + "\u02d3\3\2\2\2\u02d1\u02cf\3\2\2\2\u02d1\u02d2\3\2\2\2\u02d2i\3\2\2\2"+ + "\u02d3\u02d1\3\2\2\2\u02d4\u02d8\5l\67\2\u02d5\u02d6\7b\2\2\u02d6\u02d7"+ + "\7c\2\2\u02d7\u02d9\5\u00b2Z\2\u02d8\u02d5\3\2\2\2\u02d8\u02d9\3\2\2\2"+ + "\u02d9k\3\2\2\2\u02da\u02de\5n8\2\u02db\u02dc\7e\2\2\u02dc\u02dd\7d\2"+ + "\2\u02dd\u02df\5\u00b2Z\2\u02de\u02db\3\2\2\2\u02de\u02df\3\2\2\2\u02df"+ + "m\3\2\2\2\u02e0\u02e4\5p9\2\u02e1\u02e2\7f\2\2\u02e2\u02e3\7H\2\2\u02e3"+ + "\u02e5\5\u00b2Z\2\u02e4\u02e1\3\2\2\2\u02e4\u02e5\3\2\2\2\u02e5o\3\2\2"+ + "\2\u02e6\u02ea\5r:\2\u02e7\u02e8\7h\2\2\u02e8\u02e9\7H\2\2\u02e9\u02eb"+ + "\5\u00be`\2\u02ea\u02e7\3\2\2\2\u02ea\u02eb\3\2\2\2\u02ebq\3\2\2\2\u02ec"+ + "\u02f0\5t;\2\u02ed\u02ee\7g\2\2\u02ee\u02ef\7H\2\2\u02ef\u02f1\5\u00be"+ + "`\2\u02f0\u02ed\3\2\2\2\u02f0\u02f1\3\2\2\2\u02f1s\3\2\2\2\u02f2\u02fb"+ + "\5x=\2\u02f3\u02f4\7\6\2\2\u02f4\u02f5\7.\2\2\u02f5\u02f6\3\2\2\2\u02f6"+ + "\u02f7\5v<\2\u02f7\u02f8\5\u0098M\2\u02f8\u02fa\3\2\2\2\u02f9\u02f3\3"+ + "\2\2\2\u02fa\u02fd\3\2\2\2\u02fb\u02f9\3\2\2\2\u02fb\u02fc\3\2\2\2\u02fc"+ + "u\3\2\2\2\u02fd\u02fb\3\2\2\2\u02fe\u0302\5\32\16\2\u02ff\u0302\5\u008c"+ + "G\2\u0300\u0302\5\u008eH\2\u0301\u02fe\3\2\2\2\u0301\u02ff\3\2\2\2\u0301"+ + "\u0300\3\2\2\2\u0302w\3\2\2\2\u0303\u0305\t\6\2\2\u0304\u0303\3\2\2\2"+ + "\u0305\u0308\3\2\2\2\u0306\u0304\3\2\2\2\u0306\u0307\3\2\2\2\u0307\u0309"+ + "\3\2\2\2\u0308\u0306\3\2\2\2\u0309\u030a\5z>\2\u030ay\3\2\2\2\u030b\u030e"+ + "\5~@\2\u030c\u030e\5|?\2\u030d\u030b\3\2\2\2\u030d\u030c\3\2\2\2\u030e"+ + "{\3\2\2\2\u030f\u0310\7\66\2\2\u0310\u0311\7n\2\2\u0311\u0312\5\u00b2"+ + "Z\2\u0312\u0313\7\34\2\2\u0313\u0314\5.\30\2\u0314\u0315\7\35\2\2\u0315"+ + "}\3\2\2\2\u0316\u031b\5\u0080A\2\u0317\u0318\7\67\2\2\u0318\u031a\5\u0080"+ + "A\2\u0319\u0317\3\2\2\2\u031a\u031d\3\2\2\2\u031b\u0319\3\2\2\2\u031b"+ + "\u031c\3\2\2\2\u031c\177\3\2\2\2\u031d\u031b\3\2\2\2\u031e\u0326\5\u008a"+ + "F\2\u031f\u0325\5\u0082B\2\u0320\u0325\5\u0086D\2\u0321\u0325\5\u0088"+ + "E\2\u0322\u0325\5\u0084C\2\u0323\u0325\5\u0098M\2\u0324\u031f\3\2\2\2"+ + "\u0324\u0320\3\2\2\2\u0324\u0321\3\2\2\2\u0324\u0322\3\2\2\2\u0324\u0323"+ + "\3\2\2\2\u0325\u0328\3\2\2\2\u0326\u0324\3\2\2\2\u0326\u0327\3\2\2\2\u0327"+ + "\u0081\3\2\2\2\u0328\u0326\3\2\2\2\u0329\u032a\78\2\2\u032a\u032b\78\2"+ + "\2\u032b\u032c\5.\30\2\u032c\u032d\79\2\2\u032d\u032e\79\2\2\u032e\u0083"+ + "\3\2\2\2\u032f\u0330\78\2\2\u0330\u0331\79\2\2\u0331\u0085\3\2\2\2\u0332"+ + "\u0333\78\2\2\u0333\u0334\5.\30\2\u0334\u0335\79\2\2\u0335\u0087\3\2\2"+ + "\2\u0336\u033d\7:\2\2\u0337\u033e\5\u00c8e\2\u0338\u033e\5\u00c6d\2\u0339"+ + "\u033e\7\u0088\2\2\u033a\u033e\5\u008eH\2\u033b\u033e\5\u008cG\2\u033c"+ + "\u033e\5\u0090I\2\u033d\u0337\3\2\2\2\u033d\u0338\3\2\2\2\u033d\u0339"+ + "\3\2\2\2\u033d\u033a\3\2\2\2\u033d\u033b\3\2\2\2\u033d\u033c\3\2\2\2\u033e"+ + "\u0089\3\2\2\2\u033f\u034e\7\u0081\2\2\u0340\u034e\7l\2\2\u0341\u034e"+ + "\7m\2\2\u0342\u034e\7\u0082\2\2\u0343\u034e\5\u00c6d\2\u0344\u034e\5\u008c"+ + "G\2\u0345\u034e\5\u008eH\2\u0346\u034e\5\u0090I\2\u0347\u034e\5\u00b4"+ + "[\2\u0348\u034e\5\u0096L\2\u0349\u034e\5\u0092J\2\u034a\u034e\5\u0094"+ + "K\2\u034b\u034e\5\u00c2b\2\u034c\u034e\5\u009cO\2\u034d\u033f\3\2\2\2"+ + "\u034d\u0340\3\2\2\2\u034d\u0341\3\2\2\2\u034d\u0342\3\2\2\2\u034d\u0343"+ + "\3\2\2\2\u034d\u0344\3\2\2\2\u034d\u0345\3\2\2\2\u034d\u0346\3\2\2\2\u034d"+ + "\u0347\3\2\2\2\u034d\u0348\3\2\2\2\u034d\u0349\3\2\2\2\u034d\u034a\3\2"+ + "\2\2\u034d\u034b\3\2\2\2\u034d\u034c\3\2\2\2\u034e\u008b\3\2\2\2\u034f"+ + "\u0350\7\"\2\2\u0350\u0351\5\32\16\2\u0351\u008d\3\2\2\2\u0352\u0354\7"+ + "\32\2\2\u0353\u0355\5.\30\2\u0354\u0353\3\2\2\2\u0354\u0355\3\2\2\2\u0355"+ + "\u0356\3\2\2\2\u0356\u0357\7\33\2\2\u0357\u008f\3\2\2\2\u0358\u0359\7"+ + ";\2\2\u0359\u0091\3\2\2\2\u035a\u035b\7\b\2\2\u035b\u035c\7\34\2\2\u035c"+ + "\u035d\5.\30\2\u035d\u035e\7\35\2\2\u035e\u0093\3\2\2\2\u035f\u0360\7"+ + "k\2\2\u0360\u0361\7\34\2\2\u0361\u0362\5.\30\2\u0362\u0363\7\35\2\2\u0363"+ + "\u0095\3\2\2\2\u0364\u0365\5\32\16\2\u0365\u0366\5\u0098M\2\u0366\u0097"+ + "\3\2\2\2\u0367\u036e\7\32\2\2\u0368\u036a\5\u009aN\2\u0369\u036b\7\26"+ + "\2\2\u036a\u0369\3\2\2\2\u036a\u036b\3\2\2\2\u036b\u036d\3\2\2\2\u036c"+ + "\u0368\3\2\2\2\u036d\u0370\3\2\2\2\u036e\u036c\3\2\2\2\u036e\u036f\3\2"+ + "\2\2\u036f\u0371\3\2\2\2\u0370\u036e\3\2\2\2\u0371\u0372\7\33\2\2\u0372"+ + "\u0099\3\2\2\2\u0373\u0376\5\60\31\2\u0374\u0376\7\u0080\2\2\u0375\u0373"+ + "\3\2\2\2\u0375\u0374\3\2\2\2\u0376\u009b\3\2\2\2\u0377\u037a\5\u009eP"+ + "\2\u0378\u037a\5\u00a0Q\2\u0379\u0377\3\2\2\2\u0379\u0378\3\2\2\2\u037a"+ + "\u009d\3\2\2\2\u037b\u037c\5\32\16\2\u037c\u037d\7<\2\2\u037d\u037e\7"+ + "\u0082\2\2\u037e\u009f\3\2\2\2\u037f\u0380\7\31\2\2\u0380\u0382\7\32\2"+ + "\2\u0381\u0383\5*\26\2\u0382\u0381\3\2\2\2\u0382\u0383\3\2\2\2\u0383\u0384"+ + "\3\2\2\2\u0384\u0387\7\33\2\2\u0385\u0386\7H\2\2\u0386\u0388\5\u00b2Z"+ + "\2\u0387\u0385\3\2\2\2\u0387\u0388\3\2\2\2\u0388\u0389\3\2\2\2\u0389\u038b"+ + "\7\34\2\2\u038a\u038c\5.\30\2\u038b\u038a\3\2\2\2\u038b\u038c\3\2\2\2"+ + "\u038c\u038d\3\2\2\2\u038d\u038e\7\35\2\2\u038e\u00a1\3\2\2\2\u038f\u0390"+ + "\7s\2\2\u0390\u0391\7|\2\2\u0391\u0392\5\60\31\2\u0392\u0393\7z\2\2\u0393"+ + "\u0397\5\60\31\2\u0394\u0395\7I\2\2\u0395\u0396\7~\2\2\u0396\u0398\5\60"+ + "\31\2\u0397\u0394\3\2\2\2\u0397\u0398\3\2\2\2\u0398\u03a7\3\2\2\2\u0399"+ + "\u039a\7s\2\2\u039a\u039b\7|\2\2\u039b\u03a0\5\u00c0a\2\u039c\u039d\7"+ + "\26\2\2\u039d\u039f\5\u00c0a\2\u039e\u039c\3\2\2\2\u039f\u03a2\3\2\2\2"+ + "\u03a0\u039e\3\2\2\2\u03a0\u03a1\3\2\2\2\u03a1\u03a3\3\2\2\2\u03a2\u03a0"+ + "\3\2\2\2\u03a3\u03a4\7z\2\2\u03a4\u03a5\5\60\31\2\u03a5\u03a7\3\2\2\2"+ + "\u03a6\u038f\3\2\2\2\u03a6\u0399\3\2\2\2\u03a7\u00a3\3\2\2\2\u03a8\u03a9"+ + "\7t\2\2\u03a9\u03aa\7|\2\2\u03aa\u03ab\5\u00aeX\2\u03ab\u00a5\3\2\2\2"+ + "\u03ac\u03ad\7u\2\2\u03ad\u03ae\7|\2\2\u03ae\u03af\5\u00aeX\2\u03af\u03b0"+ + "\7H\2\2\u03b0\u03b1\5\60\31\2\u03b1\u00a7\3\2\2\2\u03b2\u03b3\7v\2\2\u03b3"+ + "\u03b4\7|\2\2\u03b4\u03b5\7{\2\2\u03b5\u03b6\7c\2\2\u03b6\u03b7\5\u00ae"+ + "X\2\u03b7\u03b8\7}\2\2\u03b8\u03b9\5\60\31\2\u03b9\u00a9\3\2\2\2\u03ba"+ + "\u03bb\7w\2\2\u03bb\u03bc\7|\2\2\u03bc\u03c1\5\u00b0Y\2\u03bd\u03be\7"+ + "\26\2\2\u03be\u03c0\5\u00b0Y\2\u03bf\u03bd\3\2\2\2\u03c0\u03c3\3\2\2\2"+ + "\u03c1\u03bf\3\2\2\2\u03c1\u03c2\3\2\2\2\u03c2\u03c4\3\2\2\2\u03c3\u03c1"+ + "\3\2\2\2\u03c4\u03c5\7x\2\2\u03c5\u03c6\5\60\31\2\u03c6\u03c7\7E\2\2\u03c7"+ + "\u03c8\5\60\31\2\u03c8\u00ab\3\2\2\2\u03c9\u03ca\7y\2\2\u03ca\u03cb\7"+ + "|\2\2\u03cb\u03cc\5\60\31\2\u03cc\u03cd\7z\2\2\u03cd\u03ce\5\60\31\2\u03ce"+ + "\u00ad\3\2\2\2\u03cf\u03d2\5\u008aF\2\u03d0\u03d3\5\u0082B\2\u03d1\u03d3"+ + "\5\u0088E\2\u03d2\u03d0\3\2\2\2\u03d2\u03d1\3\2\2\2\u03d3\u03d4\3\2\2"+ + "\2\u03d4\u03d2\3\2\2\2\u03d4\u03d5\3\2\2\2\u03d5\u00af\3\2\2\2\u03d6\u03d7"+ + "\5\u008cG\2\u03d7\u03d8\7\27\2\2\u03d8\u03d9\5\60\31\2\u03d9\u00b1\3\2"+ + "\2\2\u03da\u03db\7\32\2\2\u03db\u03e3\7\33\2\2\u03dc\u03e0\5\u00b6\\\2"+ + "\u03dd\u03e1\7\u0080\2\2\u03de\u03e1\7$\2\2\u03df\u03e1\7\61\2\2\u03e0"+ + "\u03dd\3\2\2\2\u03e0\u03de\3\2\2\2\u03e0\u03df\3\2\2\2\u03e0\u03e1\3\2"+ + "\2\2\u03e1\u03e3\3\2\2\2\u03e2\u03da\3\2\2\2\u03e2\u03dc\3\2\2\2\u03e3"+ + "\u00b3\3\2\2\2\u03e4\u03ed\7\34\2\2\u03e5\u03ea\5\u00c0a\2\u03e6\u03e7"+ + "\7\26\2\2\u03e7\u03e9\5\u00c0a\2\u03e8\u03e6\3\2\2\2\u03e9\u03ec\3\2\2"+ + "\2\u03ea\u03e8\3\2\2\2\u03ea\u03eb\3\2\2\2\u03eb\u03ee\3\2\2\2\u03ec\u03ea"+ + "\3\2\2\2\u03ed\u03e5\3\2\2\2\u03ed\u03ee\3\2\2\2\u03ee\u03ef\3\2\2\2\u03ef"+ + "\u03f5\7\35\2\2\u03f0\u03f1\7=\2\2\u03f1\u03f2\5.\30\2\u03f2\u03f3\7>"+ + "\2\2\u03f3\u03f5\3\2\2\2\u03f4\u03e4\3\2\2\2\u03f4\u03f0\3\2\2\2\u03f5"+ + "\u00b5\3\2\2\2\u03f6\u03fa\5\32\16\2\u03f7\u03fa\7\u0081\2\2\u03f8\u03fa"+ + "\5\u00b8]\2\u03f9\u03f6\3\2\2\2\u03f9\u03f7\3\2\2\2\u03f9\u03f8\3\2\2"+ + "\2\u03fa\u00b7\3\2\2\2\u03fb\u03fe\5\u00ba^\2\u03fc\u03fe\5\u00bc_\2\u03fd"+ + "\u03fb\3\2\2\2\u03fd\u03fc\3\2\2\2\u03fe\u00b9\3\2\2\2\u03ff\u0400\7\31"+ + "\2\2\u0400\u0401\7\32\2\2\u0401\u0402\7$\2\2\u0402\u0403\7\33\2\2\u0403"+ + "\u00bb\3\2\2\2\u0404\u0405\7\31\2\2\u0405\u040e\7\32\2\2\u0406\u040b\5"+ + "\u00b2Z\2\u0407\u0408\7\26\2\2\u0408\u040a\5\u00b2Z\2\u0409\u0407\3\2"+ + "\2\2\u040a\u040d\3\2\2\2\u040b\u0409\3\2\2\2\u040b\u040c\3\2\2\2\u040c"+ + "\u040f\3\2\2\2\u040d\u040b\3\2\2\2\u040e\u0406\3\2\2\2\u040e\u040f\3\2"+ + "\2\2\u040f\u0410\3\2\2\2\u0410\u0411\7\33\2\2\u0411\u0412\7H\2\2\u0412"+ + "\u0413\5\u00b2Z\2\u0413\u00bd\3\2\2\2\u0414\u0416\5\u00b6\\\2\u0415\u0417"+ + "\7\u0080\2\2\u0416\u0415\3\2\2\2\u0416\u0417\3\2\2\2\u0417\u00bf\3\2\2"+ + "\2\u0418\u041b\5\60\31\2\u0419\u041b\7\u0088\2\2\u041a\u0418\3\2\2\2\u041a"+ + "\u0419\3\2\2\2\u041b\u041c\3\2\2\2\u041c\u041d\t\b\2\2\u041d\u041e\5\60"+ + "\31\2\u041e\u00c1\3\2\2\2\u041f\u0421\78\2\2\u0420\u0422\5.\30\2\u0421"+ + "\u0420\3\2\2\2\u0421\u0422\3\2\2\2\u0422\u0423\3\2\2\2\u0423\u0424\79"+ + "\2\2\u0424\u00c3\3\2\2\2\u0425\u0426\5\u00c6d\2\u0426\u00c5\3\2\2\2\u0427"+ + "\u0428\7\177\2\2\u0428\u00c7\3\2\2\2\u0429\u042a\t\t\2\2\u042a\u00c9\3"+ + "\2\2\2q\u00d2\u00d6\u00e6\u00ec\u00f4\u00fb\u0107\u011d\u0125\u012a\u012d"+ + "\u0131\u013a\u0143\u0146\u014d\u0154\u0156\u015d\u0164\u0166\u016d\u0172"+ + "\u0176\u017a\u0181\u018b\u0192\u0199\u01a0\u01b0\u01b4\u01bc\u01be\u01ca"+ + "\u01d0\u01d4\u01d8\u01e3\u01e9\u01f8\u01fe\u0202\u0206\u020d\u0214\u021a"+ + "\u021f\u0221\u0225\u022c\u0233\u023c\u0248\u0252\u025e\u0262\u026b\u0272"+ + "\u0288\u028d\u0292\u0296\u02a2\u02aa\u02ae\u02b5\u02bc\u02c2\u02c9\u02d1"+ + "\u02d8\u02de\u02e4\u02ea\u02f0\u02fb\u0301\u0306\u030d\u031b\u0324\u0326"+ + "\u033d\u034d\u0354\u036a\u036e\u0375\u0379\u0382\u0387\u038b\u0397\u03a0"+ + "\u03a6\u03c1\u03d2\u03d4\u03e0\u03e2\u03ea\u03ed\u03f4\u03f9\u03fd\u040b"+ + "\u040e\u0416\u041a\u0421"; 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 625fa73740..286d81a971 100644 --- a/src/main/java/org/rumbledb/parser/JsoniqVisitor.java +++ b/src/main/java/org/rumbledb/parser/JsoniqVisitor.java @@ -1,4 +1,4 @@ -// Generated from ./src/main/java/org/rumbledb/parser/Jsoniq.g4 by ANTLR 4.8 +// Generated from ./src/main/java/org/rumbledb/parser/Jsoniq.g4 by ANTLR 4.7 // Java header package org.rumbledb.parser; @@ -493,6 +493,54 @@ public interface JsoniqVisitor extends ParseTreeVisitor { * @return the visitor result */ T visitInlineFunctionExpr(JsoniqParser.InlineFunctionExprContext ctx); + /** + * Visit a parse tree produced by {@link JsoniqParser#insertExpr}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitInsertExpr(JsoniqParser.InsertExprContext ctx); + /** + * Visit a parse tree produced by {@link JsoniqParser#deleteExpr}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitDeleteExpr(JsoniqParser.DeleteExprContext ctx); + /** + * Visit a parse tree produced by {@link JsoniqParser#renameExpr}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitRenameExpr(JsoniqParser.RenameExprContext ctx); + /** + * Visit a parse tree produced by {@link JsoniqParser#replaceExpr}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitReplaceExpr(JsoniqParser.ReplaceExprContext ctx); + /** + * Visit a parse tree produced by {@link JsoniqParser#transformExpr}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitTransformExpr(JsoniqParser.TransformExprContext ctx); + /** + * Visit a parse tree produced by {@link JsoniqParser#appendExpr}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitAppendExpr(JsoniqParser.AppendExprContext ctx); + /** + * Visit a parse tree produced by {@link JsoniqParser#updateLocator}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitUpdateLocator(JsoniqParser.UpdateLocatorContext ctx); + /** + * Visit a parse tree produced by {@link JsoniqParser#copyDecl}. + * @param ctx the parse tree + * @return the visitor result + */ + T visitCopyDecl(JsoniqParser.CopyDeclContext ctx); /** * Visit a parse tree produced by {@link JsoniqParser#sequenceType}. * @param ctx the parse tree From 64fa017e3363887972ed367f5fece22930e419f6 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sun, 26 Mar 2023 14:59:18 +0200 Subject: [PATCH 033/119] Maven spotless apply --- .../compiler/ExecutionModeVisitor.java | 4 +- .../ExpressionClassificationVisitor.java | 225 ++++++++++++++---- .../rumbledb/compiler/InferTypeVisitor.java | 12 +- .../compiler/StaticContextVisitor.java | 6 +- .../rumbledb/compiler/TranslationVisitor.java | 46 ++-- .../org/rumbledb/compiler/VisitorHelpers.java | 2 +- .../expressions/update/AppendExpression.java | 11 +- .../expressions/update/CopyDeclaration.java | 7 +- .../expressions/update/DeleteExpression.java | 13 +- .../expressions/update/InsertExpression.java | 16 +- .../expressions/update/RenameExpression.java | 17 +- .../expressions/update/ReplaceExpression.java | 16 +- .../update/TransformExpression.java | 26 +- 13 files changed, 271 insertions(+), 130 deletions(-) diff --git a/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java b/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java index abc9d7c85c..44cda153ac 100644 --- a/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java +++ b/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java @@ -441,8 +441,8 @@ public StaticContext visitTransformExpression(TransformExpression expression, St this.visit(copyDecl.getSourceExpression(), null); // first pass. argument.setVariableStorageMode( - copyDecl.getVariableName(), - expression.getVariableHighestStorageMode(this.visitorConfig) + copyDecl.getVariableName(), + expression.getVariableHighestStorageMode(this.visitorConfig) ); } expression.initHighestExecutionMode(this.visitorConfig); diff --git a/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java b/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java index 7d463eaa73..ac62249090 100644 --- a/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java @@ -1,6 +1,5 @@ package org.rumbledb.compiler; -import org.rumbledb.context.StaticContext; import org.rumbledb.exceptions.InvalidUpdatingExpressionPositionException; import org.rumbledb.exceptions.SimpleExpressionMustBeVacuousException; import org.rumbledb.expressions.*; @@ -28,7 +27,10 @@ protected ExpressionClassification defaultAction(Node node, ExpressionClassifica } if (expressionClassification.isUpdating()) { - throw new InvalidUpdatingExpressionPositionException("Operand of expression is Updating when it should be Simple or Vacuous", node.getMetadata()); + throw new InvalidUpdatingExpressionPositionException( + "Operand of expression is Updating when it should be Simple or Vacuous", + node.getMetadata() + ); } Expression expression = (Expression) node; expression.setExpressionClassification(expressionClassification); @@ -37,26 +39,35 @@ protected ExpressionClassification defaultAction(Node node, ExpressionClassifica @Override public ExpressionClassification visitDescendants(Node node, ExpressionClassification argument) { - List expressionClassifications = node.getChildren().stream().map(child -> this.visit(child, argument)).collect(Collectors.toList()); - ExpressionClassification result = expressionClassifications.stream().anyMatch(ExpressionClassification::isUpdating) ? - ExpressionClassification.UPDATING : - ExpressionClassification.SIMPLE; - -// if (result.isUpdating()) { -// throw new InvalidUpdatingExpressionPositionException("Operand of expression is Updating when it should be Simple or Vacuous", node.getMetadata()); -// } + List expressionClassifications = node.getChildren() + .stream() + .map(child -> this.visit(child, argument)) + .collect(Collectors.toList()); + ExpressionClassification result = expressionClassifications.stream() + .anyMatch(ExpressionClassification::isUpdating) + ? ExpressionClassification.UPDATING + : ExpressionClassification.SIMPLE; return result; } @Override - public ExpressionClassification visitCommaExpression(CommaExpression expression, ExpressionClassification argument) { - List results = expression.getChildren().stream().map(n -> this.visit(n, argument)).collect(Collectors.toList()); + public ExpressionClassification visitCommaExpression( + CommaExpression expression, + ExpressionClassification argument + ) { + List results = expression.getChildren() + .stream() + .map(n -> this.visit(n, argument)) + .collect(Collectors.toList()); boolean anyUpdating = results.stream().anyMatch(ExpressionClassification::isUpdating); boolean allUpdatingOrVacuous = results.stream().allMatch(e -> e.isVacuous() || e.isUpdating()); if (anyUpdating && !allUpdatingOrVacuous) { - throw new InvalidUpdatingExpressionPositionException("All expressions in Comma separated expressions must only be Simple expressions or only be Updating/Vacuous expressions", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException( + "All expressions in Comma separated expressions must only be Simple expressions or only be Updating/Vacuous expressions", + expression.getMetadata() + ); } if (anyUpdating) { @@ -73,7 +84,10 @@ public ExpressionClassification visitCommaExpression(CommaExpression expression, // Region FLWOR @Override - public ExpressionClassification visitFlowrExpression(FlworExpression expression, ExpressionClassification argument) { + public ExpressionClassification visitFlowrExpression( + FlworExpression expression, + ExpressionClassification argument + ) { Clause clause = expression.getReturnClause().getFirstClause(); ExpressionClassification result = argument; while (clause != null) { @@ -90,7 +104,10 @@ public ExpressionClassification visitFlowrExpression(FlworExpression expression, public ExpressionClassification visitForClause(ForClause expression, ExpressionClassification argument) { ExpressionClassification result = this.visit(expression.getExpression(), argument); if (result.isUpdating()) { - throw new InvalidUpdatingExpressionPositionException("Expression in For Clause cannot be updating", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException( + "Expression in For Clause cannot be updating", + expression.getMetadata() + ); } return result; } @@ -99,7 +116,10 @@ public ExpressionClassification visitForClause(ForClause expression, ExpressionC public ExpressionClassification visitLetClause(LetClause expression, ExpressionClassification argument) { ExpressionClassification result = this.visit(expression.getExpression(), argument); if (result.isUpdating()) { - throw new InvalidUpdatingExpressionPositionException("Expression in Let Clause cannot be updating", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException( + "Expression in Let Clause cannot be updating", + expression.getMetadata() + ); } return result; } @@ -114,7 +134,10 @@ public ExpressionClassification visitGroupByClause(GroupByClause expression, Exp public ExpressionClassification visitOrderByClause(OrderByClause expression, ExpressionClassification argument) { ExpressionClassification result = this.visitDescendants(expression, argument); if (result.isUpdating()) { - throw new InvalidUpdatingExpressionPositionException("Expressions in Order By Clause cannot be updating", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException( + "Expressions in Order By Clause cannot be updating", + expression.getMetadata() + ); } return result; } @@ -123,7 +146,10 @@ public ExpressionClassification visitOrderByClause(OrderByClause expression, Exp public ExpressionClassification visitWhereClause(WhereClause expression, ExpressionClassification argument) { ExpressionClassification result = this.visitDescendants(expression, argument); if (result.isUpdating()) { - throw new InvalidUpdatingExpressionPositionException("Expression in Where Clause cannot be updating", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException( + "Expression in Where Clause cannot be updating", + expression.getMetadata() + ); } return result; } @@ -147,20 +173,30 @@ public ExpressionClassification visitReturnClause(ReturnClause expression, Expre // Region Control @Override - public ExpressionClassification visitConditionalExpression(ConditionalExpression expression, ExpressionClassification argument) { + public ExpressionClassification visitConditionalExpression( + ConditionalExpression expression, + ExpressionClassification argument + ) { ExpressionClassification condResult = this.visit(expression.getCondition(), argument); if (condResult.isUpdating()) { - throw new InvalidUpdatingExpressionPositionException("Condition expression in Conditional expression cannot be updating", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException( + "Condition expression in Conditional expression cannot be updating", + expression.getMetadata() + ); } ExpressionClassification thenResult = this.visit(expression.getBranch(), argument); ExpressionClassification elseResult = this.visit(expression.getElseBranch(), argument); boolean oneUpdating = thenResult.isUpdating() || elseResult.isUpdating(); - boolean bothUpdatingOrVacuous = (thenResult.isUpdating() || thenResult.isVacuous()) && (elseResult.isVacuous()|| elseResult.isUpdating()); + boolean bothUpdatingOrVacuous = (thenResult.isUpdating() || thenResult.isVacuous()) + && (elseResult.isVacuous() || elseResult.isUpdating()); if (oneUpdating && !bothUpdatingOrVacuous) { - throw new InvalidUpdatingExpressionPositionException("Both branch expressions in Conditional expression must only be Simple expressions or only be Updating/Vacuous expressions", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException( + "Both branch expressions in Conditional expression must only be Simple expressions or only be Updating/Vacuous expressions", + expression.getMetadata() + ); } if (oneUpdating) { @@ -175,15 +211,24 @@ public ExpressionClassification visitConditionalExpression(ConditionalExpression } @Override - public ExpressionClassification visitSwitchExpression(SwitchExpression expression, ExpressionClassification argument) { + public ExpressionClassification visitSwitchExpression( + SwitchExpression expression, + ExpressionClassification argument + ) { return super.visitSwitchExpression(expression, argument); } @Override - public ExpressionClassification visitTypeSwitchExpression(TypeSwitchExpression expression, ExpressionClassification argument) { + public ExpressionClassification visitTypeSwitchExpression( + TypeSwitchExpression expression, + ExpressionClassification argument + ) { ExpressionClassification condResult = this.visit(expression.getTestCondition(), argument); if (condResult.isUpdating()) { - throw new InvalidUpdatingExpressionPositionException("Condition expression in Type Switch expression cannot be updating", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException( + "Condition expression in Type Switch expression cannot be updating", + expression.getMetadata() + ); } List branchResults = new ArrayList<>(); @@ -193,7 +238,10 @@ public ExpressionClassification visitTypeSwitchExpression(TypeSwitchExpression e } boolean anyUpdating = branchResults.stream().anyMatch(ExpressionClassification::isUpdating); if (anyUpdating && !branchResults.stream().allMatch(e -> e.isUpdating() || e.isVacuous())) { - throw new InvalidUpdatingExpressionPositionException("All branch expressions in Type Switch expression must only be Simple expressions or only be Updating/Vacuous expressions", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException( + "All branch expressions in Type Switch expression must only be Simple expressions or only be Updating/Vacuous expressions", + expression.getMetadata() + ); } if (anyUpdating) { @@ -212,7 +260,10 @@ public ExpressionClassification visitTypeSwitchExpression(TypeSwitchExpression e // Region Primary @Override - public ExpressionClassification visitFunctionCall(FunctionCallExpression expression, ExpressionClassification argument) { + public ExpressionClassification visitFunctionCall( + FunctionCallExpression expression, + ExpressionClassification argument + ) { // TODO: Make vacuous if call to fn:error? return super.visitFunctionCall(expression, argument); } @@ -224,15 +275,24 @@ public ExpressionClassification visitFunctionCall(FunctionCallExpression express // Region Basic Updating @Override - public ExpressionClassification visitDeleteExpression(DeleteExpression expression, ExpressionClassification argument) { + public ExpressionClassification visitDeleteExpression( + DeleteExpression expression, + ExpressionClassification argument + ) { ExpressionClassification mainResult = this.visit(expression.getMainExpression(), argument); if (!mainResult.isSimple()) { - throw new InvalidUpdatingExpressionPositionException("Main expression in Delete expression must be Simple", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException( + "Main expression in Delete expression must be Simple", + expression.getMetadata() + ); } ExpressionClassification locatorResult = this.visit(expression.getLocatorExpression(), argument); if (!locatorResult.isSimple()) { - throw new InvalidUpdatingExpressionPositionException("Locator expression in Delete expression must be Simple", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException( + "Locator expression in Delete expression must be Simple", + expression.getMetadata() + ); } expression.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); @@ -240,20 +300,32 @@ public ExpressionClassification visitDeleteExpression(DeleteExpression expressio } @Override - public ExpressionClassification visitRenameExpression(RenameExpression expression, ExpressionClassification argument) { + public ExpressionClassification visitRenameExpression( + RenameExpression expression, + ExpressionClassification argument + ) { ExpressionClassification mainResult = this.visit(expression.getMainExpression(), argument); if (!mainResult.isSimple()) { - throw new InvalidUpdatingExpressionPositionException("Main expression in Rename expression must be Simple", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException( + "Main expression in Rename expression must be Simple", + expression.getMetadata() + ); } ExpressionClassification locatorResult = this.visit(expression.getLocatorExpression(), argument); if (!locatorResult.isSimple()) { - throw new InvalidUpdatingExpressionPositionException("Locator expression in Rename expression must be Simple", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException( + "Locator expression in Rename expression must be Simple", + expression.getMetadata() + ); } ExpressionClassification replacerResult = this.visit(expression.getNameExpression(), argument); if (!replacerResult.isSimple()) { - throw new InvalidUpdatingExpressionPositionException("Replacer expression in Rename expression must be Simple", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException( + "Replacer expression in Rename expression must be Simple", + expression.getMetadata() + ); } expression.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); @@ -261,20 +333,32 @@ public ExpressionClassification visitRenameExpression(RenameExpression expressio } @Override - public ExpressionClassification visitReplaceExpression(ReplaceExpression expression, ExpressionClassification argument) { + public ExpressionClassification visitReplaceExpression( + ReplaceExpression expression, + ExpressionClassification argument + ) { ExpressionClassification mainResult = this.visit(expression.getMainExpression(), argument); if (!mainResult.isSimple()) { - throw new InvalidUpdatingExpressionPositionException("Main expression in Replace expression must be Simple", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException( + "Main expression in Replace expression must be Simple", + expression.getMetadata() + ); } ExpressionClassification locatorResult = this.visit(expression.getLocatorExpression(), argument); if (!locatorResult.isSimple()) { - throw new InvalidUpdatingExpressionPositionException("Locator expression in Replace expression must be Simple", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException( + "Locator expression in Replace expression must be Simple", + expression.getMetadata() + ); } ExpressionClassification replacerResult = this.visit(expression.getReplacerExpression(), argument); if (!replacerResult.isSimple()) { - throw new InvalidUpdatingExpressionPositionException("Replacer expression in Replace expression must be Simple", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException( + "Replacer expression in Replace expression must be Simple", + expression.getMetadata() + ); } expression.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); @@ -282,21 +366,33 @@ public ExpressionClassification visitReplaceExpression(ReplaceExpression express } @Override - public ExpressionClassification visitInsertExpression(InsertExpression expression, ExpressionClassification argument) { + public ExpressionClassification visitInsertExpression( + InsertExpression expression, + ExpressionClassification argument + ) { ExpressionClassification mainResult = this.visit(expression.getMainExpression(), argument); if (!mainResult.isSimple()) { - throw new InvalidUpdatingExpressionPositionException("Main expression in Insert expression must be Simple", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException( + "Main expression in Insert expression must be Simple", + expression.getMetadata() + ); } ExpressionClassification toInsertResult = this.visit(expression.getToInsertExpression(), argument); if (!toInsertResult.isSimple()) { - throw new InvalidUpdatingExpressionPositionException("toInsert expression in Insert expression must be Simple", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException( + "toInsert expression in Insert expression must be Simple", + expression.getMetadata() + ); } if (expression.hasPositionExpression()) { ExpressionClassification positionResult = this.visit(expression.getPositionExpression(), argument); if (!positionResult.isSimple()) { - throw new InvalidUpdatingExpressionPositionException("Position expression in Insert expression must be Simple", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException( + "Position expression in Insert expression must be Simple", + expression.getMetadata() + ); } } @@ -305,15 +401,24 @@ public ExpressionClassification visitInsertExpression(InsertExpression expressio } @Override - public ExpressionClassification visitAppendExpression(AppendExpression expression, ExpressionClassification argument) { + public ExpressionClassification visitAppendExpression( + AppendExpression expression, + ExpressionClassification argument + ) { ExpressionClassification arrayResult = this.visit(expression.getArrayExpression(), argument); if (!arrayResult.isSimple()) { - throw new InvalidUpdatingExpressionPositionException("Array expression in Append expression must be Simple", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException( + "Array expression in Append expression must be Simple", + expression.getMetadata() + ); } ExpressionClassification toAppendResult = this.visit(expression.getToAppendExpression(), argument); if (!toAppendResult.isSimple()) { - throw new InvalidUpdatingExpressionPositionException("toAppend expression in Append expression must be Simple", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException( + "toAppend expression in Append expression must be Simple", + expression.getMetadata() + ); } expression.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); @@ -321,23 +426,35 @@ public ExpressionClassification visitAppendExpression(AppendExpression expressio } @Override - public ExpressionClassification visitTransformExpression(TransformExpression expression, ExpressionClassification argument) { + public ExpressionClassification visitTransformExpression( + TransformExpression expression, + ExpressionClassification argument + ) { for (CopyDeclaration copyDecl : expression.getCopyDeclarations()) { ExpressionClassification copyDeclResult = this.visit(copyDecl.getSourceExpression(), argument); if (!copyDeclResult.isSimple()) { - throw new InvalidUpdatingExpressionPositionException("Source expression in Copy Declaration must be Simple", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException( + "Source expression in Copy Declaration must be Simple", + expression.getMetadata() + ); } } ExpressionClassification modifyResult = this.visit(expression.getModifyExpression(), argument); if (!(modifyResult.isUpdating() || modifyResult.isVacuous())) { - throw new SimpleExpressionMustBeVacuousException("Modify expression must be Updating or Vacuous", expression.getMetadata()); + throw new SimpleExpressionMustBeVacuousException( + "Modify expression must be Updating or Vacuous", + expression.getMetadata() + ); } ExpressionClassification returnResult = this.visit(expression.getReturnExpression(), argument); if (!returnResult.isSimple()) { - throw new InvalidUpdatingExpressionPositionException("Return expression of Transform expression must be Simple", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException( + "Return expression of Transform expression must be Simple", + expression.getMetadata() + ); } expression.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); @@ -348,14 +465,20 @@ public ExpressionClassification visitTransformExpression(TransformExpression exp @Override - public ExpressionClassification visitVariableDeclaration(VariableDeclaration expression, ExpressionClassification argument) { + public ExpressionClassification visitVariableDeclaration( + VariableDeclaration expression, + ExpressionClassification argument + ) { if (expression.getExpression() == null) { return argument; } ExpressionClassification result = this.visit(expression.getExpression(), argument); if (!result.isSimple()) { - throw new InvalidUpdatingExpressionPositionException("Initialising expression in variable declaration must be Simple", expression.getMetadata()); + throw new InvalidUpdatingExpressionPositionException( + "Initialising expression in variable declaration must be Simple", + expression.getMetadata() + ); } return ExpressionClassification.SIMPLE; } diff --git a/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java b/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java index 27b6f479b8..3332eaa865 100644 --- a/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java +++ b/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java @@ -712,12 +712,12 @@ public StaticContext visitTransformExpression(TransformExpression expression, St inferredType = declaredType; } checkAndUpdateVariableStaticType( - declaredType, - inferredType, - argument, - expression.getClass().getSimpleName(), - copyDecl.getVariableName(), - expression.getMetadata() + declaredType, + inferredType, + argument, + expression.getClass().getSimpleName(), + copyDecl.getVariableName(), + expression.getMetadata() ); } visit(expression.getModifyExpression(), argument); diff --git a/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java b/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java index 9253564e7d..3d7fcd1921 100644 --- a/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java +++ b/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java @@ -336,9 +336,9 @@ public StaticContext visitTransformExpression(TransformExpression expression, St this.visit(copyDecl.getSourceExpression(), argument); // first pass. argument.addVariable( - copyDecl.getVariableName(), - copyDecl.getSourceSequenceType(), - expression.getMetadata() + copyDecl.getVariableName(), + copyDecl.getSourceSequenceType(), + expression.getMetadata() ); } diff --git a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java index 1be368b06e..6b3cb1a64b 100644 --- a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java @@ -1161,8 +1161,7 @@ public Node visitInsertExpr(JsoniqParser.InsertExprContext ctx) { if (ctx.pos_expr != null) { posExpr = (Expression) this.visitExprSingle(ctx.pos_expr); } - } - else { + } else { throw new OurBadException("Unrecognised expression to insert in Insert Expression"); } Expression mainExpr = (Expression) this.visitExprSingle(ctx.main_expr); @@ -1184,7 +1183,13 @@ public Node visitRenameExpr(JsoniqParser.RenameExprContext ctx) { Expression locatorExpression = getLocatorExpressionFromUpdateLocatorContext(ctx.updateLocator()); UpdateLocatorKind locatorKind = getLocatorKindFromUpdateLocatorContext(ctx.updateLocator()); Expression nameExpression = (Expression) this.visitExprSingle(ctx.name_expr); - return new RenameExpression(mainExpression, locatorExpression, nameExpression, locatorKind, createMetadataFromContext(ctx)); + return new RenameExpression( + mainExpression, + locatorExpression, + nameExpression, + locatorKind, + createMetadataFromContext(ctx) + ); } @Override @@ -1193,18 +1198,25 @@ public Node visitReplaceExpr(JsoniqParser.ReplaceExprContext ctx) { Expression locatorExpression = getLocatorExpressionFromUpdateLocatorContext(ctx.updateLocator()); UpdateLocatorKind locatorKind = getLocatorKindFromUpdateLocatorContext(ctx.updateLocator()); Expression newExpression = (Expression) this.visitExprSingle(ctx.replacer_expr); - return new ReplaceExpression(mainExpression, locatorExpression, newExpression, locatorKind, createMetadataFromContext(ctx)); + return new ReplaceExpression( + mainExpression, + locatorExpression, + newExpression, + locatorKind, + createMetadataFromContext(ctx) + ); } @Override public Node visitTransformExpr(JsoniqParser.TransformExprContext ctx) { - List copyDecls = ctx.copyDecl().stream() - .map(copyDeclCtx -> { - Name var = ((VariableReferenceExpression) this.visitVarRef(copyDeclCtx.var_ref)).getVariableName(); - Expression expr = (Expression) this.visitExprSingle(copyDeclCtx.src_expr); - return new CopyDeclaration(var, expr); - }) - .collect(Collectors.toList()); + List copyDecls = ctx.copyDecl() + .stream() + .map(copyDeclCtx -> { + Name var = ((VariableReferenceExpression) this.visitVarRef(copyDeclCtx.var_ref)).getVariableName(); + Expression expr = (Expression) this.visitExprSingle(copyDeclCtx.src_expr); + return new CopyDeclaration(var, expr); + }) + .collect(Collectors.toList()); Expression modifyExpression = (Expression) this.visitExprSingle(ctx.mod_expr); Expression returnExpression = (Expression) this.visitExprSingle(ctx.ret_expr); return new TransformExpression(copyDecls, modifyExpression, returnExpression, createMetadataFromContext(ctx)); @@ -1227,16 +1239,14 @@ public Expression getMainExpressionFromUpdateLocatorContext(JsoniqParser.UpdateL expr, createMetadataFromContext(ctx) ); - } - else if (child instanceof JsoniqParser.ArrayLookupContext) { + } else if (child instanceof JsoniqParser.ArrayLookupContext) { Expression expr = (Expression) this.visitArrayLookup((JsoniqParser.ArrayLookupContext) child); mainExpression = new ArrayLookupExpression( mainExpression, expr, createMetadataFromContext(ctx) ); - } - else { + } else { throw new OurBadException("Unrecognized locator expression found in update expression."); } } @@ -1250,8 +1260,7 @@ public UpdateLocatorKind getLocatorKindFromUpdateLocatorContext(JsoniqParser.Upd } if (locatorExprCtx instanceof JsoniqParser.ArrayLookupContext) { return UpdateLocatorKind.ARRAY_LOOKUP; - } - else { + } else { throw new OurBadException("Unrecognized locator found in update expression."); } } @@ -1263,8 +1272,7 @@ public Expression getLocatorExpressionFromUpdateLocatorContext(JsoniqParser.Upda } if (locatorExprCtx instanceof JsoniqParser.ArrayLookupContext) { return (Expression) this.visitArrayLookup((JsoniqParser.ArrayLookupContext) locatorExprCtx); - } - else { + } else { throw new OurBadException("Unrecognized locator found in update expression."); } } diff --git a/src/main/java/org/rumbledb/compiler/VisitorHelpers.java b/src/main/java/org/rumbledb/compiler/VisitorHelpers.java index f728ec0ff4..49ace863dc 100644 --- a/src/main/java/org/rumbledb/compiler/VisitorHelpers.java +++ b/src/main/java/org/rumbledb/compiler/VisitorHelpers.java @@ -184,7 +184,7 @@ public static MainModule parseXQueryMainModule( inferTypes(mainModule, configuration); populateExecutionModes(mainModule, configuration); // TODO populate expression classifications here? -// populateExpressionClassifications(mainModule, configuration); + // populateExpressionClassifications(mainModule, configuration); return mainModule; } catch (ParseCancellationException ex) { ParsingException e = new ParsingException( diff --git a/src/main/java/org/rumbledb/expressions/update/AppendExpression.java b/src/main/java/org/rumbledb/expressions/update/AppendExpression.java index 0c54452f9c..ae7702206d 100644 --- a/src/main/java/org/rumbledb/expressions/update/AppendExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/AppendExpression.java @@ -4,7 +4,6 @@ import org.rumbledb.exceptions.OurBadException; import org.rumbledb.expressions.AbstractNodeVisitor; import org.rumbledb.expressions.Expression; -import org.rumbledb.expressions.ExpressionClassification; import org.rumbledb.expressions.Node; import java.util.Arrays; @@ -14,9 +13,11 @@ public class AppendExpression extends Expression { private Expression arrayExpression; private Expression toAppendExpression; - public AppendExpression(Expression arrayExpression, - Expression toAppendExpression, - ExceptionMetadata metadata + + public AppendExpression( + Expression arrayExpression, + Expression toAppendExpression, + ExceptionMetadata metadata ) { super(metadata); if (arrayExpression == null) { @@ -53,7 +54,7 @@ public void serializeToJSONiq(StringBuffer sb, int indent) { sb.append("append json "); this.toAppendExpression.serializeToJSONiq(sb, 0); sb.append(" into "); - this.arrayExpression.serializeToJSONiq(sb,0); + this.arrayExpression.serializeToJSONiq(sb, 0); sb.append("\n"); } } diff --git a/src/main/java/org/rumbledb/expressions/update/CopyDeclaration.java b/src/main/java/org/rumbledb/expressions/update/CopyDeclaration.java index c761021b82..fe9d215dcb 100644 --- a/src/main/java/org/rumbledb/expressions/update/CopyDeclaration.java +++ b/src/main/java/org/rumbledb/expressions/update/CopyDeclaration.java @@ -1,7 +1,6 @@ package org.rumbledb.expressions.update; import org.rumbledb.context.Name; -import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.expressions.Expression; import org.rumbledb.types.SequenceType; @@ -9,10 +8,10 @@ public class CopyDeclaration { private Name variableName; private Expression sourceExpression; - private SequenceType sequenceType; - public CopyDeclaration(Name variableName, - Expression sourceExpression + public CopyDeclaration( + Name variableName, + Expression sourceExpression ) { if (variableName == null) { throw new IllegalArgumentException("Copy clause var decls cannot be empty"); diff --git a/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java b/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java index 4003e4430f..40363f44af 100644 --- a/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java @@ -4,7 +4,6 @@ import org.rumbledb.exceptions.OurBadException; import org.rumbledb.expressions.AbstractNodeVisitor; import org.rumbledb.expressions.Expression; -import org.rumbledb.expressions.ExpressionClassification; import org.rumbledb.expressions.Node; import java.util.Arrays; @@ -15,10 +14,12 @@ public class DeleteExpression extends Expression { private Expression mainExpression; private Expression locatorExpression; private UpdateLocatorKind locatorKind; - public DeleteExpression(Expression mainExpression, - Expression locatorExpression, - UpdateLocatorKind locatorKind, - ExceptionMetadata metadata + + public DeleteExpression( + Expression mainExpression, + Expression locatorExpression, + UpdateLocatorKind locatorKind, + ExceptionMetadata metadata ) { super(metadata); if (mainExpression == null) { @@ -62,7 +63,7 @@ public void serializeToJSONiq(StringBuffer sb, int indent) { indentIt(sb, indent); sb.append("delete json "); this.mainExpression.serializeToJSONiq(sb, 0); - this.locatorExpression.serializeToJSONiq(sb,0); + this.locatorExpression.serializeToJSONiq(sb, 0); sb.append("\n"); } } diff --git a/src/main/java/org/rumbledb/expressions/update/InsertExpression.java b/src/main/java/org/rumbledb/expressions/update/InsertExpression.java index 100ad7b022..b4edff096c 100644 --- a/src/main/java/org/rumbledb/expressions/update/InsertExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/InsertExpression.java @@ -4,7 +4,6 @@ import org.rumbledb.exceptions.OurBadException; import org.rumbledb.expressions.AbstractNodeVisitor; import org.rumbledb.expressions.Expression; -import org.rumbledb.expressions.ExpressionClassification; import org.rumbledb.expressions.Node; import java.util.Arrays; @@ -16,10 +15,11 @@ public class InsertExpression extends Expression { private Expression toInsertExpression; private Expression positionExpression; - public InsertExpression(Expression mainExpression, - Expression toInsertExpression, - Expression positionExpression, - ExceptionMetadata metadata + public InsertExpression( + Expression mainExpression, + Expression toInsertExpression, + Expression positionExpression, + ExceptionMetadata metadata ) { super(metadata); this.mainExpression = mainExpression; @@ -48,9 +48,9 @@ public Expression getPositionExpression() { @Override public List getChildren() { - return this.positionExpression == null ? - Arrays.asList(mainExpression, toInsertExpression) : - Arrays.asList(mainExpression, toInsertExpression, positionExpression); + return this.positionExpression == null + ? Arrays.asList(mainExpression, toInsertExpression) + : Arrays.asList(mainExpression, toInsertExpression, positionExpression); } @Override diff --git a/src/main/java/org/rumbledb/expressions/update/RenameExpression.java b/src/main/java/org/rumbledb/expressions/update/RenameExpression.java index 43e74f3e09..6d4a879e5d 100644 --- a/src/main/java/org/rumbledb/expressions/update/RenameExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/RenameExpression.java @@ -4,7 +4,6 @@ import org.rumbledb.exceptions.OurBadException; import org.rumbledb.expressions.AbstractNodeVisitor; import org.rumbledb.expressions.Expression; -import org.rumbledb.expressions.ExpressionClassification; import org.rumbledb.expressions.Node; import java.util.Arrays; @@ -16,11 +15,13 @@ public class RenameExpression extends Expression { private Expression locatorExpression; private Expression nameExpression; private UpdateLocatorKind locatorKind; - public RenameExpression(Expression mainExpression, - Expression locatorExpression, - Expression nameExpression, - UpdateLocatorKind locatorKind, - ExceptionMetadata metadata + + public RenameExpression( + Expression mainExpression, + Expression locatorExpression, + Expression nameExpression, + UpdateLocatorKind locatorKind, + ExceptionMetadata metadata ) { super(metadata); if (mainExpression == null) { @@ -75,8 +76,8 @@ public void serializeToJSONiq(StringBuffer sb, int indent) { indentIt(sb, indent); sb.append("rename json "); this.mainExpression.serializeToJSONiq(sb, 0); - this.locatorExpression.serializeToJSONiq(sb,0); - this.nameExpression.serializeToJSONiq(sb,0); + this.locatorExpression.serializeToJSONiq(sb, 0); + this.nameExpression.serializeToJSONiq(sb, 0); sb.append("\n"); } diff --git a/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java b/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java index fd26d0c04c..a685095e63 100644 --- a/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java @@ -15,11 +15,13 @@ public class ReplaceExpression extends Expression { private Expression locatorExpression; private Expression replacerExpression; private UpdateLocatorKind locatorKind; - public ReplaceExpression(Expression mainExpression, - Expression locatorExpression, - Expression replacerExpression, - UpdateLocatorKind locatorKind, - ExceptionMetadata metadata + + public ReplaceExpression( + Expression mainExpression, + Expression locatorExpression, + Expression replacerExpression, + UpdateLocatorKind locatorKind, + ExceptionMetadata metadata ) { super(metadata); if (mainExpression == null) { @@ -71,9 +73,9 @@ public void serializeToJSONiq(StringBuffer sb, int indent) { indentIt(sb, indent); sb.append("replace json value of "); this.mainExpression.serializeToJSONiq(sb, 0); - this.locatorExpression.serializeToJSONiq(sb,0); + this.locatorExpression.serializeToJSONiq(sb, 0); sb.append(" with "); - this.replacerExpression.serializeToJSONiq(sb,0); + this.replacerExpression.serializeToJSONiq(sb, 0); sb.append("\n"); } } diff --git a/src/main/java/org/rumbledb/expressions/update/TransformExpression.java b/src/main/java/org/rumbledb/expressions/update/TransformExpression.java index afcf54573f..b824100946 100644 --- a/src/main/java/org/rumbledb/expressions/update/TransformExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/TransformExpression.java @@ -10,8 +10,7 @@ import java.util.Objects; import java.util.stream.Collectors; -public class TransformExpression extends Expression -{ +public class TransformExpression extends Expression { private List copyDeclarations; private Expression modifyExpression; @@ -19,10 +18,11 @@ public class TransformExpression extends Expression protected ExecutionMode variableHighestStorageMode = ExecutionMode.UNSET; - public TransformExpression(List copyDeclarations, - Expression modifyExpression, - Expression returnExpression, - ExceptionMetadata metadata + public TransformExpression( + List copyDeclarations, + Expression modifyExpression, + Expression returnExpression, + ExceptionMetadata metadata ) { super(metadata); if (copyDeclarations == null || copyDeclarations.isEmpty()) { @@ -38,7 +38,10 @@ public List getCopyDeclarations() { } public List getCopySourceExpressions() { - return this.copyDeclarations.stream().filter(Objects::nonNull).map(CopyDeclaration::getSourceExpression).collect(Collectors.toList()); + return this.copyDeclarations.stream() + .filter(Objects::nonNull) + .map(CopyDeclaration::getSourceExpression) + .collect(Collectors.toList()); } public Expression getModifyExpression() { @@ -57,8 +60,8 @@ public void initHighestExecutionMode(VisitorConfig visitorConfig) { public ExecutionMode getVariableHighestStorageMode(VisitorConfig visitorConfig) { if ( - !visitorConfig.suppressErrorsForAccessingUnsetExecutionModes() - && this.variableHighestStorageMode == ExecutionMode.UNSET + !visitorConfig.suppressErrorsForAccessingUnsetExecutionModes() + && this.variableHighestStorageMode == ExecutionMode.UNSET ) { throw new OurBadException("A copy variable storage mode is accessed without being set."); } @@ -67,7 +70,10 @@ public ExecutionMode getVariableHighestStorageMode(VisitorConfig visitorConfig) @Override public List getChildren() { - List result = this.copyDeclarations.stream().filter(Objects::nonNull).map(CopyDeclaration::getSourceExpression).collect(Collectors.toList()); + List result = this.copyDeclarations.stream() + .filter(Objects::nonNull) + .map(CopyDeclaration::getSourceExpression) + .collect(Collectors.toList()); result.add(this.modifyExpression); result.add(this.returnExpression); return result; From 67107eb3840ba33f37d965e49bb2a032296a7abf Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sun, 26 Mar 2023 19:03:26 +0200 Subject: [PATCH 034/119] Implement simple UpdatePrimitive class and interface, and implement InsertIntoObjectPrimitive --- .../primitives/InsertIntoObjectPrimitive.java | 29 +++++++++++++++++++ .../update/primitives/UpdatePrimitive.java | 7 +++++ .../primitives/UpdatePrimitiveInterface.java | 8 +++++ 3 files changed, 44 insertions(+) create mode 100644 src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java create mode 100644 src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java create mode 100644 src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveInterface.java diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java new file mode 100644 index 0000000000..e110a31e90 --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java @@ -0,0 +1,29 @@ +package org.rumbledb.runtime.update.primitives; + +import org.rumbledb.items.ObjectItem; + +public class InsertIntoObjectPrimitive extends UpdatePrimitive { + + private ObjectItem targetObject; + private ObjectItem sourceObject; + + public InsertIntoObjectPrimitive(ObjectItem targetObject, ObjectItem sourceObject) { + this.targetObject = targetObject; + this.sourceObject = sourceObject; + } + + public ObjectItem getTargetObject() { + return targetObject; + } + + public ObjectItem getSourceObject() { + return sourceObject; + } + + @Override + public void apply() { + for (String key : this.sourceObject.getKeys()) { + this.targetObject.putItemByKey(key, this.sourceObject.getItemByKey(key)); + } + } +} diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java new file mode 100644 index 0000000000..e03c4fef6b --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java @@ -0,0 +1,7 @@ +package org.rumbledb.runtime.update.primitives; + +public abstract class UpdatePrimitive implements UpdatePrimitiveInterface { + + @Override + public abstract void apply(); +} diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveInterface.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveInterface.java new file mode 100644 index 0000000000..497a66c6a6 --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveInterface.java @@ -0,0 +1,8 @@ +package org.rumbledb.runtime.update.primitives; + +import java.io.Serializable; + +public interface UpdatePrimitiveInterface extends Serializable { + + void apply(); +} From 6a1631f5318061072ff2e04b021cc9f3dce4054d Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sun, 26 Mar 2023 19:08:59 +0200 Subject: [PATCH 035/119] implement InsertIntoArrayPrimitive --- .../primitives/InsertIntoArrayPrimitive.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java new file mode 100644 index 0000000000..c0ba5cd8fb --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java @@ -0,0 +1,42 @@ +package org.rumbledb.runtime.update.primitives; + +import org.rumbledb.api.Item; +import org.rumbledb.items.ArrayItem; +import org.rumbledb.items.IntItem; + +import java.util.List; + +public class InsertIntoArrayPrimitive extends UpdatePrimitive { + + private ArrayItem targetArray; + + private IntItem positionInt; + + private List sourceSequence; + + public InsertIntoArrayPrimitive(ArrayItem targetArray, IntItem positionInt, List sourceSequence) { + if (positionInt.getIntValue() < 0 || positionInt.getIntValue() >= targetArray.getSize()) { + //TODO throw error or do nothing? + } + this.targetArray = targetArray; + this.positionInt = positionInt; + this.sourceSequence = sourceSequence; + } + + public ArrayItem getTargetArray() { + return targetArray; + } + + public IntItem getPositionInt() { + return positionInt; + } + + public List getSourceSequence() { + return sourceSequence; + } + + @Override + public void apply() { + this.targetArray.putItemsAt(this.sourceSequence, this.positionInt.getIntValue()); + } +} From 3eea7e9e0d513237bfbb8e3f55ef8f943a6bae95 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sun, 26 Mar 2023 19:09:23 +0200 Subject: [PATCH 036/119] update ArrayItem to put multiple items in a position at once --- src/main/java/org/rumbledb/items/ArrayItem.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/org/rumbledb/items/ArrayItem.java b/src/main/java/org/rumbledb/items/ArrayItem.java index ee50a85dca..9988eceade 100644 --- a/src/main/java/org/rumbledb/items/ArrayItem.java +++ b/src/main/java/org/rumbledb/items/ArrayItem.java @@ -83,6 +83,14 @@ public void putItem(Item value) { this.arrayItems.add(value); } + public void putItemAt(Item value, int i) { + this.arrayItems.add(i, value); + } + + public void putItemsAt(List values, int i) { + this.arrayItems.addAll(i, values); + } + @Override public boolean isArray() { return true; From daf9c3985c8f5047ddcc5256847f70dc8c602aba Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sun, 26 Mar 2023 19:15:39 +0200 Subject: [PATCH 037/119] Implement DeleteFromArrayPrimitive and DeleteFromObjectPrimitive --- .../java/org/rumbledb/items/ArrayItem.java | 4 +++ .../java/org/rumbledb/items/ObjectItem.java | 8 +++++ .../primitives/DeleteFromArrayPrimitive.java | 32 +++++++++++++++++ .../primitives/DeleteFromObjectPrimitive.java | 34 +++++++++++++++++++ 4 files changed, 78 insertions(+) create mode 100644 src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java create mode 100644 src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java diff --git a/src/main/java/org/rumbledb/items/ArrayItem.java b/src/main/java/org/rumbledb/items/ArrayItem.java index 9988eceade..e7fce02dee 100644 --- a/src/main/java/org/rumbledb/items/ArrayItem.java +++ b/src/main/java/org/rumbledb/items/ArrayItem.java @@ -91,6 +91,10 @@ public void putItemsAt(List values, int i) { this.arrayItems.addAll(i, values); } + public void removeItemAt(int i) { + this.arrayItems.remove(i); + } + @Override public boolean isArray() { return true; diff --git a/src/main/java/org/rumbledb/items/ObjectItem.java b/src/main/java/org/rumbledb/items/ObjectItem.java index d6d44306e6..a29b71decf 100644 --- a/src/main/java/org/rumbledb/items/ObjectItem.java +++ b/src/main/java/org/rumbledb/items/ObjectItem.java @@ -152,6 +152,14 @@ public void putItemByKey(String s, Item value) { checkForDuplicateKeys(this.keys, ExceptionMetadata.EMPTY_METADATA); } + public void removeItemByKey(String s) { + if (this.keys.contains(s)) { + int index = this.keys.indexOf(s); + this.values.remove(index); + this.keys.remove(index); + } + } + @Override public boolean isObject() { return true; diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java new file mode 100644 index 0000000000..bdb2d44a36 --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java @@ -0,0 +1,32 @@ +package org.rumbledb.runtime.update.primitives; + +import org.rumbledb.items.ArrayItem; +import org.rumbledb.items.IntItem; + +public class DeleteFromArrayPrimitive extends UpdatePrimitive { + + private ArrayItem targetArray; + + private IntItem positionInt; + + public DeleteFromArrayPrimitive(ArrayItem targetArray, IntItem positionInt) { + if (positionInt.getIntValue() < 0 || positionInt.getIntValue() >= targetArray.getSize()) { + //TODO throw error or do nothing? + } + this.targetArray = targetArray; + this.positionInt = positionInt; + } + + public ArrayItem getTargetArray() { + return targetArray; + } + + public IntItem getPositionInt() { + return positionInt; + } + + @Override + public void apply() { + this.targetArray.removeItemAt(this.positionInt.getIntValue()); + } +} diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java new file mode 100644 index 0000000000..6f910360d8 --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java @@ -0,0 +1,34 @@ +package org.rumbledb.runtime.update.primitives; + +import org.rumbledb.items.ObjectItem; +import org.rumbledb.items.StringItem; + +import java.util.List; +import java.util.stream.Collectors; + +public class DeleteFromObjectPrimitive extends UpdatePrimitive { + + private ObjectItem targetObject; + + private List namesToRemove; + + public DeleteFromObjectPrimitive(ObjectItem targetObject, List namesToRemove) { + this.targetObject = targetObject; + this.namesToRemove = namesToRemove; + } + + public ObjectItem getTargetObject() { + return targetObject; + } + + public List getNamesToRemove() { + return namesToRemove; + } + + @Override + public void apply() { + for (String str : this.namesToRemove.stream().map(StringItem::getStringValue).collect(Collectors.toList())) { + this.targetObject.removeItemByKey(str); + } + } +} From 5a558e0dbae8ffceac97cf118144d768095b081f Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sun, 26 Mar 2023 19:30:05 +0200 Subject: [PATCH 038/119] Implement ReplaceInArrayPrimitive and ReplaceInObjectPrimitive --- .../primitives/ReplaceInArrayPrimitive.java | 45 +++++++++++++++++++ .../primitives/ReplaceInObjectPrimitive.java | 41 +++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java create mode 100644 src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java new file mode 100644 index 0000000000..e6fb99c6e8 --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java @@ -0,0 +1,45 @@ +package org.rumbledb.runtime.update.primitives; + +import org.rumbledb.api.Item; +import org.rumbledb.items.ArrayItem; +import org.rumbledb.items.IntItem; + +public class ReplaceInArrayPrimitive extends UpdatePrimitive { + + private ArrayItem targetArray; + + private IntItem positionInt; + + private Item replacementItem; + + public ReplaceInArrayPrimitive(ArrayItem targetArray, IntItem positionInt, Item replacementItem) { + this.targetArray = targetArray; + this.positionInt = positionInt; + this.replacementItem = replacementItem; + } + + public ArrayItem getTargetArray() { + return targetArray; + } + + public IntItem getPositionInt() { + return positionInt; + } + + public Item getReplacementItem() { + return replacementItem; + } + + @Override + public void apply() { + int index = this.positionInt.getIntValue() - 1; + if (index >= 0 || index < this.targetArray.getSize()) { + this.targetArray.removeItemAt(index); + if (index == this.targetArray.getSize()) { + this.targetArray.append(this.replacementItem); + } else { + this.targetArray.putItemAt(this.replacementItem, index); + } + } + } +} diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java new file mode 100644 index 0000000000..ea2bc014f1 --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java @@ -0,0 +1,41 @@ +package org.rumbledb.runtime.update.primitives; + +import org.rumbledb.api.Item; +import org.rumbledb.items.ObjectItem; +import org.rumbledb.items.StringItem; + +public class ReplaceInObjectPrimitive extends UpdatePrimitive { + + private ObjectItem targetObject; + + private StringItem targetName; + + private Item replacementItem; + + public ReplaceInObjectPrimitive(ObjectItem targetObject, StringItem targetName, Item replacementItem) { + this.targetObject = targetObject; + this.targetName = targetName; + this.replacementItem = replacementItem; + } + + public ObjectItem getTargetObject() { + return targetObject; + } + + public StringItem getTargetName() { + return targetName; + } + + public Item getReplacementItem() { + return replacementItem; + } + + @Override + public void apply() { + String name = this.targetName.getStringValue(); + if (this.targetObject.getKeys().contains(name)) { + this.targetObject.removeItemByKey(name); + this.targetObject.putItemByKey(name, this.replacementItem); + } + } +} From e0093e813a75f46d4ab4916b6ef9eca04ccb512f Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sun, 26 Mar 2023 19:33:39 +0200 Subject: [PATCH 039/119] Implement RenameInObjectPrimitive --- .../primitives/RenameInObjectPrimitive.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java new file mode 100644 index 0000000000..f26473dca3 --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java @@ -0,0 +1,43 @@ +package org.rumbledb.runtime.update.primitives; + +import org.rumbledb.api.Item; +import org.rumbledb.items.ObjectItem; +import org.rumbledb.items.StringItem; + +public class RenameInObjectPrimitive extends UpdatePrimitive { + + private ObjectItem targetObject; + + private StringItem targetName; + + private StringItem replacementName; + + public RenameInObjectPrimitive(ObjectItem targetObject, StringItem targetName, StringItem replacementName) { + this.targetObject = targetObject; + this.targetName = targetName; + this.replacementName = replacementName; + } + + public ObjectItem getTargetObject() { + return targetObject; + } + + public StringItem getTargetName() { + return targetName; + } + + public StringItem getReplacementName() { + return replacementName; + } + + @Override + public void apply() { + String name = this.targetName.getStringValue(); + if (this.targetObject.getKeys().contains(name)) { + Item item = this.targetObject.getItemByKey(name); + this.targetObject.removeItemByKey(name); + this.targetObject.putItemByKey(this.replacementName.getStringValue(), item); + } + // TODO: implement replace and rename methods for Array & Object to avoid deletion and append + } +} From e6535964b27123ab51c18543b91dc0b561a44bcb Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 27 Mar 2023 00:54:25 +0200 Subject: [PATCH 040/119] Add getTarget method to UpdatePrimitive --- .../update/primitives/DeleteFromArrayPrimitive.java | 8 +++++++- .../update/primitives/DeleteFromObjectPrimitive.java | 6 ++++++ .../update/primitives/InsertIntoArrayPrimitive.java | 7 ++++++- .../update/primitives/InsertIntoObjectPrimitive.java | 6 ++++++ .../update/primitives/RenameInObjectPrimitive.java | 5 +++++ .../update/primitives/ReplaceInArrayPrimitive.java | 5 +++++ .../update/primitives/ReplaceInObjectPrimitive.java | 5 +++++ .../runtime/update/primitives/UpdatePrimitive.java | 5 +++++ .../update/primitives/UpdatePrimitiveInterface.java | 4 ++++ 9 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java index bdb2d44a36..fccf4572ef 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java @@ -1,5 +1,6 @@ package org.rumbledb.runtime.update.primitives; +import org.rumbledb.api.Item; import org.rumbledb.items.ArrayItem; import org.rumbledb.items.IntItem; @@ -11,7 +12,7 @@ public class DeleteFromArrayPrimitive extends UpdatePrimitive { public DeleteFromArrayPrimitive(ArrayItem targetArray, IntItem positionInt) { if (positionInt.getIntValue() < 0 || positionInt.getIntValue() >= targetArray.getSize()) { - //TODO throw error or do nothing? + // TODO throw error or do nothing? } this.targetArray = targetArray; this.positionInt = positionInt; @@ -29,4 +30,9 @@ public IntItem getPositionInt() { public void apply() { this.targetArray.removeItemAt(this.positionInt.getIntValue()); } + + @Override + public Item getTarget() { + return targetArray; + } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java index 6f910360d8..71ff5b921e 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java @@ -1,5 +1,6 @@ package org.rumbledb.runtime.update.primitives; +import org.rumbledb.api.Item; import org.rumbledb.items.ObjectItem; import org.rumbledb.items.StringItem; @@ -31,4 +32,9 @@ public void apply() { this.targetObject.removeItemByKey(str); } } + + @Override + public Item getTarget() { + return targetObject; + } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java index c0ba5cd8fb..b7b6eb0492 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java @@ -16,7 +16,7 @@ public class InsertIntoArrayPrimitive extends UpdatePrimitive { public InsertIntoArrayPrimitive(ArrayItem targetArray, IntItem positionInt, List sourceSequence) { if (positionInt.getIntValue() < 0 || positionInt.getIntValue() >= targetArray.getSize()) { - //TODO throw error or do nothing? + // TODO throw error or do nothing? } this.targetArray = targetArray; this.positionInt = positionInt; @@ -39,4 +39,9 @@ public List getSourceSequence() { public void apply() { this.targetArray.putItemsAt(this.sourceSequence, this.positionInt.getIntValue()); } + + @Override + public Item getTarget() { + return targetArray; + } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java index e110a31e90..f601f58009 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java @@ -1,5 +1,6 @@ package org.rumbledb.runtime.update.primitives; +import org.rumbledb.api.Item; import org.rumbledb.items.ObjectItem; public class InsertIntoObjectPrimitive extends UpdatePrimitive { @@ -26,4 +27,9 @@ public void apply() { this.targetObject.putItemByKey(key, this.sourceObject.getItemByKey(key)); } } + + @Override + public Item getTarget() { + return targetObject; + } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java index f26473dca3..fa0186717c 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java @@ -40,4 +40,9 @@ public void apply() { } // TODO: implement replace and rename methods for Array & Object to avoid deletion and append } + + @Override + public Item getTarget() { + return targetObject; + } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java index e6fb99c6e8..9043f8a29a 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java @@ -42,4 +42,9 @@ public void apply() { } } } + + @Override + public Item getTarget() { + return targetArray; + } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java index ea2bc014f1..31d211131c 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java @@ -38,4 +38,9 @@ public void apply() { this.targetObject.putItemByKey(name, this.replacementItem); } } + + @Override + public Item getTarget() { + return targetObject; + } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java index e03c4fef6b..baee723039 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java @@ -1,7 +1,12 @@ package org.rumbledb.runtime.update.primitives; +import org.rumbledb.api.Item; + public abstract class UpdatePrimitive implements UpdatePrimitiveInterface { @Override public abstract void apply(); + + @Override + public abstract Item getTarget(); } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveInterface.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveInterface.java index 497a66c6a6..db975a38b9 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveInterface.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveInterface.java @@ -1,8 +1,12 @@ package org.rumbledb.runtime.update.primitives; +import org.rumbledb.api.Item; + import java.io.Serializable; public interface UpdatePrimitiveInterface extends Serializable { void apply(); + + Item getTarget(); } From 082c8f08f9b34f48fdb3ddcfd940785d7ca72ad4 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 27 Mar 2023 00:54:54 +0200 Subject: [PATCH 041/119] Implement simple PUL class --- .../java/org/rumbledb/items/ObjectItem.java | 13 + .../runtime/update/PendingUpdateList.java | 223 ++++++++++++++++++ 2 files changed, 236 insertions(+) create mode 100644 src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java diff --git a/src/main/java/org/rumbledb/items/ObjectItem.java b/src/main/java/org/rumbledb/items/ObjectItem.java index a29b71decf..b11ac1f137 100644 --- a/src/main/java/org/rumbledb/items/ObjectItem.java +++ b/src/main/java/org/rumbledb/items/ObjectItem.java @@ -160,6 +160,19 @@ public void removeItemByKey(String s) { } } + public static ObjectItem mergeWith(ObjectItem obj1, ObjectItem obj2) { + ObjectItem result = new ObjectItem(); + + for (String otherKey : obj1.getKeys()) { + result.putItemByKey(otherKey, obj1.getItemByKey(otherKey)); + } + for (String otherKey : obj2.getKeys()) { + result.putItemByKey(otherKey, obj2.getItemByKey(otherKey)); + } + // TODO Raise jerr:JNUP0005 on collision + return result; + } + @Override public boolean isObject() { return true; diff --git a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java new file mode 100644 index 0000000000..c3ce86d452 --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java @@ -0,0 +1,223 @@ +package org.rumbledb.runtime.update; + +import org.rumbledb.api.Item; +import org.rumbledb.items.ArrayItem; +import org.rumbledb.items.IntItem; +import org.rumbledb.items.ObjectItem; +import org.rumbledb.items.StringItem; +import org.rumbledb.runtime.update.primitives.*; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.stream.Collectors; + +public class PendingUpdateList { + + private List updatePrimitives; + + public PendingUpdateList() { + this.updatePrimitives = new ArrayList<>(); + } + + public PendingUpdateList(List updatePrimitives) { + this.updatePrimitives = updatePrimitives; + } + + public List getUpdatePrimitives() { + return updatePrimitives; + } + + public void addUpdatePrimitive(UpdatePrimitive updatePrimitive) { + this.updatePrimitives.add(updatePrimitive); + } + + public void addAllUpdatePrimitives(List updatePrimitives) { + this.updatePrimitives.addAll(updatePrimitives); + } + + public boolean isEmpty() { + return this.updatePrimitives.isEmpty(); + } + + public int size() { + return this.updatePrimitives.size(); + } + + public void applyUpdates() { + for (UpdatePrimitive up : this.updatePrimitives) { + up.apply(); + } + } + + public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpdateList pul2) { + PendingUpdateList result = new PendingUpdateList(); + HashMap> itemToUpdateMap = new HashMap<>(); + List tempUps; + + for (UpdatePrimitive up : pul1.getUpdatePrimitives()) { + result.addUpdatePrimitive(up); + Item target = up.getTarget(); + + if (!itemToUpdateMap.containsKey(target)) { + tempUps = new ArrayList<>(); + } else { + tempUps = itemToUpdateMap.get(target); + } + tempUps.add(up); + itemToUpdateMap.put(target, tempUps); + } + + for (UpdatePrimitive up : pul2.getUpdatePrimitives()) { + result.addUpdatePrimitive(up); + Item target = up.getTarget(); + + if (!itemToUpdateMap.containsKey(target)) { + tempUps = new ArrayList<>(); + } else { + tempUps = itemToUpdateMap.get(target); + } + tempUps.add(up); + itemToUpdateMap.put(target, tempUps); + } + + for (Item target : itemToUpdateMap.keySet()) { + List targetUpdates = itemToUpdateMap.get(target); + + // object + if (target.isObject()) { + boolean hasDeletePrimitives = targetUpdates.stream() + .anyMatch(u -> u instanceof DeleteFromObjectPrimitive); + boolean hasInsertPrimitives = targetUpdates.stream() + .anyMatch(u -> u instanceof InsertIntoObjectPrimitive); + + if (hasInsertPrimitives) { + ObjectItem sourceObject = + targetUpdates + .stream() + .filter(u -> u instanceof InsertIntoObjectPrimitive) + .map(u -> ((InsertIntoObjectPrimitive) u).getSourceObject()) + .reduce(new ObjectItem(), ObjectItem::mergeWith); + result.addUpdatePrimitive(new InsertIntoObjectPrimitive((ObjectItem) target, sourceObject)); + } + + if (hasDeletePrimitives) { + List names = + targetUpdates + .stream() + .filter(u -> u instanceof DeleteFromObjectPrimitive) + .flatMap(u -> ((DeleteFromObjectPrimitive) u).getNamesToRemove().stream()) + .distinct() + .collect(Collectors.toList()); + result.addUpdatePrimitive(new DeleteFromObjectPrimitive((ObjectItem) target, names)); + continue; + } + + List renamePrimitives = + targetUpdates + .stream() + .filter(u -> u instanceof RenameInObjectPrimitive) + .collect(Collectors.toList()); + List uniqueRenameSelectors = + renamePrimitives + .stream() + .map(u -> ((RenameInObjectPrimitive) u).getTargetName()) + .distinct() + .collect(Collectors.toList()); + + if (renamePrimitives.size() != uniqueRenameSelectors.size()) { + // TODO Throw rename on same key error jerr:JNUP0010. + } + + List replacePrimitives = + targetUpdates + .stream() + .filter(u -> u instanceof ReplaceInObjectPrimitive) + .collect(Collectors.toList()); + List uniqueReplaceSelectors = + replacePrimitives + .stream() + .map(u -> ((ReplaceInObjectPrimitive) u).getTargetName()) + .distinct() + .collect(Collectors.toList()); + + if (replacePrimitives.size() != uniqueReplaceSelectors.size()) { + // TODO Throw replace on same key error jerr:JNUP0009. + } + + } + + // array + if (target.isArray()) { + boolean hasDeletePrimitives = targetUpdates.stream() + .anyMatch(u -> u instanceof DeleteFromArrayPrimitive); + boolean hasInsertPrimitives = targetUpdates.stream() + .anyMatch(u -> u instanceof InsertIntoArrayPrimitive); + + if (hasInsertPrimitives) { + HashMap> locatorToInsertsMap = new HashMap<>(); + + targetUpdates + .stream() + .filter(u -> u instanceof InsertIntoArrayPrimitive) + .map(u -> (InsertIntoArrayPrimitive) u) + .forEach(u -> { + List temp; + if (!locatorToInsertsMap.containsKey(u.getPositionInt())) { + temp = new ArrayList<>(); + } else { + temp = locatorToInsertsMap.get(u.getPositionInt()); + } + temp.addAll(u.getSourceSequence()); + locatorToInsertsMap.put(u.getPositionInt(), temp); + }); + + for (IntItem intItem : locatorToInsertsMap.keySet()) { + result.addUpdatePrimitive( + new InsertIntoArrayPrimitive( + (ArrayItem) target, + intItem, + locatorToInsertsMap.get(intItem) + ) + ); + } + } + + if (hasDeletePrimitives) { + List intItems = + targetUpdates + .stream() + .filter(u -> u instanceof DeleteFromArrayPrimitive) + .map(u -> ((DeleteFromArrayPrimitive) u).getPositionInt()) + .distinct() + .collect(Collectors.toList()); + for (IntItem intItem : intItems) { + result.addUpdatePrimitive(new DeleteFromArrayPrimitive((ArrayItem) target, intItem)); + } + continue; + } + + List replacePrimitives = + targetUpdates + .stream() + .filter(u -> u instanceof ReplaceInArrayPrimitive) + .collect(Collectors.toList()); + List uniqueReplaceSelectors = + replacePrimitives + .stream() + .map(u -> ((ReplaceInArrayPrimitive) u).getPositionInt()) + .distinct() + .collect(Collectors.toList()); + + if (replacePrimitives.size() != uniqueReplaceSelectors.size()) { + // TODO Throw replace on same key error jerr:JNUP0009. + } + + } + } + + return result; + } + + +} From 358e15a83a28f542f0ca9ada4903deb49c64cd92 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 27 Mar 2023 01:04:14 +0200 Subject: [PATCH 042/119] Add isUpdating and getPendingUpdateList methods to iterator hierarchy --- .../org/rumbledb/runtime/RuntimeIterator.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/java/org/rumbledb/runtime/RuntimeIterator.java b/src/main/java/org/rumbledb/runtime/RuntimeIterator.java index b70ba55418..1fd9830a63 100644 --- a/src/main/java/org/rumbledb/runtime/RuntimeIterator.java +++ b/src/main/java/org/rumbledb/runtime/RuntimeIterator.java @@ -50,6 +50,7 @@ import org.rumbledb.items.structured.JSoundDataFrame; import org.rumbledb.runtime.flwor.NativeClauseContext; import org.rumbledb.runtime.misc.ComparisonIterator; +import org.rumbledb.runtime.update.PendingUpdateList; import org.rumbledb.types.BuiltinTypesCatalogue; import com.esotericsoftware.kryo.Kryo; @@ -273,6 +274,20 @@ public JSoundDataFrame getDataFrame(DynamicContext context) { ); } + public boolean isUpdating() { + throw new OurBadException( + "Updating classification is not implemented for the iterator " + getClass().getCanonicalName(), + getMetadata() + ); + } + + public PendingUpdateList getPendingUpdateList() { + throw new OurBadException( + "Pending Update Lists are not implemented for the iterator " + getClass().getCanonicalName(), + getMetadata() + ); + } + public abstract Item next(); public List materialize(DynamicContext context) { From df63d110f9cc4fb7dcf5916fe635aca0f2cf5773 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 27 Mar 2023 19:03:41 +0200 Subject: [PATCH 043/119] Refactor of primitives and attempt at more efficient merge --- .../runtime/update/PendingUpdateList.java | 373 ++++++++++-------- .../primitives/DeleteFromArrayPrimitive.java | 18 +- .../primitives/DeleteFromObjectPrimitive.java | 19 +- .../primitives/InsertIntoArrayPrimitive.java | 22 +- .../primitives/InsertIntoObjectPrimitive.java | 17 +- .../primitives/RenameInObjectPrimitive.java | 30 +- .../primitives/ReplaceInArrayPrimitive.java | 32 +- .../primitives/ReplaceInObjectPrimitive.java | 28 +- .../update/primitives/UpdatePrimitive.java | 36 +- .../primitives/UpdatePrimitiveEnum.java | 14 + .../primitives/UpdatePrimitiveInterface.java | 6 +- .../primitives/UpdatePrimitiveSource.java | 57 +++ .../primitives/UpdatePrimitiveTarget.java | 22 ++ 13 files changed, 386 insertions(+), 288 deletions(-) create mode 100644 src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveEnum.java create mode 100644 src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveSource.java create mode 100644 src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveTarget.java diff --git a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java index c3ce86d452..d1b0eaa9b6 100644 --- a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java +++ b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java @@ -7,9 +7,7 @@ import org.rumbledb.items.StringItem; import org.rumbledb.runtime.update.primitives.*; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; +import java.util.*; import java.util.stream.Collectors; public class PendingUpdateList { @@ -50,174 +48,221 @@ public void applyUpdates() { } } - public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpdateList pul2) { +// public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpdateList pul2) { +// PendingUpdateList result = new PendingUpdateList(); +// HashMap> itemToUpdateMap = new HashMap<>(); +// List tempUps; +// +// for (UpdatePrimitive up : pul1.getUpdatePrimitives()) { +// result.addUpdatePrimitive(up); +// Item target = up.getTarget(); +// +// if (!itemToUpdateMap.containsKey(target)) { +// tempUps = new ArrayList<>(); +// } else { +// tempUps = itemToUpdateMap.get(target); +// } +// tempUps.add(up); +// itemToUpdateMap.put(target, tempUps); +// } +// +// for (UpdatePrimitive up : pul2.getUpdatePrimitives()) { +// result.addUpdatePrimitive(up); +// Item target = up.getTarget(); +// +// if (!itemToUpdateMap.containsKey(target)) { +// tempUps = new ArrayList<>(); +// } else { +// tempUps = itemToUpdateMap.get(target); +// } +// tempUps.add(up); +// itemToUpdateMap.put(target, tempUps); +// } +// +// for (Item target : itemToUpdateMap.keySet()) { +// List targetUpdates = itemToUpdateMap.get(target); +// +// // object +// if (target.isObject()) { +// boolean hasDeletePrimitives = targetUpdates.stream() +// .anyMatch(u -> u instanceof DeleteFromObjectPrimitive); +// boolean hasInsertPrimitives = targetUpdates.stream() +// .anyMatch(u -> u instanceof InsertIntoObjectPrimitive); +// +// if (hasInsertPrimitives) { +// ObjectItem sourceObject = +// targetUpdates +// .stream() +// .filter(u -> u instanceof InsertIntoObjectPrimitive) +// .map(u -> ((InsertIntoObjectPrimitive) u).getSourceObject()) +// .reduce(new ObjectItem(), ObjectItem::mergeWith); +// result.addUpdatePrimitive(new InsertIntoObjectPrimitive((ObjectItem) target, sourceObject)); +// } +// +// if (hasDeletePrimitives) { +// List names = +// targetUpdates +// .stream() +// .filter(u -> u instanceof DeleteFromObjectPrimitive) +// .flatMap(u -> ((DeleteFromObjectPrimitive) u).getNamesToRemove().stream()) +// .distinct() +// .collect(Collectors.toList()); +// result.addUpdatePrimitive(new DeleteFromObjectPrimitive((ObjectItem) target, names)); +// continue; +// } +// +// List renamePrimitives = +// targetUpdates +// .stream() +// .filter(u -> u instanceof RenameInObjectPrimitive) +// .collect(Collectors.toList()); +// List uniqueRenameSelectors = +// renamePrimitives +// .stream() +// .map(u -> ((RenameInObjectPrimitive) u).getTargetName()) +// .distinct() +// .collect(Collectors.toList()); +// +// if (renamePrimitives.size() != uniqueRenameSelectors.size()) { +// // TODO Throw rename on same key error jerr:JNUP0010. +// } +// +// List replacePrimitives = +// targetUpdates +// .stream() +// .filter(u -> u instanceof ReplaceInObjectPrimitive) +// .collect(Collectors.toList()); +// List uniqueReplaceSelectors = +// replacePrimitives +// .stream() +// .map(u -> ((ReplaceInObjectPrimitive) u).getTargetName()) +// .distinct() +// .collect(Collectors.toList()); +// +// if (replacePrimitives.size() != uniqueReplaceSelectors.size()) { +// // TODO Throw replace on same key error jerr:JNUP0009. +// } +// +// } +// +// // array +// if (target.isArray()) { +// boolean hasDeletePrimitives = targetUpdates.stream() +// .anyMatch(u -> u instanceof DeleteFromArrayPrimitive); +// boolean hasInsertPrimitives = targetUpdates.stream() +// .anyMatch(u -> u instanceof InsertIntoArrayPrimitive); +// +// if (hasInsertPrimitives) { +// HashMap> locatorToInsertsMap = new HashMap<>(); +// +// targetUpdates +// .stream() +// .filter(u -> u instanceof InsertIntoArrayPrimitive) +// .map(u -> (InsertIntoArrayPrimitive) u) +// .forEach(u -> { +// List temp; +// if (!locatorToInsertsMap.containsKey(u.getPositionInt())) { +// temp = new ArrayList<>(); +// } else { +// temp = locatorToInsertsMap.get(u.getPositionInt()); +// } +// temp.addAll(u.getSourceSequence()); +// locatorToInsertsMap.put(u.getPositionInt(), temp); +// }); +// +// for (IntItem intItem : locatorToInsertsMap.keySet()) { +// result.addUpdatePrimitive( +// new InsertIntoArrayPrimitive( +// (ArrayItem) target, +// intItem, +// locatorToInsertsMap.get(intItem) +// ) +// ); +// } +// } +// +// if (hasDeletePrimitives) { +// List intItems = +// targetUpdates +// .stream() +// .filter(u -> u instanceof DeleteFromArrayPrimitive) +// .map(u -> ((DeleteFromArrayPrimitive) u).getPositionInt()) +// .distinct() +// .collect(Collectors.toList()); +// for (IntItem intItem : intItems) { +// result.addUpdatePrimitive(new DeleteFromArrayPrimitive((ArrayItem) target, intItem)); +// } +// continue; +// } +// +// List replacePrimitives = +// targetUpdates +// .stream() +// .filter(u -> u instanceof ReplaceInArrayPrimitive) +// .collect(Collectors.toList()); +// List uniqueReplaceSelectors = +// replacePrimitives +// .stream() +// .map(u -> ((ReplaceInArrayPrimitive) u).getPositionInt()) +// .distinct() +// .collect(Collectors.toList()); +// +// if (replacePrimitives.size() != uniqueReplaceSelectors.size()) { +// // TODO Throw replace on same key error jerr:JNUP0009. +// } +// +// } +// } +// +// return result; +// } + + public static PendingUpdateList mergeUpdates1(PendingUpdateList pul1, PendingUpdateList pul2) { PendingUpdateList result = new PendingUpdateList(); - HashMap> itemToUpdateMap = new HashMap<>(); - List tempUps; - - for (UpdatePrimitive up : pul1.getUpdatePrimitives()) { - result.addUpdatePrimitive(up); - Item target = up.getTarget(); - - if (!itemToUpdateMap.containsKey(target)) { - tempUps = new ArrayList<>(); - } else { - tempUps = itemToUpdateMap.get(target); - } - tempUps.add(up); - itemToUpdateMap.put(target, tempUps); - } - - for (UpdatePrimitive up : pul2.getUpdatePrimitives()) { - result.addUpdatePrimitive(up); - Item target = up.getTarget(); - - if (!itemToUpdateMap.containsKey(target)) { - tempUps = new ArrayList<>(); - } else { - tempUps = itemToUpdateMap.get(target); - } - tempUps.add(up); - itemToUpdateMap.put(target, tempUps); - } - - for (Item target : itemToUpdateMap.keySet()) { - List targetUpdates = itemToUpdateMap.get(target); - - // object - if (target.isObject()) { - boolean hasDeletePrimitives = targetUpdates.stream() - .anyMatch(u -> u instanceof DeleteFromObjectPrimitive); - boolean hasInsertPrimitives = targetUpdates.stream() - .anyMatch(u -> u instanceof InsertIntoObjectPrimitive); - - if (hasInsertPrimitives) { - ObjectItem sourceObject = - targetUpdates - .stream() - .filter(u -> u instanceof InsertIntoObjectPrimitive) - .map(u -> ((InsertIntoObjectPrimitive) u).getSourceObject()) - .reduce(new ObjectItem(), ObjectItem::mergeWith); - result.addUpdatePrimitive(new InsertIntoObjectPrimitive((ObjectItem) target, sourceObject)); - } - - if (hasDeletePrimitives) { - List names = - targetUpdates - .stream() - .filter(u -> u instanceof DeleteFromObjectPrimitive) - .flatMap(u -> ((DeleteFromObjectPrimitive) u).getNamesToRemove().stream()) - .distinct() - .collect(Collectors.toList()); - result.addUpdatePrimitive(new DeleteFromObjectPrimitive((ObjectItem) target, names)); - continue; - } - - List renamePrimitives = - targetUpdates - .stream() - .filter(u -> u instanceof RenameInObjectPrimitive) - .collect(Collectors.toList()); - List uniqueRenameSelectors = - renamePrimitives - .stream() - .map(u -> ((RenameInObjectPrimitive) u).getTargetName()) - .distinct() - .collect(Collectors.toList()); - - if (renamePrimitives.size() != uniqueRenameSelectors.size()) { - // TODO Throw rename on same key error jerr:JNUP0010. - } - - List replacePrimitives = - targetUpdates - .stream() - .filter(u -> u instanceof ReplaceInObjectPrimitive) - .collect(Collectors.toList()); - List uniqueReplaceSelectors = - replacePrimitives - .stream() - .map(u -> ((ReplaceInObjectPrimitive) u).getTargetName()) - .distinct() - .collect(Collectors.toList()); - - if (replacePrimitives.size() != uniqueReplaceSelectors.size()) { - // TODO Throw replace on same key error jerr:JNUP0009. - } - - } - - // array - if (target.isArray()) { - boolean hasDeletePrimitives = targetUpdates.stream() - .anyMatch(u -> u instanceof DeleteFromArrayPrimitive); - boolean hasInsertPrimitives = targetUpdates.stream() - .anyMatch(u -> u instanceof InsertIntoArrayPrimitive); - - if (hasInsertPrimitives) { - HashMap> locatorToInsertsMap = new HashMap<>(); - - targetUpdates - .stream() - .filter(u -> u instanceof InsertIntoArrayPrimitive) - .map(u -> (InsertIntoArrayPrimitive) u) - .forEach(u -> { - List temp; - if (!locatorToInsertsMap.containsKey(u.getPositionInt())) { - temp = new ArrayList<>(); - } else { - temp = locatorToInsertsMap.get(u.getPositionInt()); - } - temp.addAll(u.getSourceSequence()); - locatorToInsertsMap.put(u.getPositionInt(), temp); - }); - - for (IntItem intItem : locatorToInsertsMap.keySet()) { - result.addUpdatePrimitive( - new InsertIntoArrayPrimitive( - (ArrayItem) target, - intItem, - locatorToInsertsMap.get(intItem) - ) - ); - } - } - - if (hasDeletePrimitives) { - List intItems = - targetUpdates - .stream() - .filter(u -> u instanceof DeleteFromArrayPrimitive) - .map(u -> ((DeleteFromArrayPrimitive) u).getPositionInt()) - .distinct() - .collect(Collectors.toList()); - for (IntItem intItem : intItems) { - result.addUpdatePrimitive(new DeleteFromArrayPrimitive((ArrayItem) target, intItem)); - } - continue; - } - - List replacePrimitives = - targetUpdates - .stream() - .filter(u -> u instanceof ReplaceInArrayPrimitive) - .collect(Collectors.toList()); - List uniqueReplaceSelectors = - replacePrimitives - .stream() - .map(u -> ((ReplaceInArrayPrimitive) u).getPositionInt()) - .distinct() - .collect(Collectors.toList()); - - if (replacePrimitives.size() != uniqueReplaceSelectors.size()) { - // TODO Throw replace on same key error jerr:JNUP0009. + HashMap>> itemToUpdateMap = new HashMap<>(); + HashMap> temp; + Set tempDistinctSources; + + for (List us : Arrays.asList(pul1.getUpdatePrimitives(), pul2.getUpdatePrimitives())) { + for (UpdatePrimitive u : us) { + UpdatePrimitiveTarget target = u.getTarget(); + temp = itemToUpdateMap.getOrDefault(target, new HashMap<>()); + + if (u instanceof DeleteFromArrayPrimitive) { + tempDistinctSources = temp.getOrDefault(UpdatePrimitiveEnum.DELETE_FROM_ARRAY, new HashSet<>()); + tempDistinctSources.add(u.getSource()); + temp.put(UpdatePrimitiveEnum.DELETE_FROM_ARRAY, tempDistinctSources); + } else if (u instanceof InsertIntoArrayPrimitive) { + tempDistinctSources = temp.getOrDefault(UpdatePrimitiveEnum.INSERT_INTO_ARRAY, new HashSet<>()); + tempDistinctSources.add(u.getSource()); + temp.put(UpdatePrimitiveEnum.INSERT_INTO_ARRAY, tempDistinctSources); + } else if (u instanceof ReplaceInArrayPrimitive) { + tempDistinctSources = temp.getOrDefault(UpdatePrimitiveEnum.REPLACE_IN_ARRAY, new HashSet<>()); + tempDistinctSources.add(u.getSource()); + temp.put(UpdatePrimitiveEnum.REPLACE_IN_ARRAY, tempDistinctSources); + } else if (u instanceof DeleteFromObjectPrimitive) { + tempDistinctSources = temp.getOrDefault(UpdatePrimitiveEnum.DELETE_FROM_OBJECT, new HashSet<>()); + tempDistinctSources.add(u.getSource()); + temp.put(UpdatePrimitiveEnum.DELETE_FROM_OBJECT, tempDistinctSources); + } else if (u instanceof InsertIntoObjectPrimitive) { + tempDistinctSources = temp.getOrDefault(UpdatePrimitiveEnum.INSERT_INTO_OBJECT, new HashSet<>()); + tempDistinctSources.add(u.getSource()); + temp.put(UpdatePrimitiveEnum.INSERT_INTO_OBJECT, tempDistinctSources); + } else if (u instanceof ReplaceInObjectPrimitive) { + tempDistinctSources = temp.getOrDefault(UpdatePrimitiveEnum.REPLACE_IN_OBJECT, new HashSet<>()); + tempDistinctSources.add(u.getSource()); + temp.put(UpdatePrimitiveEnum.REPLACE_IN_OBJECT, tempDistinctSources); + } else if (u instanceof RenameInObjectPrimitive) { + tempDistinctSources = temp.getOrDefault(UpdatePrimitiveEnum.RENAME_IN_OBJECT, new HashSet<>()); + tempDistinctSources.add(u.getSource()); + temp.put(UpdatePrimitiveEnum.RENAME_IN_OBJECT, tempDistinctSources); } + itemToUpdateMap.put(target, temp); } } return result; } - } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java index fccf4572ef..2f03e2ba1b 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java @@ -1,38 +1,28 @@ package org.rumbledb.runtime.update.primitives; -import org.rumbledb.api.Item; import org.rumbledb.items.ArrayItem; import org.rumbledb.items.IntItem; public class DeleteFromArrayPrimitive extends UpdatePrimitive { - private ArrayItem targetArray; - - private IntItem positionInt; - public DeleteFromArrayPrimitive(ArrayItem targetArray, IntItem positionInt) { + super(targetArray, positionInt); if (positionInt.getIntValue() < 0 || positionInt.getIntValue() >= targetArray.getSize()) { // TODO throw error or do nothing? } - this.targetArray = targetArray; - this.positionInt = positionInt; } public ArrayItem getTargetArray() { - return targetArray; + return (ArrayItem) target.getMainTarget(); } public IntItem getPositionInt() { - return positionInt; + return (IntItem) source.getSingletonSource(); } @Override public void apply() { - this.targetArray.removeItemAt(this.positionInt.getIntValue()); + this.getTargetArray().removeItemAt(this.getPositionInt().getIntValue()); } - @Override - public Item getTarget() { - return targetArray; - } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java index 71ff5b921e..13f9ed6128 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java @@ -9,32 +9,23 @@ public class DeleteFromObjectPrimitive extends UpdatePrimitive { - private ObjectItem targetObject; - - private List namesToRemove; - public DeleteFromObjectPrimitive(ObjectItem targetObject, List namesToRemove) { - this.targetObject = targetObject; - this.namesToRemove = namesToRemove; + super(targetObject, namesToRemove); } public ObjectItem getTargetObject() { - return targetObject; + return (ObjectItem) target.getMainTarget(); } public List getNamesToRemove() { - return namesToRemove; + return (List) source.getSourceItems(); } @Override public void apply() { - for (String str : this.namesToRemove.stream().map(StringItem::getStringValue).collect(Collectors.toList())) { - this.targetObject.removeItemByKey(str); + for (String str : this.getNamesToRemove().stream().map(StringItem::getStringValue).collect(Collectors.toList())) { + this.getTargetObject().removeItemByKey(str); } } - @Override - public Item getTarget() { - return targetObject; - } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java index b7b6eb0492..7133d3f643 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java @@ -8,40 +8,28 @@ public class InsertIntoArrayPrimitive extends UpdatePrimitive { - private ArrayItem targetArray; - - private IntItem positionInt; - - private List sourceSequence; - public InsertIntoArrayPrimitive(ArrayItem targetArray, IntItem positionInt, List sourceSequence) { + super(targetArray, positionInt, sourceSequence); if (positionInt.getIntValue() < 0 || positionInt.getIntValue() >= targetArray.getSize()) { // TODO throw error or do nothing? } - this.targetArray = targetArray; - this.positionInt = positionInt; - this.sourceSequence = sourceSequence; } public ArrayItem getTargetArray() { - return targetArray; + return (ArrayItem) target.getMainTarget(); } public IntItem getPositionInt() { - return positionInt; + return (IntItem) source.getLocator(); } public List getSourceSequence() { - return sourceSequence; + return (List) source.getSourceItems(); } @Override public void apply() { - this.targetArray.putItemsAt(this.sourceSequence, this.positionInt.getIntValue()); + this.getTargetArray().putItemsAt(this.getSourceSequence(), this.getPositionInt().getIntValue()); } - @Override - public Item getTarget() { - return targetArray; - } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java index f601f58009..119e8d5dc3 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java @@ -5,31 +5,24 @@ public class InsertIntoObjectPrimitive extends UpdatePrimitive { - private ObjectItem targetObject; - private ObjectItem sourceObject; public InsertIntoObjectPrimitive(ObjectItem targetObject, ObjectItem sourceObject) { - this.targetObject = targetObject; - this.sourceObject = sourceObject; + super(targetObject, sourceObject); } public ObjectItem getTargetObject() { - return targetObject; + return (ObjectItem) target.getMainTarget(); } public ObjectItem getSourceObject() { - return sourceObject; + return (ObjectItem) source.getSingletonSource(); } @Override public void apply() { - for (String key : this.sourceObject.getKeys()) { - this.targetObject.putItemByKey(key, this.sourceObject.getItemByKey(key)); + for (String key : this.getSourceObject().getKeys()) { + this.getTargetObject().putItemByKey(key, this.getTargetObject().getItemByKey(key)); } } - @Override - public Item getTarget() { - return targetObject; - } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java index fa0186717c..4e4a9d5733 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java @@ -6,43 +6,31 @@ public class RenameInObjectPrimitive extends UpdatePrimitive { - private ObjectItem targetObject; - - private StringItem targetName; - - private StringItem replacementName; - public RenameInObjectPrimitive(ObjectItem targetObject, StringItem targetName, StringItem replacementName) { - this.targetObject = targetObject; - this.targetName = targetName; - this.replacementName = replacementName; + super(targetObject, targetName, replacementName); } public ObjectItem getTargetObject() { - return targetObject; + return (ObjectItem) target.getMainTarget(); } public StringItem getTargetName() { - return targetName; + return (StringItem) source.getLocator(); } public StringItem getReplacementName() { - return replacementName; + return (StringItem) source.getSingletonSource(); } @Override public void apply() { - String name = this.targetName.getStringValue(); - if (this.targetObject.getKeys().contains(name)) { - Item item = this.targetObject.getItemByKey(name); - this.targetObject.removeItemByKey(name); - this.targetObject.putItemByKey(this.replacementName.getStringValue(), item); + String name = this.getTargetName().getStringValue(); + if (this.getTargetObject().getKeys().contains(name)) { + Item item = this.getTargetObject().getItemByKey(name); + this.getTargetObject().removeItemByKey(name); + this.getTargetObject().putItemByKey(this.getTargetName().getStringValue(), item); } // TODO: implement replace and rename methods for Array & Object to avoid deletion and append } - @Override - public Item getTarget() { - return targetObject; - } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java index 9043f8a29a..6f81ed6262 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java @@ -6,45 +6,33 @@ public class ReplaceInArrayPrimitive extends UpdatePrimitive { - private ArrayItem targetArray; - - private IntItem positionInt; - - private Item replacementItem; - public ReplaceInArrayPrimitive(ArrayItem targetArray, IntItem positionInt, Item replacementItem) { - this.targetArray = targetArray; - this.positionInt = positionInt; - this.replacementItem = replacementItem; + super(targetArray, positionInt, replacementItem); } public ArrayItem getTargetArray() { - return targetArray; + return (ArrayItem) target.getMainTarget(); } public IntItem getPositionInt() { - return positionInt; + return (IntItem) source.getLocator(); } public Item getReplacementItem() { - return replacementItem; + return source.getSingletonSource(); } @Override public void apply() { - int index = this.positionInt.getIntValue() - 1; - if (index >= 0 || index < this.targetArray.getSize()) { - this.targetArray.removeItemAt(index); - if (index == this.targetArray.getSize()) { - this.targetArray.append(this.replacementItem); + int index = this.getPositionInt().getIntValue() - 1; + if (index >= 0 || index < this.getTargetArray().getSize()) { + this.getTargetArray().removeItemAt(index); + if (index == this.getTargetArray().getSize()) { + this.getTargetArray().append(this.getReplacementItem()); } else { - this.targetArray.putItemAt(this.replacementItem, index); + this.getTargetArray().putItemAt(this.getReplacementItem(), index); } } } - @Override - public Item getTarget() { - return targetArray; - } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java index 31d211131c..f98f68b39c 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java @@ -6,41 +6,29 @@ public class ReplaceInObjectPrimitive extends UpdatePrimitive { - private ObjectItem targetObject; - - private StringItem targetName; - - private Item replacementItem; - public ReplaceInObjectPrimitive(ObjectItem targetObject, StringItem targetName, Item replacementItem) { - this.targetObject = targetObject; - this.targetName = targetName; - this.replacementItem = replacementItem; + super(targetObject, targetName, replacementItem); } public ObjectItem getTargetObject() { - return targetObject; + return (ObjectItem) target.getMainTarget(); } public StringItem getTargetName() { - return targetName; + return (StringItem) source.getLocator(); } public Item getReplacementItem() { - return replacementItem; + return source.getSingletonSource(); } @Override public void apply() { - String name = this.targetName.getStringValue(); - if (this.targetObject.getKeys().contains(name)) { - this.targetObject.removeItemByKey(name); - this.targetObject.putItemByKey(name, this.replacementItem); + String name = this.getTargetName().getStringValue(); + if (this.getTargetObject().getKeys().contains(name)) { + this.getTargetObject().removeItemByKey(name); + this.getTargetObject().putItemByKey(name, this.getReplacementItem()); } } - @Override - public Item getTarget() { - return targetObject; - } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java index baee723039..b2421098a5 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java @@ -2,11 +2,45 @@ import org.rumbledb.api.Item; +import java.util.List; + public abstract class UpdatePrimitive implements UpdatePrimitiveInterface { + protected UpdatePrimitiveTarget target; + + protected UpdatePrimitiveSource source; + + public UpdatePrimitive(UpdatePrimitiveTarget target, UpdatePrimitiveSource source) { + this.target = target; + this.source = source; + } + + public UpdatePrimitive(Item target, Item locator, Item source) { + this(new UpdatePrimitiveTarget(target), new UpdatePrimitiveSource(source, locator)); + } + + public UpdatePrimitive(Item target, Item locator, List source) { + this(new UpdatePrimitiveTarget(target), new UpdatePrimitiveSource(source, locator)); + } + + public UpdatePrimitive(Item target, Item source) { + this(new UpdatePrimitiveTarget(target), new UpdatePrimitiveSource(source)); + } + + public UpdatePrimitive(Item target, List source) { + this(new UpdatePrimitiveTarget(target), new UpdatePrimitiveSource(source)); + } + @Override public abstract void apply(); @Override - public abstract Item getTarget(); + public UpdatePrimitiveTarget getTarget() { + return target; + } + + @Override + public UpdatePrimitiveSource getSource() { + return source; + } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveEnum.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveEnum.java new file mode 100644 index 0000000000..e2bc0dd65d --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveEnum.java @@ -0,0 +1,14 @@ +package org.rumbledb.runtime.update.primitives; + +public enum UpdatePrimitiveEnum { + + DELETE_FROM_ARRAY, + DELETE_FROM_OBJECT, + INSERT_INTO_ARRAY, + INSERT_INTO_OBJECT, + REPLACE_IN_ARRAY, + REPLACE_IN_OBJECT, + RENAME_IN_OBJECT; + + +} diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveInterface.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveInterface.java index db975a38b9..46d8200152 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveInterface.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveInterface.java @@ -1,12 +1,12 @@ package org.rumbledb.runtime.update.primitives; -import org.rumbledb.api.Item; - import java.io.Serializable; public interface UpdatePrimitiveInterface extends Serializable { void apply(); - Item getTarget(); + UpdatePrimitiveTarget getTarget(); + + UpdatePrimitiveSource getSource(); } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveSource.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveSource.java new file mode 100644 index 0000000000..08b264790c --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveSource.java @@ -0,0 +1,57 @@ +package org.rumbledb.runtime.update.primitives; + +import org.rumbledb.api.Item; +import org.rumbledb.exceptions.OurBadException; + +import java.util.Collections; +import java.util.List; + +public class UpdatePrimitiveSource { + + private List sourceItems; + + private Item locator; + + public UpdatePrimitiveSource(List sourceItems, Item locator) { + this.sourceItems = sourceItems; + this.locator = locator; + } + + public UpdatePrimitiveSource(Item sourceItem, Item locator) { + this(Collections.singletonList(sourceItem), locator); + } + + public UpdatePrimitiveSource(List sourceItems) { + this(sourceItems, null); + } + + public UpdatePrimitiveSource(Item sourceItem) { + this(sourceItem, null); + } + + public boolean isSingleton() { + return this.sourceItems.size() == 1; + } + + public Item getSingletonSource() { + if (!this.isSingleton()) { + throw new OurBadException("Invalid call to getSingletonSource when source of UpdatePrimitiveSource is a list"); + } + return this.sourceItems.get(0); + } + + public List getSourceItems() { + return sourceItems; + } + public Item getLocator() { + if (!this.hasLocator()) { + throw new OurBadException("Invalid call to getLocator for UpdatePrimitiveTarget without locator"); + } + return locator; + } + + public boolean hasLocator() { + return this.locator != null; + } + +} diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveTarget.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveTarget.java new file mode 100644 index 0000000000..5010b580d0 --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveTarget.java @@ -0,0 +1,22 @@ +package org.rumbledb.runtime.update.primitives; + +import org.rumbledb.api.Item; +import org.rumbledb.exceptions.OurBadException; + +public class UpdatePrimitiveTarget { + + private Item mainTarget; + + public UpdatePrimitiveTarget(Item mainTarget, Item locator) { + this.mainTarget = mainTarget; + } + + public UpdatePrimitiveTarget(Item mainTarget) { + this(mainTarget, null); + } + + public Item getMainTarget() { + return mainTarget; + } + +} From 6c16a26866f62658b3ebb91bc296c149d65efda6 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Tue, 28 Mar 2023 02:26:35 +0200 Subject: [PATCH 044/119] Refactor update primitives to follow Target, Selector, Source logical model --- .../primitives/DeleteFromArrayPrimitive.java | 4 +- .../primitives/DeleteFromObjectPrimitive.java | 16 +++-- .../primitives/InsertIntoArrayPrimitive.java | 13 +++- .../primitives/InsertIntoObjectPrimitive.java | 23 ++++++- .../primitives/RenameInObjectPrimitive.java | 4 +- .../primitives/ReplaceInArrayPrimitive.java | 4 +- .../primitives/ReplaceInObjectPrimitive.java | 4 +- .../update/primitives/UpdatePrimitive.java | 43 ++++++++++--- .../primitives/UpdatePrimitiveInterface.java | 9 ++- .../primitives/UpdatePrimitiveSelector.java | 60 +++++++++++++++++++ .../primitives/UpdatePrimitiveSource.java | 53 +++++++--------- .../primitives/UpdatePrimitiveTarget.java | 51 +++++++++++++--- 12 files changed, 219 insertions(+), 65 deletions(-) create mode 100644 src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveSelector.java diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java index 2f03e2ba1b..b8f5c9e976 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java @@ -6,14 +6,14 @@ public class DeleteFromArrayPrimitive extends UpdatePrimitive { public DeleteFromArrayPrimitive(ArrayItem targetArray, IntItem positionInt) { - super(targetArray, positionInt); + super(targetArray, positionInt, positionInt); if (positionInt.getIntValue() < 0 || positionInt.getIntValue() >= targetArray.getSize()) { // TODO throw error or do nothing? } } public ArrayItem getTargetArray() { - return (ArrayItem) target.getMainTarget(); + return target.getTargetAsArray(); } public IntItem getPositionInt() { diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java index 13f9ed6128..701d846d38 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java @@ -1,6 +1,5 @@ package org.rumbledb.runtime.update.primitives; -import org.rumbledb.api.Item; import org.rumbledb.items.ObjectItem; import org.rumbledb.items.StringItem; @@ -14,18 +13,27 @@ public DeleteFromObjectPrimitive(ObjectItem targetObject, List names } public ObjectItem getTargetObject() { - return (ObjectItem) target.getMainTarget(); + return target.getTargetAsObject(); } public List getNamesToRemove() { - return (List) source.getSourceItems(); + return source.getSourceAsListOfStrings(); } @Override public void apply() { - for (String str : this.getNamesToRemove().stream().map(StringItem::getStringValue).collect(Collectors.toList())) { + for ( + String str : this.getNamesToRemove().stream().map(StringItem::getStringValue).collect(Collectors.toList()) + ) { this.getTargetObject().removeItemByKey(str); } } + public static UpdatePrimitiveSource mergeSources(UpdatePrimitiveSource first, UpdatePrimitiveSource second) { + List merged = first.getSourceAsListOfStrings(); + merged.addAll(second.getSourceAsListOfStrings()); + merged = merged.stream().distinct().collect(Collectors.toList()); + return new UpdatePrimitiveSource(merged); + } + } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java index 7133d3f643..1487a833b7 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java @@ -4,6 +4,7 @@ import org.rumbledb.items.ArrayItem; import org.rumbledb.items.IntItem; +import java.util.ArrayList; import java.util.List; public class InsertIntoArrayPrimitive extends UpdatePrimitive { @@ -16,15 +17,15 @@ public InsertIntoArrayPrimitive(ArrayItem targetArray, IntItem positionInt, List } public ArrayItem getTargetArray() { - return (ArrayItem) target.getMainTarget(); + return target.getTargetAsArray(); } public IntItem getPositionInt() { - return (IntItem) source.getLocator(); + return selector.getSelectorAsInt(); } public List getSourceSequence() { - return (List) source.getSourceItems(); + return source.getSourceAsListOfItems(); } @Override @@ -32,4 +33,10 @@ public void apply() { this.getTargetArray().putItemsAt(this.getSourceSequence(), this.getPositionInt().getIntValue()); } + public static UpdatePrimitiveSource mergeSources(UpdatePrimitiveSource first, UpdatePrimitiveSource second) { + List merged = new ArrayList<>(first.getSource()); + merged.addAll(second.getSource()); + return new UpdatePrimitiveSource(merged); + } + } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java index 119e8d5dc3..e255d4d1e3 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java @@ -1,6 +1,7 @@ package org.rumbledb.runtime.update.primitives; -import org.rumbledb.api.Item; +import org.rumbledb.exceptions.DuplicateObjectKeyException; +import org.rumbledb.exceptions.OurBadException; import org.rumbledb.items.ObjectItem; public class InsertIntoObjectPrimitive extends UpdatePrimitive { @@ -11,7 +12,7 @@ public InsertIntoObjectPrimitive(ObjectItem targetObject, ObjectItem sourceObjec } public ObjectItem getTargetObject() { - return (ObjectItem) target.getMainTarget(); + return target.getTargetAsObject(); } public ObjectItem getSourceObject() { @@ -25,4 +26,22 @@ public void apply() { } } + public static UpdatePrimitiveSource mergeSources(UpdatePrimitiveSource first, UpdatePrimitiveSource second) { + ObjectItem merged = new ObjectItem(); + ObjectItem objFirst = (ObjectItem) first.getSingletonSource(); + ObjectItem objSecond = (ObjectItem) second.getSingletonSource(); + try { + for (String otherKey : objFirst.getKeys()) { + merged.putItemByKey(otherKey, objFirst.getItemByKey(otherKey)); + } + for (String otherKey : objSecond.getKeys()) { + merged.putItemByKey(otherKey, objSecond.getItemByKey(otherKey)); + } + } catch (DuplicateObjectKeyException e) { + throw new OurBadException("SHOULD THROW SMTH ELSE"); + // TODO THROW jerr:JNUP0005 INSTEAD ON COLLISION + } + return new UpdatePrimitiveSource(merged); + } + } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java index 4e4a9d5733..9ef5885b48 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java @@ -11,11 +11,11 @@ public RenameInObjectPrimitive(ObjectItem targetObject, StringItem targetName, S } public ObjectItem getTargetObject() { - return (ObjectItem) target.getMainTarget(); + return target.getTargetAsObject(); } public StringItem getTargetName() { - return (StringItem) source.getLocator(); + return selector.getSelectorAsString(); } public StringItem getReplacementName() { diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java index 6f81ed6262..8fe291171b 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java @@ -11,11 +11,11 @@ public ReplaceInArrayPrimitive(ArrayItem targetArray, IntItem positionInt, Item } public ArrayItem getTargetArray() { - return (ArrayItem) target.getMainTarget(); + return target.getTargetAsArray(); } public IntItem getPositionInt() { - return (IntItem) source.getLocator(); + return selector.getSelectorAsInt(); } public Item getReplacementItem() { diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java index f98f68b39c..d024dd6977 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java @@ -11,11 +11,11 @@ public ReplaceInObjectPrimitive(ObjectItem targetObject, StringItem targetName, } public ObjectItem getTargetObject() { - return (ObjectItem) target.getMainTarget(); + return target.getTargetAsObject(); } public StringItem getTargetName() { - return (StringItem) source.getLocator(); + return selector.getSelectorAsString(); } public Item getReplacementItem() { diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java index b2421098a5..12be07d504 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java @@ -1,44 +1,71 @@ package org.rumbledb.runtime.update.primitives; import org.rumbledb.api.Item; +import org.rumbledb.exceptions.OurBadException; import java.util.List; public abstract class UpdatePrimitive implements UpdatePrimitiveInterface { protected UpdatePrimitiveTarget target; - + protected UpdatePrimitiveSelector selector; protected UpdatePrimitiveSource source; - public UpdatePrimitive(UpdatePrimitiveTarget target, UpdatePrimitiveSource source) { + public UpdatePrimitive( + UpdatePrimitiveTarget target, + UpdatePrimitiveSelector selector, + UpdatePrimitiveSource source + ) { this.target = target; + this.selector = selector; this.source = source; } - public UpdatePrimitive(Item target, Item locator, Item source) { - this(new UpdatePrimitiveTarget(target), new UpdatePrimitiveSource(source, locator)); + public UpdatePrimitive(Item target, Item selector, Item source) { + this( + new UpdatePrimitiveTarget(target), + new UpdatePrimitiveSelector(selector), + new UpdatePrimitiveSource(source) + ); } - public UpdatePrimitive(Item target, Item locator, List source) { - this(new UpdatePrimitiveTarget(target), new UpdatePrimitiveSource(source, locator)); + public UpdatePrimitive(Item target, Item selector, List source) { + this( + new UpdatePrimitiveTarget(target), + new UpdatePrimitiveSelector(selector), + new UpdatePrimitiveSource(source) + ); } public UpdatePrimitive(Item target, Item source) { - this(new UpdatePrimitiveTarget(target), new UpdatePrimitiveSource(source)); + this(new UpdatePrimitiveTarget(target), null, new UpdatePrimitiveSource(source)); } public UpdatePrimitive(Item target, List source) { - this(new UpdatePrimitiveTarget(target), new UpdatePrimitiveSource(source)); + this(new UpdatePrimitiveTarget(target), null, new UpdatePrimitiveSource(source)); } @Override public abstract void apply(); + @Override + public boolean hasSelector() { + return this.selector == null; + } + @Override public UpdatePrimitiveTarget getTarget() { return target; } + @Override + public UpdatePrimitiveSelector getSelector() { + if (!this.hasSelector()) { + throw new OurBadException("Invalid call to getSelector when selector is null"); + } + return selector; + } + @Override public UpdatePrimitiveSource getSource() { return source; diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveInterface.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveInterface.java index 46d8200152..ff83a3cf17 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveInterface.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveInterface.java @@ -1,12 +1,15 @@ package org.rumbledb.runtime.update.primitives; -import java.io.Serializable; - -public interface UpdatePrimitiveInterface extends Serializable { +public interface UpdatePrimitiveInterface { void apply(); + boolean hasSelector(); + UpdatePrimitiveTarget getTarget(); + UpdatePrimitiveSelector getSelector(); + UpdatePrimitiveSource getSource(); + } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveSelector.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveSelector.java new file mode 100644 index 0000000000..72745c91a6 --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveSelector.java @@ -0,0 +1,60 @@ +package org.rumbledb.runtime.update.primitives; + +import org.rumbledb.api.Item; +import org.rumbledb.exceptions.OurBadException; +import org.rumbledb.items.IntItem; +import org.rumbledb.items.StringItem; + + +public class UpdatePrimitiveSelector { + + private Item selector; + + public UpdatePrimitiveSelector(Item selector) { + if (!selector.isString() && !selector.isNumeric()) { + throw new OurBadException("Locators of primitives must be strings or numeric"); + } + this.selector = selector; + } + + public Item getSelector() { + return selector; + } + + public StringItem getSelectorAsString() { + if (!this.isString()) { + throw new OurBadException("Invalid call to getSelectorAsString"); + } + return (StringItem) this.selector; + } + + public IntItem getSelectorAsInt() { + if (!this.isNumeric()) { + throw new OurBadException("Invalid call to getSelectorAsInt"); + } + return (IntItem) this.selector; + } + + public boolean isString() { + return this.selector.isString(); + } + + public boolean isNumeric() { + return this.selector.isNumeric(); + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + UpdatePrimitiveSelector that = (UpdatePrimitiveSelector) o; + return selector.equals(that.selector); + } + + @Override + public int hashCode() { + return selector.hashCode(); + } +} diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveSource.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveSource.java index 08b264790c..380058200b 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveSource.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveSource.java @@ -1,57 +1,50 @@ package org.rumbledb.runtime.update.primitives; import org.rumbledb.api.Item; -import org.rumbledb.exceptions.OurBadException; +import org.rumbledb.items.StringItem; +import java.util.ArrayList; import java.util.Collections; import java.util.List; public class UpdatePrimitiveSource { - private List sourceItems; + private List source; - private Item locator; - - public UpdatePrimitiveSource(List sourceItems, Item locator) { - this.sourceItems = sourceItems; - this.locator = locator; - } - - public UpdatePrimitiveSource(Item sourceItem, Item locator) { - this(Collections.singletonList(sourceItem), locator); - } - - public UpdatePrimitiveSource(List sourceItems) { - this(sourceItems, null); + public UpdatePrimitiveSource(List source) { + this.source = source; } - public UpdatePrimitiveSource(Item sourceItem) { - this(sourceItem, null); + public UpdatePrimitiveSource(Item source) { + this.source = Collections.singletonList(source); } - public boolean isSingleton() { - return this.sourceItems.size() == 1; + public List getSource() { + return source; } public Item getSingletonSource() { - if (!this.isSingleton()) { - throw new OurBadException("Invalid call to getSingletonSource when source of UpdatePrimitiveSource is a list"); + if (this.isSingleton()) { + return this.source.get(0); } - return this.sourceItems.get(0); + // TODO: Find out if error + return null; } - public List getSourceItems() { - return sourceItems; + public boolean isSingleton() { + return this.source.size() == 1; } - public Item getLocator() { - if (!this.hasLocator()) { - throw new OurBadException("Invalid call to getLocator for UpdatePrimitiveTarget without locator"); + + public List getSourceAsListOfStrings() { + List result = new ArrayList<>(); + for (Item item : this.source) { + result.add((StringItem) item); } - return locator; + return result; } - public boolean hasLocator() { - return this.locator != null; + public List getSourceAsListOfItems() { + return new ArrayList<>(this.source); } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveTarget.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveTarget.java index 5010b580d0..b356ddd2ad 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveTarget.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveTarget.java @@ -2,21 +2,58 @@ import org.rumbledb.api.Item; import org.rumbledb.exceptions.OurBadException; +import org.rumbledb.items.ArrayItem; +import org.rumbledb.items.ObjectItem; public class UpdatePrimitiveTarget { - private Item mainTarget; + private Item target; - public UpdatePrimitiveTarget(Item mainTarget, Item locator) { - this.mainTarget = mainTarget; + public UpdatePrimitiveTarget(Item target) { + if (!target.isArray() && !target.isObject()) { + throw new OurBadException("Targets of primitives must be arrays or objects"); + } + this.target = target; } - public UpdatePrimitiveTarget(Item mainTarget) { - this(mainTarget, null); + public Item getTarget() { + return target; } - public Item getMainTarget() { - return mainTarget; + public ArrayItem getTargetAsArray() { + if (!this.isArray()) { + throw new OurBadException("Invalid call to getTargetAsArray"); + } + return (ArrayItem) this.target; } + public ObjectItem getTargetAsObject() { + if (!this.isArray()) { + throw new OurBadException("Invalid call to getTargetAsObject"); + } + return (ObjectItem) this.target; + } + + public boolean isArray() { + return this.target.isArray(); + } + + public boolean isObject() { + return this.target.isObject(); + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + UpdatePrimitiveTarget that = (UpdatePrimitiveTarget) o; + return target.equals(that.target); + } + + @Override + public int hashCode() { + return target.hashCode(); + } } From 2f9c63caba5a6871cafc7b0951f097c5fbd24b75 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Tue, 28 Mar 2023 02:26:58 +0200 Subject: [PATCH 045/119] Implement hashmap version of merge updates --- .../runtime/update/PendingUpdateList.java | 523 +++++++++++------- .../primitives/UpdatePrimitiveEnum.java | 2 +- 2 files changed, 326 insertions(+), 199 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java index d1b0eaa9b6..da2ca9db13 100644 --- a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java +++ b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java @@ -1,14 +1,12 @@ package org.rumbledb.runtime.update; -import org.rumbledb.api.Item; -import org.rumbledb.items.ArrayItem; +import org.rumbledb.exceptions.OurBadException; import org.rumbledb.items.IntItem; import org.rumbledb.items.ObjectItem; import org.rumbledb.items.StringItem; import org.rumbledb.runtime.update.primitives.*; import java.util.*; -import java.util.stream.Collectors; public class PendingUpdateList { @@ -48,217 +46,346 @@ public void applyUpdates() { } } -// public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpdateList pul2) { -// PendingUpdateList result = new PendingUpdateList(); -// HashMap> itemToUpdateMap = new HashMap<>(); -// List tempUps; -// -// for (UpdatePrimitive up : pul1.getUpdatePrimitives()) { -// result.addUpdatePrimitive(up); -// Item target = up.getTarget(); -// -// if (!itemToUpdateMap.containsKey(target)) { -// tempUps = new ArrayList<>(); -// } else { -// tempUps = itemToUpdateMap.get(target); -// } -// tempUps.add(up); -// itemToUpdateMap.put(target, tempUps); -// } -// -// for (UpdatePrimitive up : pul2.getUpdatePrimitives()) { -// result.addUpdatePrimitive(up); -// Item target = up.getTarget(); -// -// if (!itemToUpdateMap.containsKey(target)) { -// tempUps = new ArrayList<>(); -// } else { -// tempUps = itemToUpdateMap.get(target); -// } -// tempUps.add(up); -// itemToUpdateMap.put(target, tempUps); -// } -// -// for (Item target : itemToUpdateMap.keySet()) { -// List targetUpdates = itemToUpdateMap.get(target); -// -// // object -// if (target.isObject()) { -// boolean hasDeletePrimitives = targetUpdates.stream() -// .anyMatch(u -> u instanceof DeleteFromObjectPrimitive); -// boolean hasInsertPrimitives = targetUpdates.stream() -// .anyMatch(u -> u instanceof InsertIntoObjectPrimitive); -// -// if (hasInsertPrimitives) { -// ObjectItem sourceObject = -// targetUpdates -// .stream() -// .filter(u -> u instanceof InsertIntoObjectPrimitive) -// .map(u -> ((InsertIntoObjectPrimitive) u).getSourceObject()) -// .reduce(new ObjectItem(), ObjectItem::mergeWith); -// result.addUpdatePrimitive(new InsertIntoObjectPrimitive((ObjectItem) target, sourceObject)); -// } -// -// if (hasDeletePrimitives) { -// List names = -// targetUpdates -// .stream() -// .filter(u -> u instanceof DeleteFromObjectPrimitive) -// .flatMap(u -> ((DeleteFromObjectPrimitive) u).getNamesToRemove().stream()) -// .distinct() -// .collect(Collectors.toList()); -// result.addUpdatePrimitive(new DeleteFromObjectPrimitive((ObjectItem) target, names)); -// continue; -// } -// -// List renamePrimitives = -// targetUpdates -// .stream() -// .filter(u -> u instanceof RenameInObjectPrimitive) -// .collect(Collectors.toList()); -// List uniqueRenameSelectors = -// renamePrimitives -// .stream() -// .map(u -> ((RenameInObjectPrimitive) u).getTargetName()) -// .distinct() -// .collect(Collectors.toList()); -// -// if (renamePrimitives.size() != uniqueRenameSelectors.size()) { -// // TODO Throw rename on same key error jerr:JNUP0010. -// } -// -// List replacePrimitives = -// targetUpdates -// .stream() -// .filter(u -> u instanceof ReplaceInObjectPrimitive) -// .collect(Collectors.toList()); -// List uniqueReplaceSelectors = -// replacePrimitives -// .stream() -// .map(u -> ((ReplaceInObjectPrimitive) u).getTargetName()) -// .distinct() -// .collect(Collectors.toList()); -// -// if (replacePrimitives.size() != uniqueReplaceSelectors.size()) { -// // TODO Throw replace on same key error jerr:JNUP0009. -// } -// -// } -// -// // array -// if (target.isArray()) { -// boolean hasDeletePrimitives = targetUpdates.stream() -// .anyMatch(u -> u instanceof DeleteFromArrayPrimitive); -// boolean hasInsertPrimitives = targetUpdates.stream() -// .anyMatch(u -> u instanceof InsertIntoArrayPrimitive); -// -// if (hasInsertPrimitives) { -// HashMap> locatorToInsertsMap = new HashMap<>(); -// -// targetUpdates -// .stream() -// .filter(u -> u instanceof InsertIntoArrayPrimitive) -// .map(u -> (InsertIntoArrayPrimitive) u) -// .forEach(u -> { -// List temp; -// if (!locatorToInsertsMap.containsKey(u.getPositionInt())) { -// temp = new ArrayList<>(); -// } else { -// temp = locatorToInsertsMap.get(u.getPositionInt()); -// } -// temp.addAll(u.getSourceSequence()); -// locatorToInsertsMap.put(u.getPositionInt(), temp); -// }); -// -// for (IntItem intItem : locatorToInsertsMap.keySet()) { -// result.addUpdatePrimitive( -// new InsertIntoArrayPrimitive( -// (ArrayItem) target, -// intItem, -// locatorToInsertsMap.get(intItem) -// ) -// ); -// } -// } -// -// if (hasDeletePrimitives) { -// List intItems = -// targetUpdates -// .stream() -// .filter(u -> u instanceof DeleteFromArrayPrimitive) -// .map(u -> ((DeleteFromArrayPrimitive) u).getPositionInt()) -// .distinct() -// .collect(Collectors.toList()); -// for (IntItem intItem : intItems) { -// result.addUpdatePrimitive(new DeleteFromArrayPrimitive((ArrayItem) target, intItem)); -// } -// continue; -// } -// -// List replacePrimitives = -// targetUpdates -// .stream() -// .filter(u -> u instanceof ReplaceInArrayPrimitive) -// .collect(Collectors.toList()); -// List uniqueReplaceSelectors = -// replacePrimitives -// .stream() -// .map(u -> ((ReplaceInArrayPrimitive) u).getPositionInt()) -// .distinct() -// .collect(Collectors.toList()); -// -// if (replacePrimitives.size() != uniqueReplaceSelectors.size()) { -// // TODO Throw replace on same key error jerr:JNUP0009. -// } -// -// } -// } -// -// return result; -// } + // public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpdateList pul2) { + // PendingUpdateList result = new PendingUpdateList(); + // HashMap> itemToUpdateMap = new HashMap<>(); + // List tempUps; + // + // for (UpdatePrimitive up : pul1.getUpdatePrimitives()) { + // result.addUpdatePrimitive(up); + // Item target = up.getTarget(); + // + // if (!itemToUpdateMap.containsKey(target)) { + // tempUps = new ArrayList<>(); + // } else { + // tempUps = itemToUpdateMap.get(target); + // } + // tempUps.add(up); + // itemToUpdateMap.put(target, tempUps); + // } + // + // for (UpdatePrimitive up : pul2.getUpdatePrimitives()) { + // result.addUpdatePrimitive(up); + // Item target = up.getTarget(); + // + // if (!itemToUpdateMap.containsKey(target)) { + // tempUps = new ArrayList<>(); + // } else { + // tempUps = itemToUpdateMap.get(target); + // } + // tempUps.add(up); + // itemToUpdateMap.put(target, tempUps); + // } + // + // for (Item target : itemToUpdateMap.keySet()) { + // List targetUpdates = itemToUpdateMap.get(target); + // + // // object + // if (target.isObject()) { + // boolean hasDeletePrimitives = targetUpdates.stream() + // .anyMatch(u -> u instanceof DeleteFromObjectPrimitive); + // boolean hasInsertPrimitives = targetUpdates.stream() + // .anyMatch(u -> u instanceof InsertIntoObjectPrimitive); + // + // if (hasInsertPrimitives) { + // ObjectItem sourceObject = + // targetUpdates + // .stream() + // .filter(u -> u instanceof InsertIntoObjectPrimitive) + // .map(u -> ((InsertIntoObjectPrimitive) u).getSourceObject()) + // .reduce(new ObjectItem(), ObjectItem::mergeWith); + // result.addUpdatePrimitive(new InsertIntoObjectPrimitive((ObjectItem) target, sourceObject)); + // } + // + // if (hasDeletePrimitives) { + // List names = + // targetUpdates + // .stream() + // .filter(u -> u instanceof DeleteFromObjectPrimitive) + // .flatMap(u -> ((DeleteFromObjectPrimitive) u).getNamesToRemove().stream()) + // .distinct() + // .collect(Collectors.toList()); + // result.addUpdatePrimitive(new DeleteFromObjectPrimitive((ObjectItem) target, names)); + // continue; + // } + // + // List renamePrimitives = + // targetUpdates + // .stream() + // .filter(u -> u instanceof RenameInObjectPrimitive) + // .collect(Collectors.toList()); + // List uniqueRenameSelectors = + // renamePrimitives + // .stream() + // .map(u -> ((RenameInObjectPrimitive) u).getTargetName()) + // .distinct() + // .collect(Collectors.toList()); + // + // if (renamePrimitives.size() != uniqueRenameSelectors.size()) { + // // TODO Throw rename on same key error jerr:JNUP0010. + // } + // + // List replacePrimitives = + // targetUpdates + // .stream() + // .filter(u -> u instanceof ReplaceInObjectPrimitive) + // .collect(Collectors.toList()); + // List uniqueReplaceSelectors = + // replacePrimitives + // .stream() + // .map(u -> ((ReplaceInObjectPrimitive) u).getTargetName()) + // .distinct() + // .collect(Collectors.toList()); + // + // if (replacePrimitives.size() != uniqueReplaceSelectors.size()) { + // // TODO Throw replace on same key error jerr:JNUP0009. + // } + // + // } + // + // // array + // if (target.isArray()) { + // boolean hasDeletePrimitives = targetUpdates.stream() + // .anyMatch(u -> u instanceof DeleteFromArrayPrimitive); + // boolean hasInsertPrimitives = targetUpdates.stream() + // .anyMatch(u -> u instanceof InsertIntoArrayPrimitive); + // + // if (hasInsertPrimitives) { + // HashMap> locatorToInsertsMap = new HashMap<>(); + // + // targetUpdates + // .stream() + // .filter(u -> u instanceof InsertIntoArrayPrimitive) + // .map(u -> (InsertIntoArrayPrimitive) u) + // .forEach(u -> { + // List temp; + // if (!locatorToInsertsMap.containsKey(u.getPositionInt())) { + // temp = new ArrayList<>(); + // } else { + // temp = locatorToInsertsMap.get(u.getPositionInt()); + // } + // temp.addAll(u.getSourceSequence()); + // locatorToInsertsMap.put(u.getPositionInt(), temp); + // }); + // + // for (IntItem intItem : locatorToInsertsMap.keySet()) { + // result.addUpdatePrimitive( + // new InsertIntoArrayPrimitive( + // (ArrayItem) target, + // intItem, + // locatorToInsertsMap.get(intItem) + // ) + // ); + // } + // } + // + // if (hasDeletePrimitives) { + // List intItems = + // targetUpdates + // .stream() + // .filter(u -> u instanceof DeleteFromArrayPrimitive) + // .map(u -> ((DeleteFromArrayPrimitive) u).getPositionInt()) + // .distinct() + // .collect(Collectors.toList()); + // for (IntItem intItem : intItems) { + // result.addUpdatePrimitive(new DeleteFromArrayPrimitive((ArrayItem) target, intItem)); + // } + // continue; + // } + // + // List replacePrimitives = + // targetUpdates + // .stream() + // .filter(u -> u instanceof ReplaceInArrayPrimitive) + // .collect(Collectors.toList()); + // List uniqueReplaceSelectors = + // replacePrimitives + // .stream() + // .map(u -> ((ReplaceInArrayPrimitive) u).getPositionInt()) + // .distinct() + // .collect(Collectors.toList()); + // + // if (replacePrimitives.size() != uniqueReplaceSelectors.size()) { + // // TODO Throw replace on same key error jerr:JNUP0009. + // } + // + // } + // } + // + // return result; + // } - public static PendingUpdateList mergeUpdates1(PendingUpdateList pul1, PendingUpdateList pul2) { + public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpdateList pul2) { PendingUpdateList result = new PendingUpdateList(); - HashMap>> itemToUpdateMap = new HashMap<>(); - HashMap> temp; - Set tempDistinctSources; + HashMap>> itemToUpdateMap = + new HashMap<>(); + HashMap> tempEnumMap; + HashMap tempSelectorMap; + UpdatePrimitiveSource tempSource; + UpdatePrimitiveSelector placeholderSelector = new UpdatePrimitiveSelector(new IntItem(0)); for (List us : Arrays.asList(pul1.getUpdatePrimitives(), pul2.getUpdatePrimitives())) { for (UpdatePrimitive u : us) { UpdatePrimitiveTarget target = u.getTarget(); - temp = itemToUpdateMap.getOrDefault(target, new HashMap<>()); + tempEnumMap = itemToUpdateMap.getOrDefault(target, new HashMap<>()); if (u instanceof DeleteFromArrayPrimitive) { - tempDistinctSources = temp.getOrDefault(UpdatePrimitiveEnum.DELETE_FROM_ARRAY, new HashSet<>()); - tempDistinctSources.add(u.getSource()); - temp.put(UpdatePrimitiveEnum.DELETE_FROM_ARRAY, tempDistinctSources); + tempSelectorMap = tempEnumMap.getOrDefault(UpdatePrimitiveEnum.DELETE_FROM_ARRAY, new HashMap<>()); + if (!tempSelectorMap.containsKey(u.getSelector())) { + tempSelectorMap.put(u.getSelector(), u.getSource()); + } + // No merge for same selector, just ignore + + tempEnumMap.put(UpdatePrimitiveEnum.DELETE_FROM_ARRAY, tempSelectorMap); + } else if (u instanceof InsertIntoArrayPrimitive) { - tempDistinctSources = temp.getOrDefault(UpdatePrimitiveEnum.INSERT_INTO_ARRAY, new HashSet<>()); - tempDistinctSources.add(u.getSource()); - temp.put(UpdatePrimitiveEnum.INSERT_INTO_ARRAY, tempDistinctSources); + tempSelectorMap = tempEnumMap.getOrDefault(UpdatePrimitiveEnum.INSERT_INTO_ARRAY, new HashMap<>()); + if (!tempSelectorMap.containsKey(u.getSelector())) { + tempSelectorMap.put(u.getSelector(), u.getSource()); + } else { + tempSource = tempSelectorMap.get(u.getSelector()); + tempSelectorMap.put( + u.getSelector(), + InsertIntoArrayPrimitive.mergeSources(tempSource, u.getSource()) + ); + } + tempEnumMap.put(UpdatePrimitiveEnum.INSERT_INTO_ARRAY, tempSelectorMap); } else if (u instanceof ReplaceInArrayPrimitive) { - tempDistinctSources = temp.getOrDefault(UpdatePrimitiveEnum.REPLACE_IN_ARRAY, new HashSet<>()); - tempDistinctSources.add(u.getSource()); - temp.put(UpdatePrimitiveEnum.REPLACE_IN_ARRAY, tempDistinctSources); + tempSelectorMap = tempEnumMap.getOrDefault(UpdatePrimitiveEnum.REPLACE_IN_ARRAY, new HashMap<>()); + if (!tempSelectorMap.containsKey(u.getSelector())) { + tempSelectorMap.put(u.getSelector(), u.getSource()); + } else { + // TODO implement jerr:NUP0009 + throw new OurBadException("MULTIPLE REPLACE OF SAME TARGET & SELECTOR"); + } + tempEnumMap.put(UpdatePrimitiveEnum.REPLACE_IN_ARRAY, tempSelectorMap); } else if (u instanceof DeleteFromObjectPrimitive) { - tempDistinctSources = temp.getOrDefault(UpdatePrimitiveEnum.DELETE_FROM_OBJECT, new HashSet<>()); - tempDistinctSources.add(u.getSource()); - temp.put(UpdatePrimitiveEnum.DELETE_FROM_OBJECT, tempDistinctSources); + tempSelectorMap = tempEnumMap.getOrDefault(UpdatePrimitiveEnum.DELETE_FROM_OBJECT, new HashMap<>()); + if (!tempSelectorMap.containsKey(placeholderSelector)) { + tempSelectorMap.put(placeholderSelector, u.getSource()); + } else { + tempSource = tempSelectorMap.get(placeholderSelector); + tempSelectorMap.put( + placeholderSelector, + DeleteFromObjectPrimitive.mergeSources(tempSource, u.getSource()) + ); + } + tempEnumMap.put(UpdatePrimitiveEnum.DELETE_FROM_OBJECT, tempSelectorMap); } else if (u instanceof InsertIntoObjectPrimitive) { - tempDistinctSources = temp.getOrDefault(UpdatePrimitiveEnum.INSERT_INTO_OBJECT, new HashSet<>()); - tempDistinctSources.add(u.getSource()); - temp.put(UpdatePrimitiveEnum.INSERT_INTO_OBJECT, tempDistinctSources); + tempSelectorMap = tempEnumMap.getOrDefault(UpdatePrimitiveEnum.INSERT_INTO_OBJECT, new HashMap<>()); + if (!tempSelectorMap.containsKey(placeholderSelector)) { + tempSelectorMap.put(placeholderSelector, u.getSource()); + } else { + tempSource = tempSelectorMap.get(placeholderSelector); + tempSelectorMap.put( + u.getSelector(), + InsertIntoObjectPrimitive.mergeSources(tempSource, u.getSource()) + ); + } + tempEnumMap.put(UpdatePrimitiveEnum.INSERT_INTO_OBJECT, tempSelectorMap); } else if (u instanceof ReplaceInObjectPrimitive) { - tempDistinctSources = temp.getOrDefault(UpdatePrimitiveEnum.REPLACE_IN_OBJECT, new HashSet<>()); - tempDistinctSources.add(u.getSource()); - temp.put(UpdatePrimitiveEnum.REPLACE_IN_OBJECT, tempDistinctSources); + tempSelectorMap = tempEnumMap.getOrDefault(UpdatePrimitiveEnum.REPLACE_IN_OBJECT, new HashMap<>()); + if (!tempSelectorMap.containsKey(u.getSelector())) { + tempSelectorMap.put(u.getSelector(), u.getSource()); + } else { + // TODO implement jerr:NUP0009 + throw new OurBadException("MULTIPLE REPLACE OF SAME TARGET & SELECTOR"); + } + tempEnumMap.put(UpdatePrimitiveEnum.REPLACE_IN_OBJECT, tempSelectorMap); } else if (u instanceof RenameInObjectPrimitive) { - tempDistinctSources = temp.getOrDefault(UpdatePrimitiveEnum.RENAME_IN_OBJECT, new HashSet<>()); - tempDistinctSources.add(u.getSource()); - temp.put(UpdatePrimitiveEnum.RENAME_IN_OBJECT, tempDistinctSources); + tempSelectorMap = tempEnumMap.getOrDefault(UpdatePrimitiveEnum.RENAME_IN_OBJECT, new HashMap<>()); + if (!tempSelectorMap.containsKey(u.getSelector())) { + tempSelectorMap.put(u.getSelector(), u.getSource()); + } else { + // TODO implement jerr:NUP0010 + throw new OurBadException("MULTIPLE REPLACE OF SAME TARGET & SELECTOR"); + } + tempEnumMap.put(UpdatePrimitiveEnum.RENAME_IN_OBJECT, tempSelectorMap); } - itemToUpdateMap.put(target, temp); + itemToUpdateMap.put(target, tempEnumMap); + } + } + + for (UpdatePrimitiveTarget target : itemToUpdateMap.keySet()) { + tempEnumMap = itemToUpdateMap.get(target); + + if (target.isObject()) { + UpdatePrimitiveSource deleteFromObjSrc = tempEnumMap.get(UpdatePrimitiveEnum.DELETE_FROM_OBJECT) + .get(placeholderSelector); + List delStrs = deleteFromObjSrc.getSourceAsListOfStrings(); + Set delStrsSet = new HashSet<>(delStrs); + result.addUpdatePrimitive( + new DeleteFromObjectPrimitive( + target.getTargetAsObject(), + deleteFromObjSrc.getSourceAsListOfStrings() + ) + ); + + UpdatePrimitiveSource insertIntoObjSrc = tempEnumMap.get(UpdatePrimitiveEnum.INSERT_INTO_OBJECT) + .get(placeholderSelector); + ObjectItem mergedObjectItem = (ObjectItem) insertIntoObjSrc.getSingletonSource(); + result.addUpdatePrimitive(new InsertIntoObjectPrimitive(target.getTargetAsObject(), mergedObjectItem)); + + tempSelectorMap = tempEnumMap.get(UpdatePrimitiveEnum.REPLACE_IN_OBJECT); + for (UpdatePrimitiveSelector selector : tempSelectorMap.keySet()) { + if (!(delStrsSet.contains(selector.getSelectorAsString()))) { + result.addUpdatePrimitive( + new ReplaceInObjectPrimitive( + target.getTargetAsObject(), + selector.getSelectorAsString(), + tempSelectorMap.get(selector).getSingletonSource() + ) + ); + } + } + + tempSelectorMap = tempEnumMap.get(UpdatePrimitiveEnum.RENAME_IN_OBJECT); + for (UpdatePrimitiveSelector selector : tempSelectorMap.keySet()) { + if (!(delStrsSet.contains(selector.getSelectorAsString()))) { + result.addUpdatePrimitive( + new RenameInObjectPrimitive( + target.getTargetAsObject(), + selector.getSelectorAsString(), + (StringItem) tempSelectorMap.get(selector).getSingletonSource() + ) + ); + } + } + + } else if (target.isArray()) { + tempSelectorMap = tempEnumMap.get(UpdatePrimitiveEnum.DELETE_FROM_ARRAY); + Set delIntsSet = new HashSet<>(); + for (UpdatePrimitiveSelector selector : tempSelectorMap.keySet()) { + delIntsSet.add(selector.getSelectorAsInt()); + result.addUpdatePrimitive( + new DeleteFromArrayPrimitive(target.getTargetAsArray(), selector.getSelectorAsInt()) + ); + } + + tempSelectorMap = tempEnumMap.get(UpdatePrimitiveEnum.INSERT_INTO_ARRAY); + for (UpdatePrimitiveSelector selector : tempSelectorMap.keySet()) { + result.addUpdatePrimitive( + new InsertIntoArrayPrimitive( + target.getTargetAsArray(), + selector.getSelectorAsInt(), + tempSelectorMap.get(selector).getSourceAsListOfItems() + ) + ); + } + + tempSelectorMap = tempEnumMap.get(UpdatePrimitiveEnum.REPLACE_IN_ARRAY); + for (UpdatePrimitiveSelector selector : tempSelectorMap.keySet()) { + if (!(delIntsSet.contains(selector.getSelectorAsInt()))) { + result.addUpdatePrimitive( + new ReplaceInArrayPrimitive( + target.getTargetAsArray(), + selector.getSelectorAsInt(), + tempSelectorMap.get(selector).getSingletonSource() + ) + ); + } + } } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveEnum.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveEnum.java index e2bc0dd65d..4e473d37ef 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveEnum.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveEnum.java @@ -1,5 +1,6 @@ package org.rumbledb.runtime.update.primitives; + public enum UpdatePrimitiveEnum { DELETE_FROM_ARRAY, @@ -10,5 +11,4 @@ public enum UpdatePrimitiveEnum { REPLACE_IN_OBJECT, RENAME_IN_OBJECT; - } From 4cdfef659a626be4f264df1e896bbbf9f0e3781d Mon Sep 17 00:00:00 2001 From: dloughlin Date: Wed, 5 Apr 2023 15:39:15 +0200 Subject: [PATCH 046/119] Begin to refactor to only use interfaces and finish merge in PUL --- .../runtime/update/PendingUpdateList.java | 315 ++++++++---------- .../primitives/DeleteFromArrayPrimitive.java | 9 +- .../primitives/DeleteFromObjectPrimitive.java | 15 +- .../primitives/InsertIntoArrayPrimitive.java | 8 +- .../primitives/InsertIntoObjectPrimitive.java | 9 +- .../primitives/RenameInObjectPrimitive.java | 8 +- .../primitives/ReplaceInArrayPrimitive.java | 8 +- .../primitives/ReplaceInObjectPrimitive.java | 8 +- .../primitives/UpdatePrimitiveFactory.java | 47 +++ .../primitives/UpdatePrimitiveInterface.java | 29 ++ .../primitives/UpdatePrimitiveSource.java | 8 +- 11 files changed, 270 insertions(+), 194 deletions(-) create mode 100644 src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveFactory.java diff --git a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java index da2ca9db13..f6414cab57 100644 --- a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java +++ b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java @@ -1,5 +1,6 @@ package org.rumbledb.runtime.update; +import org.rumbledb.api.Item; import org.rumbledb.exceptions.OurBadException; import org.rumbledb.items.IntItem; import org.rumbledb.items.ObjectItem; @@ -12,6 +13,12 @@ public class PendingUpdateList { private List updatePrimitives; + private Map insertObjMap; + private Map> insertArrayMap; + private Map> delReplaceObjMap; + private Map> delReplaceArrayMap; + private Map> renameObjMap; + public PendingUpdateList() { this.updatePrimitives = new ArrayList<>(); } @@ -46,175 +53,6 @@ public void applyUpdates() { } } - // public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpdateList pul2) { - // PendingUpdateList result = new PendingUpdateList(); - // HashMap> itemToUpdateMap = new HashMap<>(); - // List tempUps; - // - // for (UpdatePrimitive up : pul1.getUpdatePrimitives()) { - // result.addUpdatePrimitive(up); - // Item target = up.getTarget(); - // - // if (!itemToUpdateMap.containsKey(target)) { - // tempUps = new ArrayList<>(); - // } else { - // tempUps = itemToUpdateMap.get(target); - // } - // tempUps.add(up); - // itemToUpdateMap.put(target, tempUps); - // } - // - // for (UpdatePrimitive up : pul2.getUpdatePrimitives()) { - // result.addUpdatePrimitive(up); - // Item target = up.getTarget(); - // - // if (!itemToUpdateMap.containsKey(target)) { - // tempUps = new ArrayList<>(); - // } else { - // tempUps = itemToUpdateMap.get(target); - // } - // tempUps.add(up); - // itemToUpdateMap.put(target, tempUps); - // } - // - // for (Item target : itemToUpdateMap.keySet()) { - // List targetUpdates = itemToUpdateMap.get(target); - // - // // object - // if (target.isObject()) { - // boolean hasDeletePrimitives = targetUpdates.stream() - // .anyMatch(u -> u instanceof DeleteFromObjectPrimitive); - // boolean hasInsertPrimitives = targetUpdates.stream() - // .anyMatch(u -> u instanceof InsertIntoObjectPrimitive); - // - // if (hasInsertPrimitives) { - // ObjectItem sourceObject = - // targetUpdates - // .stream() - // .filter(u -> u instanceof InsertIntoObjectPrimitive) - // .map(u -> ((InsertIntoObjectPrimitive) u).getSourceObject()) - // .reduce(new ObjectItem(), ObjectItem::mergeWith); - // result.addUpdatePrimitive(new InsertIntoObjectPrimitive((ObjectItem) target, sourceObject)); - // } - // - // if (hasDeletePrimitives) { - // List names = - // targetUpdates - // .stream() - // .filter(u -> u instanceof DeleteFromObjectPrimitive) - // .flatMap(u -> ((DeleteFromObjectPrimitive) u).getNamesToRemove().stream()) - // .distinct() - // .collect(Collectors.toList()); - // result.addUpdatePrimitive(new DeleteFromObjectPrimitive((ObjectItem) target, names)); - // continue; - // } - // - // List renamePrimitives = - // targetUpdates - // .stream() - // .filter(u -> u instanceof RenameInObjectPrimitive) - // .collect(Collectors.toList()); - // List uniqueRenameSelectors = - // renamePrimitives - // .stream() - // .map(u -> ((RenameInObjectPrimitive) u).getTargetName()) - // .distinct() - // .collect(Collectors.toList()); - // - // if (renamePrimitives.size() != uniqueRenameSelectors.size()) { - // // TODO Throw rename on same key error jerr:JNUP0010. - // } - // - // List replacePrimitives = - // targetUpdates - // .stream() - // .filter(u -> u instanceof ReplaceInObjectPrimitive) - // .collect(Collectors.toList()); - // List uniqueReplaceSelectors = - // replacePrimitives - // .stream() - // .map(u -> ((ReplaceInObjectPrimitive) u).getTargetName()) - // .distinct() - // .collect(Collectors.toList()); - // - // if (replacePrimitives.size() != uniqueReplaceSelectors.size()) { - // // TODO Throw replace on same key error jerr:JNUP0009. - // } - // - // } - // - // // array - // if (target.isArray()) { - // boolean hasDeletePrimitives = targetUpdates.stream() - // .anyMatch(u -> u instanceof DeleteFromArrayPrimitive); - // boolean hasInsertPrimitives = targetUpdates.stream() - // .anyMatch(u -> u instanceof InsertIntoArrayPrimitive); - // - // if (hasInsertPrimitives) { - // HashMap> locatorToInsertsMap = new HashMap<>(); - // - // targetUpdates - // .stream() - // .filter(u -> u instanceof InsertIntoArrayPrimitive) - // .map(u -> (InsertIntoArrayPrimitive) u) - // .forEach(u -> { - // List temp; - // if (!locatorToInsertsMap.containsKey(u.getPositionInt())) { - // temp = new ArrayList<>(); - // } else { - // temp = locatorToInsertsMap.get(u.getPositionInt()); - // } - // temp.addAll(u.getSourceSequence()); - // locatorToInsertsMap.put(u.getPositionInt(), temp); - // }); - // - // for (IntItem intItem : locatorToInsertsMap.keySet()) { - // result.addUpdatePrimitive( - // new InsertIntoArrayPrimitive( - // (ArrayItem) target, - // intItem, - // locatorToInsertsMap.get(intItem) - // ) - // ); - // } - // } - // - // if (hasDeletePrimitives) { - // List intItems = - // targetUpdates - // .stream() - // .filter(u -> u instanceof DeleteFromArrayPrimitive) - // .map(u -> ((DeleteFromArrayPrimitive) u).getPositionInt()) - // .distinct() - // .collect(Collectors.toList()); - // for (IntItem intItem : intItems) { - // result.addUpdatePrimitive(new DeleteFromArrayPrimitive((ArrayItem) target, intItem)); - // } - // continue; - // } - // - // List replacePrimitives = - // targetUpdates - // .stream() - // .filter(u -> u instanceof ReplaceInArrayPrimitive) - // .collect(Collectors.toList()); - // List uniqueReplaceSelectors = - // replacePrimitives - // .stream() - // .map(u -> ((ReplaceInArrayPrimitive) u).getPositionInt()) - // .distinct() - // .collect(Collectors.toList()); - // - // if (replacePrimitives.size() != uniqueReplaceSelectors.size()) { - // // TODO Throw replace on same key error jerr:JNUP0009. - // } - // - // } - // } - // - // return result; - // } - public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpdateList pul2) { PendingUpdateList result = new PendingUpdateList(); HashMap>> itemToUpdateMap = @@ -313,8 +151,8 @@ public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpda if (target.isObject()) { UpdatePrimitiveSource deleteFromObjSrc = tempEnumMap.get(UpdatePrimitiveEnum.DELETE_FROM_OBJECT) .get(placeholderSelector); - List delStrs = deleteFromObjSrc.getSourceAsListOfStrings(); - Set delStrsSet = new HashSet<>(delStrs); + List delStrs = deleteFromObjSrc.getSourceAsListOfStrings(); + Set delStrsSet = new HashSet<>(delStrs); result.addUpdatePrimitive( new DeleteFromObjectPrimitive( target.getTargetAsObject(), @@ -392,4 +230,139 @@ public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpda return result; } + public static PendingUpdateList mergeUpdatesMaps(PendingUpdateList pul1, PendingUpdateList pul2) { + PendingUpdateList res = new PendingUpdateList(); + Map> resDelRepObjMap; + Map tempSelSrcMap; + Map tempSelSrcResMap; + UpdatePrimitiveSource tempSrc; + + ////// OBJECTS + + // DELETES & REPLACES + + for (UpdatePrimitiveTarget target : pul1.delReplaceObjMap.keySet()) { + tempSelSrcMap = pul1.delReplaceObjMap.get(target); + tempSelSrcResMap = res.delReplaceObjMap.getOrDefault(target, new HashMap<>()); + + for (UpdatePrimitiveSelector selector : tempSelSrcMap.keySet()) { + tempSelSrcResMap.put(selector, tempSelSrcMap.get(selector)); + } + res.delReplaceObjMap.put(target,tempSelSrcResMap); + } + + for (UpdatePrimitiveTarget target : pul2.delReplaceObjMap.keySet()) { + tempSelSrcMap = pul2.delReplaceObjMap.get(target); + tempSelSrcResMap = res.delReplaceObjMap.getOrDefault(target, new HashMap<>()); + + for (UpdatePrimitiveSelector selector : tempSelSrcMap.keySet()) { + if (tempSelSrcResMap.containsKey(selector)) { + tempSrc = tempSelSrcResMap.get(selector); + if (tempSrc != null) { + // TODO implement jerr:NUP0009 + throw new OurBadException("MULTIPLE REPLACE OF SAME TARGET & SELECTOR"); + } + continue; + } + tempSelSrcResMap.put(selector, tempSelSrcMap.get(selector)); + } + res.delReplaceObjMap.put(target,tempSelSrcResMap); + } + + // INSERTS + + res.insertObjMap.putAll(pul1.insertObjMap); + + for (UpdatePrimitiveTarget target : pul2.insertObjMap.keySet()) { + tempSrc = pul2.insertObjMap.get(target); + if (res.insertObjMap.containsKey(target)) { + tempSrc = InsertIntoObjectPrimitive.mergeSources(res.insertObjMap.get(target), tempSrc); + } + res.insertObjMap.put(target,tempSrc); + } + + // RENAME + + for (UpdatePrimitiveTarget target : pul1.renameObjMap.keySet()) { + tempSelSrcMap = pul1.renameObjMap.get(target); + tempSelSrcResMap = res.renameObjMap.getOrDefault(target, new HashMap<>()); + + for (UpdatePrimitiveSelector selector : tempSelSrcMap.keySet()) { + tempSelSrcResMap.put(selector, tempSelSrcMap.get(selector)); + } + res.delReplaceObjMap.put(target,tempSelSrcResMap); + } + + for (UpdatePrimitiveTarget target : pul2.renameObjMap.keySet()) { + tempSelSrcMap = pul2.renameObjMap.get(target); + tempSelSrcResMap = res.renameObjMap.getOrDefault(target, new HashMap<>()); + + for (UpdatePrimitiveSelector selector : tempSelSrcMap.keySet()) { + if (tempSelSrcResMap.containsKey(selector)) { + // TODO implement jerr:NUP0010 + throw new OurBadException("MULTIPLE RENAME OF SAME TARGET & SELECTOR"); + } + tempSelSrcResMap.put(selector, tempSelSrcMap.get(selector)); + } + res.delReplaceObjMap.put(target,tempSelSrcResMap); + } + + ////// ARRAYS + + // DELETES & REPLACES + + for (UpdatePrimitiveTarget target : pul1.delReplaceArrayMap.keySet()) { + tempSelSrcMap = pul1.delReplaceArrayMap.get(target); + tempSelSrcResMap = res.delReplaceArrayMap.getOrDefault(target, new HashMap<>()); + + for (UpdatePrimitiveSelector selector : tempSelSrcMap.keySet()) { + tempSelSrcResMap.put(selector, tempSelSrcMap.get(selector)); + } + res.delReplaceArrayMap.put(target,tempSelSrcResMap); + } + + for (UpdatePrimitiveTarget target : pul2.delReplaceArrayMap.keySet()) { + tempSelSrcMap = pul2.delReplaceArrayMap.get(target); + tempSelSrcResMap = res.delReplaceArrayMap.getOrDefault(target, new HashMap<>()); + + for (UpdatePrimitiveSelector selector : tempSelSrcMap.keySet()) { + if (tempSelSrcResMap.containsKey(selector)) { + tempSrc = tempSelSrcResMap.get(selector); + if (tempSrc != null) { + // TODO implement jerr:NUP0009 + throw new OurBadException("MULTIPLE REPLACE OF SAME TARGET & SELECTOR"); + } + continue; + } + tempSelSrcResMap.put(selector, tempSelSrcMap.get(selector)); + } + res.delReplaceArrayMap.put(target,tempSelSrcResMap); + } + + // INSERTS + + for (UpdatePrimitiveTarget target : pul1.insertArrayMap.keySet()) { + tempSelSrcMap = pul1.insertArrayMap.get(target); + tempSelSrcResMap = res.insertArrayMap.getOrDefault(target, new HashMap<>()); + + for (UpdatePrimitiveSelector selector : tempSelSrcMap.keySet()) { + tempSelSrcResMap.put(selector, tempSelSrcMap.get(selector)); + } + res.insertArrayMap.put(target,tempSelSrcResMap); + } + + for (UpdatePrimitiveTarget target : pul2.insertArrayMap.keySet()) { + tempSelSrcMap = pul2.insertArrayMap.get(target); + tempSelSrcResMap = res.insertArrayMap.getOrDefault(target, new HashMap<>()); + + for (UpdatePrimitiveSelector selector : tempSelSrcMap.keySet()) { + tempSrc = tempSelSrcResMap.getOrDefault(selector, new UpdatePrimitiveSource(new ObjectItem())); + tempSelSrcResMap.put(selector, InsertIntoArrayPrimitive.mergeSources(tempSelSrcMap.get(selector), tempSrc)); + } + res.insertArrayMap.put(target,tempSelSrcResMap); + } + + return res; + } + } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java index b8f5c9e976..2e822cfc97 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java @@ -1,11 +1,12 @@ package org.rumbledb.runtime.update.primitives; +import org.rumbledb.api.Item; import org.rumbledb.items.ArrayItem; import org.rumbledb.items.IntItem; -public class DeleteFromArrayPrimitive extends UpdatePrimitive { +public class DeleteFromArrayPrimitive extends UpdatePrimitive implements UpdatePrimitiveInterface { - public DeleteFromArrayPrimitive(ArrayItem targetArray, IntItem positionInt) { + public DeleteFromArrayPrimitive(Item targetArray, Item positionInt) { super(targetArray, positionInt, positionInt); if (positionInt.getIntValue() < 0 || positionInt.getIntValue() >= targetArray.getSize()) { // TODO throw error or do nothing? @@ -25,4 +26,8 @@ public void apply() { this.getTargetArray().removeItemAt(this.getPositionInt().getIntValue()); } + @Override + public boolean isDeleteArray() { + return true; + } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java index 701d846d38..137470ae8b 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java @@ -1,14 +1,15 @@ package org.rumbledb.runtime.update.primitives; +import org.rumbledb.api.Item; import org.rumbledb.items.ObjectItem; import org.rumbledb.items.StringItem; import java.util.List; import java.util.stream.Collectors; -public class DeleteFromObjectPrimitive extends UpdatePrimitive { +public class DeleteFromObjectPrimitive extends UpdatePrimitive implements UpdatePrimitiveInterface { - public DeleteFromObjectPrimitive(ObjectItem targetObject, List namesToRemove) { + public DeleteFromObjectPrimitive(Item targetObject, List namesToRemove) { super(targetObject, namesToRemove); } @@ -16,24 +17,28 @@ public ObjectItem getTargetObject() { return target.getTargetAsObject(); } - public List getNamesToRemove() { + public List getNamesToRemove() { return source.getSourceAsListOfStrings(); } @Override public void apply() { for ( - String str : this.getNamesToRemove().stream().map(StringItem::getStringValue).collect(Collectors.toList()) + String str : this.getNamesToRemove().stream().map(Item::getStringValue).collect(Collectors.toList()) ) { this.getTargetObject().removeItemByKey(str); } } public static UpdatePrimitiveSource mergeSources(UpdatePrimitiveSource first, UpdatePrimitiveSource second) { - List merged = first.getSourceAsListOfStrings(); + List merged = first.getSourceAsListOfStrings(); merged.addAll(second.getSourceAsListOfStrings()); merged = merged.stream().distinct().collect(Collectors.toList()); return new UpdatePrimitiveSource(merged); } + @Override + public boolean isDeleteObject() { + return true; + } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java index 1487a833b7..284b2e465f 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java @@ -7,9 +7,9 @@ import java.util.ArrayList; import java.util.List; -public class InsertIntoArrayPrimitive extends UpdatePrimitive { +public class InsertIntoArrayPrimitive extends UpdatePrimitive implements UpdatePrimitiveInterface { - public InsertIntoArrayPrimitive(ArrayItem targetArray, IntItem positionInt, List sourceSequence) { + public InsertIntoArrayPrimitive(Item targetArray, Item positionInt, List sourceSequence) { super(targetArray, positionInt, sourceSequence); if (positionInt.getIntValue() < 0 || positionInt.getIntValue() >= targetArray.getSize()) { // TODO throw error or do nothing? @@ -39,4 +39,8 @@ public static UpdatePrimitiveSource mergeSources(UpdatePrimitiveSource first, Up return new UpdatePrimitiveSource(merged); } + @Override + public boolean isInsertArray() { + return true; + } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java index e255d4d1e3..1aafdab895 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java @@ -1,13 +1,14 @@ package org.rumbledb.runtime.update.primitives; +import org.rumbledb.api.Item; import org.rumbledb.exceptions.DuplicateObjectKeyException; import org.rumbledb.exceptions.OurBadException; import org.rumbledb.items.ObjectItem; -public class InsertIntoObjectPrimitive extends UpdatePrimitive { +public class InsertIntoObjectPrimitive extends UpdatePrimitive implements UpdatePrimitiveInterface { - public InsertIntoObjectPrimitive(ObjectItem targetObject, ObjectItem sourceObject) { + public InsertIntoObjectPrimitive(Item targetObject, Item sourceObject) { super(targetObject, sourceObject); } @@ -44,4 +45,8 @@ public static UpdatePrimitiveSource mergeSources(UpdatePrimitiveSource first, Up return new UpdatePrimitiveSource(merged); } + @Override + public boolean isInsertObject() { + return true; + } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java index 9ef5885b48..8e3cfefd75 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java @@ -4,9 +4,9 @@ import org.rumbledb.items.ObjectItem; import org.rumbledb.items.StringItem; -public class RenameInObjectPrimitive extends UpdatePrimitive { +public class RenameInObjectPrimitive extends UpdatePrimitive implements UpdatePrimitiveInterface { - public RenameInObjectPrimitive(ObjectItem targetObject, StringItem targetName, StringItem replacementName) { + public RenameInObjectPrimitive(Item targetObject, Item targetName, Item replacementName) { super(targetObject, targetName, replacementName); } @@ -33,4 +33,8 @@ public void apply() { // TODO: implement replace and rename methods for Array & Object to avoid deletion and append } + @Override + public boolean isRenameObject() { + return true; + } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java index 8fe291171b..cf5b8b3d0a 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java @@ -4,9 +4,9 @@ import org.rumbledb.items.ArrayItem; import org.rumbledb.items.IntItem; -public class ReplaceInArrayPrimitive extends UpdatePrimitive { +public class ReplaceInArrayPrimitive extends UpdatePrimitive implements UpdatePrimitiveInterface { - public ReplaceInArrayPrimitive(ArrayItem targetArray, IntItem positionInt, Item replacementItem) { + public ReplaceInArrayPrimitive(Item targetArray, Item positionInt, Item replacementItem) { super(targetArray, positionInt, replacementItem); } @@ -35,4 +35,8 @@ public void apply() { } } + @Override + public boolean isReplaceArray() { + return true; + } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java index d024dd6977..3444a58620 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java @@ -4,9 +4,9 @@ import org.rumbledb.items.ObjectItem; import org.rumbledb.items.StringItem; -public class ReplaceInObjectPrimitive extends UpdatePrimitive { +public class ReplaceInObjectPrimitive extends UpdatePrimitive implements UpdatePrimitiveInterface { - public ReplaceInObjectPrimitive(ObjectItem targetObject, StringItem targetName, Item replacementItem) { + public ReplaceInObjectPrimitive(Item targetObject, Item targetName, Item replacementItem) { super(targetObject, targetName, replacementItem); } @@ -31,4 +31,8 @@ public void apply() { } } + @Override + public boolean isReplaceObject() { + return true; + } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveFactory.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveFactory.java new file mode 100644 index 0000000000..52e225a038 --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveFactory.java @@ -0,0 +1,47 @@ +package org.rumbledb.runtime.update.primitives; + +import org.rumbledb.api.Item; + +import java.util.List; + +public class UpdatePrimitiveFactory { + + private static UpdatePrimitiveFactory instance; + + public static UpdatePrimitiveFactory getInstance() { + if (instance == null) { + instance = new UpdatePrimitiveFactory(); + } + return instance; + } + + public UpdatePrimitiveInterface createDeleteFromArrayPrimitive(Item targetArray, Item selectorInt) { + return new DeleteFromArrayPrimitive(targetArray, selectorInt); + } + + public UpdatePrimitiveInterface createDeleteFromObjectPrimitive(Item targetObject, List selectorStrs) { + return new DeleteFromObjectPrimitive(targetObject, selectorStrs); + } + + public UpdatePrimitiveInterface createInsertIntoArrayPrimitive(Item targetArray, Item selectorInt, List contents ) { + return new InsertIntoArrayPrimitive(targetArray, selectorInt, contents); + } + + public UpdatePrimitiveInterface createInsertIntoObjectPrimitive(Item targetObject, Item contentsObject) { + return new InsertIntoObjectPrimitive(targetObject, contentsObject); + } + + public UpdatePrimitiveInterface createReplaceInArrayPrimitive(Item targetArray, Item selectorInt, Item content) { + return new ReplaceInArrayPrimitive(targetArray, selectorInt, content); + } + + public UpdatePrimitiveInterface createReplaceInObjectPrimitive(Item targetObject, Item selectorStr, Item content) { + return new ReplaceInObjectPrimitive(targetObject, selectorStr, content); + } + + public UpdatePrimitiveInterface createRenameInObjectPrimitive(Item targetObject, Item selectorStr, Item content) { + return new RenameInObjectPrimitive(targetObject, selectorStr, content); + } + + +} diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveInterface.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveInterface.java index ff83a3cf17..84200eeb22 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveInterface.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveInterface.java @@ -12,4 +12,33 @@ public interface UpdatePrimitiveInterface { UpdatePrimitiveSource getSource(); + default boolean isDeleteObject() { + return false; + } + + default boolean isDeleteArray() { + return false; + } + + default boolean isInsertObject() { + return false; + } + + default boolean isInsertArray() { + return false; + } + + default boolean isReplaceObject() { + return false; + } + + default boolean isReplaceArray() { + return false; + } + + default boolean isRenameObject() { + return false; + } + + } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveSource.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveSource.java index 380058200b..60e4fe3c90 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveSource.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveSource.java @@ -35,12 +35,8 @@ public boolean isSingleton() { return this.source.size() == 1; } - public List getSourceAsListOfStrings() { - List result = new ArrayList<>(); - for (Item item : this.source) { - result.add((StringItem) item); - } - return result; + public List getSourceAsListOfStrings() { + return new ArrayList<>(this.source); } public List getSourceAsListOfItems() { From 900ae6de4836182c62283b6fb5d2680e184cbeb0 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 10 Apr 2023 18:18:36 +0200 Subject: [PATCH 047/119] Refactor UpdatePrimitive classes to use interface and use Maps in PUL --- .../runtime/update/PendingUpdateList.java | 293 +++--------------- .../primitives/DeleteFromArrayPrimitive.java | 37 ++- .../primitives/DeleteFromObjectPrimitive.java | 55 +++- .../primitives/InsertIntoArrayPrimitive.java | 48 ++- .../primitives/InsertIntoObjectPrimitive.java | 59 ++-- .../primitives/RenameInObjectPrimitive.java | 52 +++- .../primitives/ReplaceInArrayPrimitive.java | 55 ++-- .../primitives/ReplaceInObjectPrimitive.java | 48 ++- .../update/primitives/UpdatePrimitive.java | 75 ++--- .../primitives/UpdatePrimitiveFactory.java | 14 +- .../primitives/UpdatePrimitiveInterface.java | 44 --- .../primitives/UpdatePrimitiveSelector.java | 60 ---- .../primitives/UpdatePrimitiveSource.java | 46 --- .../primitives/UpdatePrimitiveTarget.java | 59 ---- 14 files changed, 328 insertions(+), 617 deletions(-) delete mode 100644 src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveInterface.java delete mode 100644 src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveSelector.java delete mode 100644 src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveSource.java delete mode 100644 src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveTarget.java diff --git a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java index f6414cab57..7df5b76a2d 100644 --- a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java +++ b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java @@ -1,5 +1,6 @@ package org.rumbledb.runtime.update; +import com.amazonaws.services.dynamodbv2.model.ItemCollectionMetrics; import org.rumbledb.api.Item; import org.rumbledb.exceptions.OurBadException; import org.rumbledb.items.IntItem; @@ -11,251 +12,59 @@ public class PendingUpdateList { - private List updatePrimitives; - - private Map insertObjMap; - private Map> insertArrayMap; - private Map> delReplaceObjMap; - private Map> delReplaceArrayMap; - private Map> renameObjMap; + private Map insertObjMap; + private Map>> insertArrayMap; + private Map> delReplaceObjMap; + private Map> delReplaceArrayMap; + private Map> renameObjMap; public PendingUpdateList() { - this.updatePrimitives = new ArrayList<>(); - } - - public PendingUpdateList(List updatePrimitives) { - this.updatePrimitives = updatePrimitives; - } - - public List getUpdatePrimitives() { - return updatePrimitives; - } - public void addUpdatePrimitive(UpdatePrimitive updatePrimitive) { - this.updatePrimitives.add(updatePrimitive); } - public void addAllUpdatePrimitives(List updatePrimitives) { - this.updatePrimitives.addAll(updatePrimitives); - } - - public boolean isEmpty() { - return this.updatePrimitives.isEmpty(); - } +// public void addUpdatePrimitive(UpdatePrimitive updatePrimitive) { +// this.updatePrimitives.add(updatePrimitive); +// } +// +// public void addAllUpdatePrimitives(List updatePrimitives) { +// this.updatePrimitives.addAll(updatePrimitives); +// } - public int size() { - return this.updatePrimitives.size(); - } - public void applyUpdates() { - for (UpdatePrimitive up : this.updatePrimitives) { - up.apply(); - } - } +// public void applyUpdates() { +// for (UpdatePrimitive up : this.updatePrimitives) { +// up.apply(); +// } +// } public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpdateList pul2) { - PendingUpdateList result = new PendingUpdateList(); - HashMap>> itemToUpdateMap = - new HashMap<>(); - HashMap> tempEnumMap; - HashMap tempSelectorMap; - UpdatePrimitiveSource tempSource; - UpdatePrimitiveSelector placeholderSelector = new UpdatePrimitiveSelector(new IntItem(0)); - - for (List us : Arrays.asList(pul1.getUpdatePrimitives(), pul2.getUpdatePrimitives())) { - for (UpdatePrimitive u : us) { - UpdatePrimitiveTarget target = u.getTarget(); - tempEnumMap = itemToUpdateMap.getOrDefault(target, new HashMap<>()); - - if (u instanceof DeleteFromArrayPrimitive) { - tempSelectorMap = tempEnumMap.getOrDefault(UpdatePrimitiveEnum.DELETE_FROM_ARRAY, new HashMap<>()); - if (!tempSelectorMap.containsKey(u.getSelector())) { - tempSelectorMap.put(u.getSelector(), u.getSource()); - } - // No merge for same selector, just ignore - - tempEnumMap.put(UpdatePrimitiveEnum.DELETE_FROM_ARRAY, tempSelectorMap); - - } else if (u instanceof InsertIntoArrayPrimitive) { - tempSelectorMap = tempEnumMap.getOrDefault(UpdatePrimitiveEnum.INSERT_INTO_ARRAY, new HashMap<>()); - if (!tempSelectorMap.containsKey(u.getSelector())) { - tempSelectorMap.put(u.getSelector(), u.getSource()); - } else { - tempSource = tempSelectorMap.get(u.getSelector()); - tempSelectorMap.put( - u.getSelector(), - InsertIntoArrayPrimitive.mergeSources(tempSource, u.getSource()) - ); - } - tempEnumMap.put(UpdatePrimitiveEnum.INSERT_INTO_ARRAY, tempSelectorMap); - } else if (u instanceof ReplaceInArrayPrimitive) { - tempSelectorMap = tempEnumMap.getOrDefault(UpdatePrimitiveEnum.REPLACE_IN_ARRAY, new HashMap<>()); - if (!tempSelectorMap.containsKey(u.getSelector())) { - tempSelectorMap.put(u.getSelector(), u.getSource()); - } else { - // TODO implement jerr:NUP0009 - throw new OurBadException("MULTIPLE REPLACE OF SAME TARGET & SELECTOR"); - } - tempEnumMap.put(UpdatePrimitiveEnum.REPLACE_IN_ARRAY, tempSelectorMap); - } else if (u instanceof DeleteFromObjectPrimitive) { - tempSelectorMap = tempEnumMap.getOrDefault(UpdatePrimitiveEnum.DELETE_FROM_OBJECT, new HashMap<>()); - if (!tempSelectorMap.containsKey(placeholderSelector)) { - tempSelectorMap.put(placeholderSelector, u.getSource()); - } else { - tempSource = tempSelectorMap.get(placeholderSelector); - tempSelectorMap.put( - placeholderSelector, - DeleteFromObjectPrimitive.mergeSources(tempSource, u.getSource()) - ); - } - tempEnumMap.put(UpdatePrimitiveEnum.DELETE_FROM_OBJECT, tempSelectorMap); - } else if (u instanceof InsertIntoObjectPrimitive) { - tempSelectorMap = tempEnumMap.getOrDefault(UpdatePrimitiveEnum.INSERT_INTO_OBJECT, new HashMap<>()); - if (!tempSelectorMap.containsKey(placeholderSelector)) { - tempSelectorMap.put(placeholderSelector, u.getSource()); - } else { - tempSource = tempSelectorMap.get(placeholderSelector); - tempSelectorMap.put( - u.getSelector(), - InsertIntoObjectPrimitive.mergeSources(tempSource, u.getSource()) - ); - } - tempEnumMap.put(UpdatePrimitiveEnum.INSERT_INTO_OBJECT, tempSelectorMap); - } else if (u instanceof ReplaceInObjectPrimitive) { - tempSelectorMap = tempEnumMap.getOrDefault(UpdatePrimitiveEnum.REPLACE_IN_OBJECT, new HashMap<>()); - if (!tempSelectorMap.containsKey(u.getSelector())) { - tempSelectorMap.put(u.getSelector(), u.getSource()); - } else { - // TODO implement jerr:NUP0009 - throw new OurBadException("MULTIPLE REPLACE OF SAME TARGET & SELECTOR"); - } - tempEnumMap.put(UpdatePrimitiveEnum.REPLACE_IN_OBJECT, tempSelectorMap); - } else if (u instanceof RenameInObjectPrimitive) { - tempSelectorMap = tempEnumMap.getOrDefault(UpdatePrimitiveEnum.RENAME_IN_OBJECT, new HashMap<>()); - if (!tempSelectorMap.containsKey(u.getSelector())) { - tempSelectorMap.put(u.getSelector(), u.getSource()); - } else { - // TODO implement jerr:NUP0010 - throw new OurBadException("MULTIPLE REPLACE OF SAME TARGET & SELECTOR"); - } - tempEnumMap.put(UpdatePrimitiveEnum.RENAME_IN_OBJECT, tempSelectorMap); - } - - itemToUpdateMap.put(target, tempEnumMap); - } - } - - for (UpdatePrimitiveTarget target : itemToUpdateMap.keySet()) { - tempEnumMap = itemToUpdateMap.get(target); - - if (target.isObject()) { - UpdatePrimitiveSource deleteFromObjSrc = tempEnumMap.get(UpdatePrimitiveEnum.DELETE_FROM_OBJECT) - .get(placeholderSelector); - List delStrs = deleteFromObjSrc.getSourceAsListOfStrings(); - Set delStrsSet = new HashSet<>(delStrs); - result.addUpdatePrimitive( - new DeleteFromObjectPrimitive( - target.getTargetAsObject(), - deleteFromObjSrc.getSourceAsListOfStrings() - ) - ); - - UpdatePrimitiveSource insertIntoObjSrc = tempEnumMap.get(UpdatePrimitiveEnum.INSERT_INTO_OBJECT) - .get(placeholderSelector); - ObjectItem mergedObjectItem = (ObjectItem) insertIntoObjSrc.getSingletonSource(); - result.addUpdatePrimitive(new InsertIntoObjectPrimitive(target.getTargetAsObject(), mergedObjectItem)); - - tempSelectorMap = tempEnumMap.get(UpdatePrimitiveEnum.REPLACE_IN_OBJECT); - for (UpdatePrimitiveSelector selector : tempSelectorMap.keySet()) { - if (!(delStrsSet.contains(selector.getSelectorAsString()))) { - result.addUpdatePrimitive( - new ReplaceInObjectPrimitive( - target.getTargetAsObject(), - selector.getSelectorAsString(), - tempSelectorMap.get(selector).getSingletonSource() - ) - ); - } - } - - tempSelectorMap = tempEnumMap.get(UpdatePrimitiveEnum.RENAME_IN_OBJECT); - for (UpdatePrimitiveSelector selector : tempSelectorMap.keySet()) { - if (!(delStrsSet.contains(selector.getSelectorAsString()))) { - result.addUpdatePrimitive( - new RenameInObjectPrimitive( - target.getTargetAsObject(), - selector.getSelectorAsString(), - (StringItem) tempSelectorMap.get(selector).getSingletonSource() - ) - ); - } - } - - } else if (target.isArray()) { - tempSelectorMap = tempEnumMap.get(UpdatePrimitiveEnum.DELETE_FROM_ARRAY); - Set delIntsSet = new HashSet<>(); - for (UpdatePrimitiveSelector selector : tempSelectorMap.keySet()) { - delIntsSet.add(selector.getSelectorAsInt()); - result.addUpdatePrimitive( - new DeleteFromArrayPrimitive(target.getTargetAsArray(), selector.getSelectorAsInt()) - ); - } - - tempSelectorMap = tempEnumMap.get(UpdatePrimitiveEnum.INSERT_INTO_ARRAY); - for (UpdatePrimitiveSelector selector : tempSelectorMap.keySet()) { - result.addUpdatePrimitive( - new InsertIntoArrayPrimitive( - target.getTargetAsArray(), - selector.getSelectorAsInt(), - tempSelectorMap.get(selector).getSourceAsListOfItems() - ) - ); - } - - tempSelectorMap = tempEnumMap.get(UpdatePrimitiveEnum.REPLACE_IN_ARRAY); - for (UpdatePrimitiveSelector selector : tempSelectorMap.keySet()) { - if (!(delIntsSet.contains(selector.getSelectorAsInt()))) { - result.addUpdatePrimitive( - new ReplaceInArrayPrimitive( - target.getTargetAsArray(), - selector.getSelectorAsInt(), - tempSelectorMap.get(selector).getSingletonSource() - ) - ); - } - } - } - } - - return result; - } - - public static PendingUpdateList mergeUpdatesMaps(PendingUpdateList pul1, PendingUpdateList pul2) { PendingUpdateList res = new PendingUpdateList(); - Map> resDelRepObjMap; - Map tempSelSrcMap; - Map tempSelSrcResMap; - UpdatePrimitiveSource tempSrc; + Map tempSelSrcMap; + Map> tempSelSrcListMap; + Map tempSelSrcResMap; + Map> tempSelSrcResListMap; + Item tempSrc; + List tempSrcList; ////// OBJECTS // DELETES & REPLACES - for (UpdatePrimitiveTarget target : pul1.delReplaceObjMap.keySet()) { + for (Item target : pul1.delReplaceObjMap.keySet()) { tempSelSrcMap = pul1.delReplaceObjMap.get(target); tempSelSrcResMap = res.delReplaceObjMap.getOrDefault(target, new HashMap<>()); - for (UpdatePrimitiveSelector selector : tempSelSrcMap.keySet()) { + for (Item selector : tempSelSrcMap.keySet()) { tempSelSrcResMap.put(selector, tempSelSrcMap.get(selector)); } res.delReplaceObjMap.put(target,tempSelSrcResMap); } - for (UpdatePrimitiveTarget target : pul2.delReplaceObjMap.keySet()) { + for (Item target : pul2.delReplaceObjMap.keySet()) { tempSelSrcMap = pul2.delReplaceObjMap.get(target); tempSelSrcResMap = res.delReplaceObjMap.getOrDefault(target, new HashMap<>()); - for (UpdatePrimitiveSelector selector : tempSelSrcMap.keySet()) { + for (Item selector : tempSelSrcMap.keySet()) { if (tempSelSrcResMap.containsKey(selector)) { tempSrc = tempSelSrcResMap.get(selector); if (tempSrc != null) { @@ -273,31 +82,31 @@ public static PendingUpdateList mergeUpdatesMaps(PendingUpdateList pul1, Pending res.insertObjMap.putAll(pul1.insertObjMap); - for (UpdatePrimitiveTarget target : pul2.insertObjMap.keySet()) { + for (Item target : pul2.insertObjMap.keySet()) { tempSrc = pul2.insertObjMap.get(target); if (res.insertObjMap.containsKey(target)) { - tempSrc = InsertIntoObjectPrimitive.mergeSources(res.insertObjMap.get(target), tempSrc); +// tempSrc = InsertIntoObjectPrimitive.mergeSources(res.insertObjMap.get(target), tempSrc); } res.insertObjMap.put(target,tempSrc); } // RENAME - for (UpdatePrimitiveTarget target : pul1.renameObjMap.keySet()) { + for (Item target : pul1.renameObjMap.keySet()) { tempSelSrcMap = pul1.renameObjMap.get(target); tempSelSrcResMap = res.renameObjMap.getOrDefault(target, new HashMap<>()); - for (UpdatePrimitiveSelector selector : tempSelSrcMap.keySet()) { + for (Item selector : tempSelSrcMap.keySet()) { tempSelSrcResMap.put(selector, tempSelSrcMap.get(selector)); } res.delReplaceObjMap.put(target,tempSelSrcResMap); } - for (UpdatePrimitiveTarget target : pul2.renameObjMap.keySet()) { + for (Item target : pul2.renameObjMap.keySet()) { tempSelSrcMap = pul2.renameObjMap.get(target); tempSelSrcResMap = res.renameObjMap.getOrDefault(target, new HashMap<>()); - for (UpdatePrimitiveSelector selector : tempSelSrcMap.keySet()) { + for (Item selector : tempSelSrcMap.keySet()) { if (tempSelSrcResMap.containsKey(selector)) { // TODO implement jerr:NUP0010 throw new OurBadException("MULTIPLE RENAME OF SAME TARGET & SELECTOR"); @@ -311,21 +120,21 @@ public static PendingUpdateList mergeUpdatesMaps(PendingUpdateList pul1, Pending // DELETES & REPLACES - for (UpdatePrimitiveTarget target : pul1.delReplaceArrayMap.keySet()) { + for (Item target : pul1.delReplaceArrayMap.keySet()) { tempSelSrcMap = pul1.delReplaceArrayMap.get(target); tempSelSrcResMap = res.delReplaceArrayMap.getOrDefault(target, new HashMap<>()); - for (UpdatePrimitiveSelector selector : tempSelSrcMap.keySet()) { + for (Item selector : tempSelSrcMap.keySet()) { tempSelSrcResMap.put(selector, tempSelSrcMap.get(selector)); } res.delReplaceArrayMap.put(target,tempSelSrcResMap); } - for (UpdatePrimitiveTarget target : pul2.delReplaceArrayMap.keySet()) { + for (Item target : pul2.delReplaceArrayMap.keySet()) { tempSelSrcMap = pul2.delReplaceArrayMap.get(target); tempSelSrcResMap = res.delReplaceArrayMap.getOrDefault(target, new HashMap<>()); - for (UpdatePrimitiveSelector selector : tempSelSrcMap.keySet()) { + for (Item selector : tempSelSrcMap.keySet()) { if (tempSelSrcResMap.containsKey(selector)) { tempSrc = tempSelSrcResMap.get(selector); if (tempSrc != null) { @@ -341,25 +150,25 @@ public static PendingUpdateList mergeUpdatesMaps(PendingUpdateList pul1, Pending // INSERTS - for (UpdatePrimitiveTarget target : pul1.insertArrayMap.keySet()) { - tempSelSrcMap = pul1.insertArrayMap.get(target); - tempSelSrcResMap = res.insertArrayMap.getOrDefault(target, new HashMap<>()); + for (Item target : pul1.insertArrayMap.keySet()) { + tempSelSrcListMap = pul1.insertArrayMap.get(target); + tempSelSrcResListMap = res.insertArrayMap.getOrDefault(target, new HashMap<>()); - for (UpdatePrimitiveSelector selector : tempSelSrcMap.keySet()) { - tempSelSrcResMap.put(selector, tempSelSrcMap.get(selector)); + for (Item selector : tempSelSrcListMap.keySet()) { + tempSelSrcResListMap.put(selector, tempSelSrcListMap.get(selector)); } - res.insertArrayMap.put(target,tempSelSrcResMap); + res.insertArrayMap.put(target,tempSelSrcResListMap); } - for (UpdatePrimitiveTarget target : pul2.insertArrayMap.keySet()) { - tempSelSrcMap = pul2.insertArrayMap.get(target); - tempSelSrcResMap = res.insertArrayMap.getOrDefault(target, new HashMap<>()); + for (Item target : pul2.insertArrayMap.keySet()) { + tempSelSrcListMap = pul2.insertArrayMap.get(target); + tempSelSrcResListMap = res.insertArrayMap.getOrDefault(target, new HashMap<>()); - for (UpdatePrimitiveSelector selector : tempSelSrcMap.keySet()) { - tempSrc = tempSelSrcResMap.getOrDefault(selector, new UpdatePrimitiveSource(new ObjectItem())); - tempSelSrcResMap.put(selector, InsertIntoArrayPrimitive.mergeSources(tempSelSrcMap.get(selector), tempSrc)); + for (Item selector : tempSelSrcListMap.keySet()) { + tempSrcList = tempSelSrcResListMap.getOrDefault(selector, null); + tempSelSrcResListMap.put(selector, InsertIntoArrayPrimitive.mergeSources(tempSelSrcListMap.get(selector), tempSrcList)); } - res.insertArrayMap.put(target,tempSelSrcResMap); + res.insertArrayMap.put(target,tempSelSrcResListMap); } return res; diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java index 2e822cfc97..8f0defdc84 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java @@ -2,28 +2,47 @@ import org.rumbledb.api.Item; import org.rumbledb.items.ArrayItem; -import org.rumbledb.items.IntItem; -public class DeleteFromArrayPrimitive extends UpdatePrimitive implements UpdatePrimitiveInterface { +public class DeleteFromArrayPrimitive implements UpdatePrimitive { + + + private Item target; + private Item selector; public DeleteFromArrayPrimitive(Item targetArray, Item positionInt) { - super(targetArray, positionInt, positionInt); + if (!targetArray.isArray() || !positionInt.isNumeric()) { + // TODO ERROR + } if (positionInt.getIntValue() < 0 || positionInt.getIntValue() >= targetArray.getSize()) { // TODO throw error or do nothing? } + this.target = targetArray; + this.selector = positionInt; + } + + @Override + public void apply() { + ((ArrayItem) this.target).removeItemAt(this.selector.getIntValue()); } - public ArrayItem getTargetArray() { - return target.getTargetAsArray(); + @Override + public boolean hasSelector() { + return true; } - public IntItem getPositionInt() { - return (IntItem) source.getSingletonSource(); + @Override + public Item getTarget() { + return target; } @Override - public void apply() { - this.getTargetArray().removeItemAt(this.getPositionInt().getIntValue()); + public Item getSelector() { + return selector; + } + + @Override + public Item getContent() { + return null; } @Override diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java index 137470ae8b..273cb9e496 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java @@ -1,44 +1,65 @@ package org.rumbledb.runtime.update.primitives; import org.rumbledb.api.Item; +import org.rumbledb.exceptions.OurBadException; import org.rumbledb.items.ObjectItem; -import org.rumbledb.items.StringItem; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; -public class DeleteFromObjectPrimitive extends UpdatePrimitive implements UpdatePrimitiveInterface { +public class DeleteFromObjectPrimitive implements UpdatePrimitive { - public DeleteFromObjectPrimitive(Item targetObject, List namesToRemove) { - super(targetObject, namesToRemove); - } + private Item target; + private List content; - public ObjectItem getTargetObject() { - return target.getTargetAsObject(); - } + public DeleteFromObjectPrimitive(Item targetObject, List namesToRemove) { + if (!targetObject.isObject() || !namesToRemove.stream().allMatch(Item::isString)) { + // TODO ERROR + } - public List getNamesToRemove() { - return source.getSourceAsListOfStrings(); + this.target = targetObject; + this.content = namesToRemove; } @Override public void apply() { for ( - String str : this.getNamesToRemove().stream().map(Item::getStringValue).collect(Collectors.toList()) + String str : this.content.stream().map(Item::getStringValue).collect(Collectors.toList()) ) { - this.getTargetObject().removeItemByKey(str); + ((ObjectItem) this.target).removeItemByKey(str); } } - public static UpdatePrimitiveSource mergeSources(UpdatePrimitiveSource first, UpdatePrimitiveSource second) { - List merged = first.getSourceAsListOfStrings(); - merged.addAll(second.getSourceAsListOfStrings()); - merged = merged.stream().distinct().collect(Collectors.toList()); - return new UpdatePrimitiveSource(merged); + @Override + public boolean hasSelector() { + return false; + } + + @Override + public Item getTarget() { + return target; + } + + @Override + public Item getSelector() { + throw new OurBadException("INVALID SELECTOR GET IN DELETEFROMOBJECT PRIMITIVE"); + } + + @Override + public List getContentList() { + return content; } @Override public boolean isDeleteObject() { return true; } + + public static List mergeSources(List first, List second) { + List merged = new ArrayList<>(first); + merged.addAll(second); + merged = merged.stream().distinct().collect(Collectors.toList()); + return merged; + } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java index 284b2e465f..6eacc8d122 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java @@ -2,45 +2,63 @@ import org.rumbledb.api.Item; import org.rumbledb.items.ArrayItem; -import org.rumbledb.items.IntItem; import java.util.ArrayList; import java.util.List; -public class InsertIntoArrayPrimitive extends UpdatePrimitive implements UpdatePrimitiveInterface { +public class InsertIntoArrayPrimitive implements UpdatePrimitive { + + private Item target; + private Item selector; + private List content; public InsertIntoArrayPrimitive(Item targetArray, Item positionInt, List sourceSequence) { - super(targetArray, positionInt, sourceSequence); + if (!targetArray.isArray() || !positionInt.isNumeric()) { + // TODO ERROR + } if (positionInt.getIntValue() < 0 || positionInt.getIntValue() >= targetArray.getSize()) { // TODO throw error or do nothing? } + + this.target = targetArray; + this.selector = positionInt; + this.content = sourceSequence; + } - public ArrayItem getTargetArray() { - return target.getTargetAsArray(); + @Override + public void apply() { + ((ArrayItem) this.target).putItemsAt(this.content, this.selector.getIntValue()); } - public IntItem getPositionInt() { - return selector.getSelectorAsInt(); + @Override + public boolean hasSelector() { + return true; } - public List getSourceSequence() { - return source.getSourceAsListOfItems(); + @Override + public Item getTarget() { + return target; } @Override - public void apply() { - this.getTargetArray().putItemsAt(this.getSourceSequence(), this.getPositionInt().getIntValue()); + public Item getSelector() { + return selector; } - public static UpdatePrimitiveSource mergeSources(UpdatePrimitiveSource first, UpdatePrimitiveSource second) { - List merged = new ArrayList<>(first.getSource()); - merged.addAll(second.getSource()); - return new UpdatePrimitiveSource(merged); + @Override + public List getContentList() { + return content; } @Override public boolean isInsertArray() { return true; } + + public static List mergeSources(List first, List second) { + List merged = new ArrayList<>(first); + merged.addAll(second); + return merged; + } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java index 1aafdab895..664f849384 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java @@ -5,32 +5,56 @@ import org.rumbledb.exceptions.OurBadException; import org.rumbledb.items.ObjectItem; -public class InsertIntoObjectPrimitive extends UpdatePrimitive implements UpdatePrimitiveInterface { +public class InsertIntoObjectPrimitive implements UpdatePrimitive { + private Item target; + private Item content; - public InsertIntoObjectPrimitive(Item targetObject, Item sourceObject) { - super(targetObject, sourceObject); + + public InsertIntoObjectPrimitive(Item targetObject, Item contentObject) { + if (!targetObject.isObject() || !contentObject.isObject()) { + // TODO: ERROR + } + this.target = targetObject; + this.content = contentObject; + } + + @Override + public void apply() { + for (String key : this.content.getKeys()) { + this.target.putItemByKey(key, this.target.getItemByKey(key)); + } } - public ObjectItem getTargetObject() { - return target.getTargetAsObject(); + @Override + public boolean hasSelector() { + return false; } - public ObjectItem getSourceObject() { - return (ObjectItem) source.getSingletonSource(); + @Override + public Item getTarget() { + return target; } @Override - public void apply() { - for (String key : this.getSourceObject().getKeys()) { - this.getTargetObject().putItemByKey(key, this.getTargetObject().getItemByKey(key)); - } + public Item getSelector() { + throw new OurBadException("INVALID SELECTOR GET IN INSERTINTOOBJECT PRIMITIVE"); + } + + @Override + public Item getContent() { + return content; + } + + @Override + public boolean isInsertObject() { + return true; } - public static UpdatePrimitiveSource mergeSources(UpdatePrimitiveSource first, UpdatePrimitiveSource second) { + public static Item mergeSources(Item first, Item second) { ObjectItem merged = new ObjectItem(); - ObjectItem objFirst = (ObjectItem) first.getSingletonSource(); - ObjectItem objSecond = (ObjectItem) second.getSingletonSource(); + ObjectItem objFirst = (ObjectItem) first; + ObjectItem objSecond = (ObjectItem) second; try { for (String otherKey : objFirst.getKeys()) { merged.putItemByKey(otherKey, objFirst.getItemByKey(otherKey)); @@ -42,11 +66,6 @@ public static UpdatePrimitiveSource mergeSources(UpdatePrimitiveSource first, Up throw new OurBadException("SHOULD THROW SMTH ELSE"); // TODO THROW jerr:JNUP0005 INSTEAD ON COLLISION } - return new UpdatePrimitiveSource(merged); - } - - @Override - public boolean isInsertObject() { - return true; + return merged; } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java index 8e3cfefd75..e0182e1420 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java @@ -2,35 +2,53 @@ import org.rumbledb.api.Item; import org.rumbledb.items.ObjectItem; -import org.rumbledb.items.StringItem; -public class RenameInObjectPrimitive extends UpdatePrimitive implements UpdatePrimitiveInterface { +public class RenameInObjectPrimitive implements UpdatePrimitive { + + private Item target; + private Item selector; + private Item content; public RenameInObjectPrimitive(Item targetObject, Item targetName, Item replacementName) { - super(targetObject, targetName, replacementName); + + if (!targetObject.isObject() || !targetName.isString() || !replacementName.isString()) { + // TODO ERROR + } + + this.target = targetObject; + this.selector = targetName; + this.content = replacementName; } - public ObjectItem getTargetObject() { - return target.getTargetAsObject(); + @Override + public void apply() { + String name = this.selector.getStringValue(); + if (this.target.getKeys().contains(name)) { + Item item = this.target.getItemByKey(name); + ((ObjectItem) this.target).removeItemByKey(name); + this.target.putItemByKey(this.content.getStringValue(), item); + } + // TODO: implement replace and rename methods for Array & Object to avoid deletion and append } - public StringItem getTargetName() { - return selector.getSelectorAsString(); + @Override + public boolean hasSelector() { + return true; } - public StringItem getReplacementName() { - return (StringItem) source.getSingletonSource(); + @Override + public Item getTarget() { + return target; } @Override - public void apply() { - String name = this.getTargetName().getStringValue(); - if (this.getTargetObject().getKeys().contains(name)) { - Item item = this.getTargetObject().getItemByKey(name); - this.getTargetObject().removeItemByKey(name); - this.getTargetObject().putItemByKey(this.getTargetName().getStringValue(), item); - } - // TODO: implement replace and rename methods for Array & Object to avoid deletion and append + public Item getSelector() { + return selector; + } + + @Override + public Item getContent() { + return content; } @Override diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java index cf5b8b3d0a..757be3b00e 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java @@ -2,37 +2,54 @@ import org.rumbledb.api.Item; import org.rumbledb.items.ArrayItem; -import org.rumbledb.items.IntItem; -public class ReplaceInArrayPrimitive extends UpdatePrimitive implements UpdatePrimitiveInterface { +public class ReplaceInArrayPrimitive implements UpdatePrimitive { + + private Item target; + private Item selector; + private Item content; public ReplaceInArrayPrimitive(Item targetArray, Item positionInt, Item replacementItem) { - super(targetArray, positionInt, replacementItem); + if (!targetArray.isArray() || !positionInt.isNumeric()) { + // TODO ERROR + } + + this.target = targetArray; + this.selector = positionInt; + this.content = replacementItem; + } + + @Override + public void apply() { + int index = this.selector.getIntValue() - 1; + if (index >= 0 || index < this.target.getSize()) { + ((ArrayItem) this.target).removeItemAt(index); + if (index == this.target.getSize()) { + this.target.append(this.content); + } else { + ((ArrayItem) this.target).putItemAt(this.content, index); + } + } } - public ArrayItem getTargetArray() { - return target.getTargetAsArray(); + @Override + public boolean hasSelector() { + return true; } - public IntItem getPositionInt() { - return selector.getSelectorAsInt(); + @Override + public Item getTarget() { + return target; } - public Item getReplacementItem() { - return source.getSingletonSource(); + @Override + public Item getSelector() { + return selector; } @Override - public void apply() { - int index = this.getPositionInt().getIntValue() - 1; - if (index >= 0 || index < this.getTargetArray().getSize()) { - this.getTargetArray().removeItemAt(index); - if (index == this.getTargetArray().getSize()) { - this.getTargetArray().append(this.getReplacementItem()); - } else { - this.getTargetArray().putItemAt(this.getReplacementItem(), index); - } - } + public Item getContent() { + return content; } @Override diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java index 3444a58620..430c1a4ecd 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java @@ -2,33 +2,51 @@ import org.rumbledb.api.Item; import org.rumbledb.items.ObjectItem; -import org.rumbledb.items.StringItem; -public class ReplaceInObjectPrimitive extends UpdatePrimitive implements UpdatePrimitiveInterface { +public class ReplaceInObjectPrimitive implements UpdatePrimitive { + + private Item target; + private Item selector; + private Item content; public ReplaceInObjectPrimitive(Item targetObject, Item targetName, Item replacementItem) { - super(targetObject, targetName, replacementItem); + + if (!targetObject.isObject() || !targetName.isString()) { + // TODO ERROR + } + + this.target = targetObject; + this.selector = targetName; + this.content = replacementItem; } - public ObjectItem getTargetObject() { - return target.getTargetAsObject(); + @Override + public void apply() { + String name = this.getSelector().getStringValue(); + if (this.getTarget().getKeys().contains(name)) { + ((ObjectItem) this.getTarget()).removeItemByKey(name); + this.getTarget().putItemByKey(name, this.getContent()); + } } - public StringItem getTargetName() { - return selector.getSelectorAsString(); + @Override + public boolean hasSelector() { + return true; } - public Item getReplacementItem() { - return source.getSingletonSource(); + @Override + public Item getTarget() { + return target; } @Override - public void apply() { - String name = this.getTargetName().getStringValue(); - if (this.getTargetObject().getKeys().contains(name)) { - this.getTargetObject().removeItemByKey(name); - this.getTargetObject().putItemByKey(name, this.getReplacementItem()); - } + public Item getSelector() { + return selector; + } + + @Override + public Item getContent() { + return content; } @Override diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java index 12be07d504..8583579e8e 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java @@ -1,73 +1,54 @@ package org.rumbledb.runtime.update.primitives; import org.rumbledb.api.Item; -import org.rumbledb.exceptions.OurBadException; import java.util.List; -public abstract class UpdatePrimitive implements UpdatePrimitiveInterface { +public interface UpdatePrimitive { - protected UpdatePrimitiveTarget target; - protected UpdatePrimitiveSelector selector; - protected UpdatePrimitiveSource source; + void apply(); - public UpdatePrimitive( - UpdatePrimitiveTarget target, - UpdatePrimitiveSelector selector, - UpdatePrimitiveSource source - ) { - this.target = target; - this.selector = selector; - this.source = source; - } + boolean hasSelector(); + + Item getTarget(); + + Item getSelector(); - public UpdatePrimitive(Item target, Item selector, Item source) { - this( - new UpdatePrimitiveTarget(target), - new UpdatePrimitiveSelector(selector), - new UpdatePrimitiveSource(source) - ); + default Item getContent() { + throw new UnsupportedOperationException("Operation not defined"); } - public UpdatePrimitive(Item target, Item selector, List source) { - this( - new UpdatePrimitiveTarget(target), - new UpdatePrimitiveSelector(selector), - new UpdatePrimitiveSource(source) - ); + default List getContentList() { + throw new UnsupportedOperationException("Operation not defined"); } - public UpdatePrimitive(Item target, Item source) { - this(new UpdatePrimitiveTarget(target), null, new UpdatePrimitiveSource(source)); + default boolean isDeleteObject() { + return false; } - public UpdatePrimitive(Item target, List source) { - this(new UpdatePrimitiveTarget(target), null, new UpdatePrimitiveSource(source)); + default boolean isDeleteArray() { + return false; } - @Override - public abstract void apply(); + default boolean isInsertObject() { + return false; + } - @Override - public boolean hasSelector() { - return this.selector == null; + default boolean isInsertArray() { + return false; } - @Override - public UpdatePrimitiveTarget getTarget() { - return target; + default boolean isReplaceObject() { + return false; } - @Override - public UpdatePrimitiveSelector getSelector() { - if (!this.hasSelector()) { - throw new OurBadException("Invalid call to getSelector when selector is null"); - } - return selector; + default boolean isReplaceArray() { + return false; } - @Override - public UpdatePrimitiveSource getSource() { - return source; + default boolean isRenameObject() { + return false; } + + } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveFactory.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveFactory.java index 52e225a038..7fd01b9a78 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveFactory.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveFactory.java @@ -15,31 +15,31 @@ public static UpdatePrimitiveFactory getInstance() { return instance; } - public UpdatePrimitiveInterface createDeleteFromArrayPrimitive(Item targetArray, Item selectorInt) { + public UpdatePrimitive createDeleteFromArrayPrimitive(Item targetArray, Item selectorInt) { return new DeleteFromArrayPrimitive(targetArray, selectorInt); } - public UpdatePrimitiveInterface createDeleteFromObjectPrimitive(Item targetObject, List selectorStrs) { + public UpdatePrimitive createDeleteFromObjectPrimitive(Item targetObject, List selectorStrs) { return new DeleteFromObjectPrimitive(targetObject, selectorStrs); } - public UpdatePrimitiveInterface createInsertIntoArrayPrimitive(Item targetArray, Item selectorInt, List contents ) { + public UpdatePrimitive createInsertIntoArrayPrimitive(Item targetArray, Item selectorInt, List contents ) { return new InsertIntoArrayPrimitive(targetArray, selectorInt, contents); } - public UpdatePrimitiveInterface createInsertIntoObjectPrimitive(Item targetObject, Item contentsObject) { + public UpdatePrimitive createInsertIntoObjectPrimitive(Item targetObject, Item contentsObject) { return new InsertIntoObjectPrimitive(targetObject, contentsObject); } - public UpdatePrimitiveInterface createReplaceInArrayPrimitive(Item targetArray, Item selectorInt, Item content) { + public UpdatePrimitive createReplaceInArrayPrimitive(Item targetArray, Item selectorInt, Item content) { return new ReplaceInArrayPrimitive(targetArray, selectorInt, content); } - public UpdatePrimitiveInterface createReplaceInObjectPrimitive(Item targetObject, Item selectorStr, Item content) { + public UpdatePrimitive createReplaceInObjectPrimitive(Item targetObject, Item selectorStr, Item content) { return new ReplaceInObjectPrimitive(targetObject, selectorStr, content); } - public UpdatePrimitiveInterface createRenameInObjectPrimitive(Item targetObject, Item selectorStr, Item content) { + public UpdatePrimitive createRenameInObjectPrimitive(Item targetObject, Item selectorStr, Item content) { return new RenameInObjectPrimitive(targetObject, selectorStr, content); } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveInterface.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveInterface.java deleted file mode 100644 index 84200eeb22..0000000000 --- a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveInterface.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.rumbledb.runtime.update.primitives; - -public interface UpdatePrimitiveInterface { - - void apply(); - - boolean hasSelector(); - - UpdatePrimitiveTarget getTarget(); - - UpdatePrimitiveSelector getSelector(); - - UpdatePrimitiveSource getSource(); - - default boolean isDeleteObject() { - return false; - } - - default boolean isDeleteArray() { - return false; - } - - default boolean isInsertObject() { - return false; - } - - default boolean isInsertArray() { - return false; - } - - default boolean isReplaceObject() { - return false; - } - - default boolean isReplaceArray() { - return false; - } - - default boolean isRenameObject() { - return false; - } - - -} diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveSelector.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveSelector.java deleted file mode 100644 index 72745c91a6..0000000000 --- a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveSelector.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.rumbledb.runtime.update.primitives; - -import org.rumbledb.api.Item; -import org.rumbledb.exceptions.OurBadException; -import org.rumbledb.items.IntItem; -import org.rumbledb.items.StringItem; - - -public class UpdatePrimitiveSelector { - - private Item selector; - - public UpdatePrimitiveSelector(Item selector) { - if (!selector.isString() && !selector.isNumeric()) { - throw new OurBadException("Locators of primitives must be strings or numeric"); - } - this.selector = selector; - } - - public Item getSelector() { - return selector; - } - - public StringItem getSelectorAsString() { - if (!this.isString()) { - throw new OurBadException("Invalid call to getSelectorAsString"); - } - return (StringItem) this.selector; - } - - public IntItem getSelectorAsInt() { - if (!this.isNumeric()) { - throw new OurBadException("Invalid call to getSelectorAsInt"); - } - return (IntItem) this.selector; - } - - public boolean isString() { - return this.selector.isString(); - } - - public boolean isNumeric() { - return this.selector.isNumeric(); - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - UpdatePrimitiveSelector that = (UpdatePrimitiveSelector) o; - return selector.equals(that.selector); - } - - @Override - public int hashCode() { - return selector.hashCode(); - } -} diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveSource.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveSource.java deleted file mode 100644 index 60e4fe3c90..0000000000 --- a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveSource.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.rumbledb.runtime.update.primitives; - -import org.rumbledb.api.Item; -import org.rumbledb.items.StringItem; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public class UpdatePrimitiveSource { - - private List source; - - public UpdatePrimitiveSource(List source) { - this.source = source; - } - - public UpdatePrimitiveSource(Item source) { - this.source = Collections.singletonList(source); - } - - public List getSource() { - return source; - } - - public Item getSingletonSource() { - if (this.isSingleton()) { - return this.source.get(0); - } - // TODO: Find out if error - return null; - } - - public boolean isSingleton() { - return this.source.size() == 1; - } - - public List getSourceAsListOfStrings() { - return new ArrayList<>(this.source); - } - - public List getSourceAsListOfItems() { - return new ArrayList<>(this.source); - } - -} diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveTarget.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveTarget.java deleted file mode 100644 index b356ddd2ad..0000000000 --- a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveTarget.java +++ /dev/null @@ -1,59 +0,0 @@ -package org.rumbledb.runtime.update.primitives; - -import org.rumbledb.api.Item; -import org.rumbledb.exceptions.OurBadException; -import org.rumbledb.items.ArrayItem; -import org.rumbledb.items.ObjectItem; - -public class UpdatePrimitiveTarget { - - private Item target; - - public UpdatePrimitiveTarget(Item target) { - if (!target.isArray() && !target.isObject()) { - throw new OurBadException("Targets of primitives must be arrays or objects"); - } - this.target = target; - } - - public Item getTarget() { - return target; - } - - public ArrayItem getTargetAsArray() { - if (!this.isArray()) { - throw new OurBadException("Invalid call to getTargetAsArray"); - } - return (ArrayItem) this.target; - } - - public ObjectItem getTargetAsObject() { - if (!this.isArray()) { - throw new OurBadException("Invalid call to getTargetAsObject"); - } - return (ObjectItem) this.target; - } - - public boolean isArray() { - return this.target.isArray(); - } - - public boolean isObject() { - return this.target.isObject(); - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - UpdatePrimitiveTarget that = (UpdatePrimitiveTarget) o; - return target.equals(that.target); - } - - @Override - public int hashCode() { - return target.hashCode(); - } -} From 7ce6e465b854d7e3f616a8bd9cff361852feeb4a Mon Sep 17 00:00:00 2001 From: dloughlin Date: Fri, 21 Apr 2023 19:14:30 +0200 Subject: [PATCH 048/119] Implement ApplyUpdates in PendingUpdateList.java --- .../runtime/update/PendingUpdateList.java | 83 +++++++++++++++++-- 1 file changed, 74 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java index 7df5b76a2d..ce81246df5 100644 --- a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java +++ b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java @@ -1,11 +1,7 @@ package org.rumbledb.runtime.update; -import com.amazonaws.services.dynamodbv2.model.ItemCollectionMetrics; import org.rumbledb.api.Item; import org.rumbledb.exceptions.OurBadException; -import org.rumbledb.items.IntItem; -import org.rumbledb.items.ObjectItem; -import org.rumbledb.items.StringItem; import org.rumbledb.runtime.update.primitives.*; import java.util.*; @@ -31,11 +27,80 @@ public PendingUpdateList() { // } -// public void applyUpdates() { -// for (UpdatePrimitive up : this.updatePrimitives) { -// up.apply(); -// } -// } + public void applyUpdates() { + + UpdatePrimitiveFactory factory = UpdatePrimitiveFactory.getInstance(); + + List pul = new ArrayList<>(); + Map tempSelSrcMap; + Map> tempSelSrcListMap; + Item tempSrc; + List tempSrcList; + + ////// OBJECTS + + // DELETES & REPLACES + for (Item target : delReplaceObjMap.keySet()) { + List toDel = new ArrayList<>(); + tempSelSrcMap = delReplaceObjMap.get(target); + for (Item locator : tempSelSrcMap.keySet()) { + tempSrc = tempSelSrcMap.get(locator); + if (tempSrc == null) { + toDel.add(locator); + } else { + pul.add(factory.createReplaceInObjectPrimitive(target, locator, tempSrc)); + } + } + pul.add(factory.createDeleteFromObjectPrimitive(target, toDel)); + } + + // INSERTS + + for (Item target : insertObjMap.keySet()) { + pul.add(factory.createInsertIntoObjectPrimitive(target, insertObjMap.get(target))); + } + + // RENAMES + + for (Item target : renameObjMap.keySet()) { + tempSelSrcMap = renameObjMap.get(target); + for (Item locator : tempSelSrcMap.keySet()) { + pul.add(factory.createRenameInObjectPrimitive(target, locator, tempSelSrcMap.get(locator))); + } + } + + ////// ARRAYS + + // DELETES & REPLACES + + for (Item target : delReplaceArrayMap.keySet()) { + tempSelSrcMap = delReplaceArrayMap.get(target); + for (Item locator : tempSelSrcMap.keySet()) { + tempSrc = tempSelSrcMap.get(locator); + if (tempSrc == null) { + pul.add(factory.createDeleteFromArrayPrimitive(target, locator)); + } else { + pul.add(factory.createReplaceInArrayPrimitive(target, locator, tempSrc)); + } + } + } + + // INSERTS + + for (Item target : insertArrayMap.keySet()) { + tempSelSrcListMap = insertArrayMap.get(target); + for (Item locator : tempSelSrcListMap.keySet()) { + pul.add(factory.createInsertIntoArrayPrimitive(target, locator, tempSelSrcListMap.get(locator))); + } + } + + ////// APPLY + + for (UpdatePrimitive updatePrimitive : pul) { + updatePrimitive.apply(); + } + + } public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpdateList pul2) { PendingUpdateList res = new PendingUpdateList(); From d5e609615a7f88ac09ffb356ea168b7c253bb5f1 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Thu, 27 Apr 2023 12:47:59 +0200 Subject: [PATCH 049/119] Implement errors during merge and apply updates --- .../org/rumbledb/errorcodes/ErrorCode.java | 7 +- .../DuplicateKeyOnUpdateApplyException.java | 16 ++++ .../DuplicateObjectInsertSourceException.java | 17 +++++ ...yRenamesOnSameTargetSelectorException.java | 17 +++++ ...ReplacesOnSameTargetSelectorException.java | 16 ++++ .../java/org/rumbledb/items/ObjectItem.java | 13 ---- .../runtime/update/PendingUpdateList.java | 73 +++++++++++++++---- .../primitives/InsertIntoObjectPrimitive.java | 41 ++++++----- .../primitives/UpdatePrimitiveEnum.java | 14 ---- 9 files changed, 154 insertions(+), 60 deletions(-) create mode 100644 src/main/java/org/rumbledb/exceptions/DuplicateKeyOnUpdateApplyException.java create mode 100644 src/main/java/org/rumbledb/exceptions/DuplicateObjectInsertSourceException.java create mode 100644 src/main/java/org/rumbledb/exceptions/TooManyRenamesOnSameTargetSelectorException.java create mode 100644 src/main/java/org/rumbledb/exceptions/TooManyReplacesOnSameTargetSelectorException.java delete mode 100644 src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveEnum.java diff --git a/src/main/java/org/rumbledb/errorcodes/ErrorCode.java b/src/main/java/org/rumbledb/errorcodes/ErrorCode.java index 2a9d69ca75..8c13473945 100644 --- a/src/main/java/org/rumbledb/errorcodes/ErrorCode.java +++ b/src/main/java/org/rumbledb/errorcodes/ErrorCode.java @@ -123,7 +123,12 @@ public enum ErrorCode { InvalidTimezoneValue("FODT0003"), InvalidUpdatingExpressionPositionErrorCode("XUST0001"), - SimpleExpressionMustBeVacuousErrorCode("XUST0002"); + SimpleExpressionMustBeVacuousErrorCode("XUST0002"), + + DuplicateObjectInsertSourceErrorCode("JNUP0005"), + DuplicateKeyOnUpdateApplyErrorCode("JNUP0006"), + TooManyReplacesOnSameTargetSelectorErrorCode("JNUP0009"), + TooManyRenamesOnSameTargetSelectorErrorCode("JNUP0010"); diff --git a/src/main/java/org/rumbledb/exceptions/DuplicateKeyOnUpdateApplyException.java b/src/main/java/org/rumbledb/exceptions/DuplicateKeyOnUpdateApplyException.java new file mode 100644 index 0000000000..e29f2cd4ac --- /dev/null +++ b/src/main/java/org/rumbledb/exceptions/DuplicateKeyOnUpdateApplyException.java @@ -0,0 +1,16 @@ +package org.rumbledb.exceptions; + +import org.rumbledb.errorcodes.ErrorCode; + +public class DuplicateKeyOnUpdateApplyException extends RumbleException { + + private static final long serialVersionUID = 1L; + + public DuplicateKeyOnUpdateApplyException(String keyInfo, ExceptionMetadata metadata) { + super( + "Dynamic Updating error; Duplicate keys inserted into target object during update application: " + keyInfo + ".", + ErrorCode.DuplicateKeyOnUpdateApplyErrorCode, + metadata + ); + } +} diff --git a/src/main/java/org/rumbledb/exceptions/DuplicateObjectInsertSourceException.java b/src/main/java/org/rumbledb/exceptions/DuplicateObjectInsertSourceException.java new file mode 100644 index 0000000000..6bfaa262fb --- /dev/null +++ b/src/main/java/org/rumbledb/exceptions/DuplicateObjectInsertSourceException.java @@ -0,0 +1,17 @@ +package org.rumbledb.exceptions; + +import org.rumbledb.errorcodes.ErrorCode; + +public class DuplicateObjectInsertSourceException extends RumbleException { + + private static final long serialVersionUID = 1L; + + public DuplicateObjectInsertSourceException(String keyInfo, ExceptionMetadata metadata) { + super( + "Dynamic Updating error; Duplicate keys to insert into object: " + keyInfo + ".", + ErrorCode.DuplicateObjectInsertSourceErrorCode, + metadata + ); + } + +} diff --git a/src/main/java/org/rumbledb/exceptions/TooManyRenamesOnSameTargetSelectorException.java b/src/main/java/org/rumbledb/exceptions/TooManyRenamesOnSameTargetSelectorException.java new file mode 100644 index 0000000000..65bd8b1f89 --- /dev/null +++ b/src/main/java/org/rumbledb/exceptions/TooManyRenamesOnSameTargetSelectorException.java @@ -0,0 +1,17 @@ +package org.rumbledb.exceptions; + +import org.rumbledb.errorcodes.ErrorCode; + +public class TooManyRenamesOnSameTargetSelectorException extends RumbleException { + + private static final long serialVersionUID = 1L; + + public TooManyRenamesOnSameTargetSelectorException(String keyInfo, ExceptionMetadata metadata) { + super( + "Dynamic Updating error; Too many renames on same object at key: " + keyInfo + ".", + ErrorCode.TooManyRenamesOnSameTargetSelectorErrorCode, + metadata + ); + } + +} diff --git a/src/main/java/org/rumbledb/exceptions/TooManyReplacesOnSameTargetSelectorException.java b/src/main/java/org/rumbledb/exceptions/TooManyReplacesOnSameTargetSelectorException.java new file mode 100644 index 0000000000..7f7808383e --- /dev/null +++ b/src/main/java/org/rumbledb/exceptions/TooManyReplacesOnSameTargetSelectorException.java @@ -0,0 +1,16 @@ +package org.rumbledb.exceptions; + +import org.rumbledb.errorcodes.ErrorCode; + +public class TooManyReplacesOnSameTargetSelectorException extends RumbleException { + + private static final long serialVersionUID = 1L; + + public TooManyReplacesOnSameTargetSelectorException(String targetInfo, String selectorInfo, ExceptionMetadata metadata) { + super( + "Dynamic Updating error; Too many replaces on " + targetInfo + " at: " + selectorInfo + ".", + ErrorCode.TooManyReplacesOnSameTargetSelectorErrorCode, + metadata + ); + } +} diff --git a/src/main/java/org/rumbledb/items/ObjectItem.java b/src/main/java/org/rumbledb/items/ObjectItem.java index b11ac1f137..a29b71decf 100644 --- a/src/main/java/org/rumbledb/items/ObjectItem.java +++ b/src/main/java/org/rumbledb/items/ObjectItem.java @@ -160,19 +160,6 @@ public void removeItemByKey(String s) { } } - public static ObjectItem mergeWith(ObjectItem obj1, ObjectItem obj2) { - ObjectItem result = new ObjectItem(); - - for (String otherKey : obj1.getKeys()) { - result.putItemByKey(otherKey, obj1.getItemByKey(otherKey)); - } - for (String otherKey : obj2.getKeys()) { - result.putItemByKey(otherKey, obj2.getItemByKey(otherKey)); - } - // TODO Raise jerr:JNUP0005 on collision - return result; - } - @Override public boolean isObject() { return true; diff --git a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java index ce81246df5..90dd9c887a 100644 --- a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java +++ b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java @@ -1,8 +1,13 @@ package org.rumbledb.runtime.update; +import org.apache.hadoop.mapred.lib.DelegatingInputFormat; import org.rumbledb.api.Item; +import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.OurBadException; +import org.rumbledb.exceptions.TooManyRenamesOnSameTargetSelectorException; +import org.rumbledb.exceptions.TooManyReplacesOnSameTargetSelectorException; import org.rumbledb.runtime.update.primitives.*; +import org.rumbledb.types.ItemType; import java.util.*; @@ -15,17 +20,58 @@ public class PendingUpdateList { private Map> renameObjMap; public PendingUpdateList() { - + this.insertObjMap = new HashMap<>(); + this.insertArrayMap = new HashMap<>(); + this.delReplaceObjMap = new HashMap<>(); + this.delReplaceArrayMap = new HashMap<>(); + this.renameObjMap = new HashMap<>(); } -// public void addUpdatePrimitive(UpdatePrimitive updatePrimitive) { -// this.updatePrimitives.add(updatePrimitive); -// } -// -// public void addAllUpdatePrimitives(List updatePrimitives) { -// this.updatePrimitives.addAll(updatePrimitives); -// } + public PendingUpdateList(UpdatePrimitive updatePrimitive) { + this(); + this.addUpdatePrimitive(updatePrimitive); + } + public void addUpdatePrimitive(UpdatePrimitive updatePrimitive) { + Item target = updatePrimitive.getTarget(); + if (updatePrimitive.isDeleteObject()) { + Map locSrcMap = delReplaceObjMap.getOrDefault(target, new HashMap<>()); + for (Item locator : updatePrimitive.getContentList()) { + locSrcMap.put(locator, null); + } + delReplaceObjMap.put(target, locSrcMap); + + } else if (updatePrimitive.isReplaceObject()) { + Map locSrcMap = delReplaceObjMap.getOrDefault(target, new HashMap<>()); + locSrcMap.put(updatePrimitive.getSelector(), updatePrimitive.getContent()); + delReplaceObjMap.put(target, locSrcMap); + + } else if (updatePrimitive.isInsertObject()) { + insertObjMap.put(target, updatePrimitive.getContent()); + + } else if (updatePrimitive.isRenameObject()) { + Map locSrcMap = renameObjMap.getOrDefault(target, new HashMap<>()); + locSrcMap.put(updatePrimitive.getSelector(), updatePrimitive.getContent()); + renameObjMap.put(target, locSrcMap); + + } else if (updatePrimitive.isDeleteArray()) { + Map locSrcMap = delReplaceArrayMap.getOrDefault(target, new HashMap<>()); + locSrcMap.put(updatePrimitive.getSelector(), null); + delReplaceArrayMap.put(target, locSrcMap); + + } else if (updatePrimitive.isReplaceArray()) { + Map locSrcMap = delReplaceArrayMap.getOrDefault(target, new HashMap<>()); + locSrcMap.put(updatePrimitive.getSelector(), updatePrimitive.getContent()); + delReplaceArrayMap.put(target, locSrcMap); + + } else if (updatePrimitive.isInsertArray()) { + Map> locSrcMap = insertArrayMap.getOrDefault(target, new HashMap<>()); + locSrcMap.put(updatePrimitive.getSelector(), updatePrimitive.getContentList()); + insertArrayMap.put(target, locSrcMap); + } else { + throw new OurBadException("Invalid UpdatePrimitive created"); + } + } public void applyUpdates() { @@ -133,8 +179,7 @@ public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpda if (tempSelSrcResMap.containsKey(selector)) { tempSrc = tempSelSrcResMap.get(selector); if (tempSrc != null) { - // TODO implement jerr:NUP0009 - throw new OurBadException("MULTIPLE REPLACE OF SAME TARGET & SELECTOR"); + throw new TooManyReplacesOnSameTargetSelectorException(target.getDynamicType().getName().toString(), selector.getStringValue(), ExceptionMetadata.EMPTY_METADATA); } continue; } @@ -150,7 +195,7 @@ public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpda for (Item target : pul2.insertObjMap.keySet()) { tempSrc = pul2.insertObjMap.get(target); if (res.insertObjMap.containsKey(target)) { -// tempSrc = InsertIntoObjectPrimitive.mergeSources(res.insertObjMap.get(target), tempSrc); + tempSrc = InsertIntoObjectPrimitive.mergeSources(res.insertObjMap.get(target), tempSrc); } res.insertObjMap.put(target,tempSrc); } @@ -173,8 +218,7 @@ public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpda for (Item selector : tempSelSrcMap.keySet()) { if (tempSelSrcResMap.containsKey(selector)) { - // TODO implement jerr:NUP0010 - throw new OurBadException("MULTIPLE RENAME OF SAME TARGET & SELECTOR"); + throw new TooManyRenamesOnSameTargetSelectorException(selector.getStringValue(), ExceptionMetadata.EMPTY_METADATA); } tempSelSrcResMap.put(selector, tempSelSrcMap.get(selector)); } @@ -203,8 +247,7 @@ public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpda if (tempSelSrcResMap.containsKey(selector)) { tempSrc = tempSelSrcResMap.get(selector); if (tempSrc != null) { - // TODO implement jerr:NUP0009 - throw new OurBadException("MULTIPLE REPLACE OF SAME TARGET & SELECTOR"); + throw new TooManyReplacesOnSameTargetSelectorException(target.getDynamicType().getName().toString(), Integer.toString(selector.getIntValue()), ExceptionMetadata.EMPTY_METADATA); } continue; } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java index 664f849384..a341b817f4 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java @@ -1,9 +1,11 @@ package org.rumbledb.runtime.update.primitives; import org.rumbledb.api.Item; -import org.rumbledb.exceptions.DuplicateObjectKeyException; -import org.rumbledb.exceptions.OurBadException; -import org.rumbledb.items.ObjectItem; +import org.rumbledb.exceptions.*; +import org.rumbledb.items.ItemFactory; + +import java.util.ArrayList; +import java.util.List; public class InsertIntoObjectPrimitive implements UpdatePrimitive { @@ -21,8 +23,12 @@ public InsertIntoObjectPrimitive(Item targetObject, Item contentObject) { @Override public void apply() { - for (String key : this.content.getKeys()) { - this.target.putItemByKey(key, this.target.getItemByKey(key)); + try { + for (String key : this.content.getKeys()) { + this.target.putItemByKey(key, this.target.getItemByKey(key)); + } + } catch (DuplicateObjectKeyException e) { + throw new DuplicateKeyOnUpdateApplyException(e.getMessage(), ExceptionMetadata.EMPTY_METADATA); } } @@ -52,20 +58,21 @@ public boolean isInsertObject() { } public static Item mergeSources(Item first, Item second) { - ObjectItem merged = new ObjectItem(); - ObjectItem objFirst = (ObjectItem) first; - ObjectItem objSecond = (ObjectItem) second; + // TODO: ADD METADATA + Item res; + + List keys = new ArrayList<>(first.getKeys()); + keys.addAll(second.getKeys()); + + List values = new ArrayList<>(first.getValues()); + values.addAll(second.getValues()); + try { - for (String otherKey : objFirst.getKeys()) { - merged.putItemByKey(otherKey, objFirst.getItemByKey(otherKey)); - } - for (String otherKey : objSecond.getKeys()) { - merged.putItemByKey(otherKey, objSecond.getItemByKey(otherKey)); - } + res = ItemFactory.getInstance().createObjectItem(keys, values, ExceptionMetadata.EMPTY_METADATA); } catch (DuplicateObjectKeyException e) { - throw new OurBadException("SHOULD THROW SMTH ELSE"); - // TODO THROW jerr:JNUP0005 INSTEAD ON COLLISION + throw new DuplicateObjectInsertSourceException(e.getMessage(), ExceptionMetadata.EMPTY_METADATA); } - return merged; + + return res; } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveEnum.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveEnum.java deleted file mode 100644 index 4e473d37ef..0000000000 --- a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveEnum.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.rumbledb.runtime.update.primitives; - - -public enum UpdatePrimitiveEnum { - - DELETE_FROM_ARRAY, - DELETE_FROM_OBJECT, - INSERT_INTO_ARRAY, - INSERT_INTO_OBJECT, - REPLACE_IN_ARRAY, - REPLACE_IN_OBJECT, - RENAME_IN_OBJECT; - -} From 162ab3af10aa5eff6869465885c85a6c6b1a7f47 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Thu, 27 Apr 2023 13:10:01 +0200 Subject: [PATCH 050/119] Move item specific functions into interface --- src/main/java/org/rumbledb/api/Item.java | 38 +++++++++++++++++++ .../java/org/rumbledb/items/ArrayItem.java | 3 ++ .../primitives/DeleteFromArrayPrimitive.java | 2 +- .../primitives/DeleteFromObjectPrimitive.java | 7 +--- .../primitives/InsertIntoArrayPrimitive.java | 2 +- .../primitives/RenameInObjectPrimitive.java | 2 +- .../primitives/ReplaceInArrayPrimitive.java | 4 +- .../primitives/ReplaceInObjectPrimitive.java | 2 +- .../update/primitives/UpdatePrimitive.java | 2 +- 9 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/rumbledb/api/Item.java b/src/main/java/org/rumbledb/api/Item.java index 98834d5b6d..20581464ad 100644 --- a/src/main/java/org/rumbledb/api/Item.java +++ b/src/main/java/org/rumbledb/api/Item.java @@ -558,6 +558,35 @@ default void putItem(Item item) { throw new UnsupportedOperationException("Operation not defined for type " + this.getDynamicType()); } + /** + * Add an item at index i, if it is an array. + * + * @param item an item. + * @param i an integer. + */ + default void putItemAt(Item item, int i) { + throw new UnsupportedOperationException("Operation not defined for type " + this.getDynamicType()); + } + + /** + * Add all items in items at index i, if it is an array. + * + * @param items a list of items. + * @param i an integer. + */ + default void putItemsAt(List items, int i) { + throw new UnsupportedOperationException("Operation not defined for type " + this.getDynamicType()); + } + + /** + * Remove the item at index i, if it is an array. + * + * @param i an integer. + */ + default void removeItemAt(int i) { + throw new UnsupportedOperationException("Operation not defined for type " + this.getDynamicType()); + } + /** * Adds a value pair, if it is an array item. * @@ -577,6 +606,15 @@ default void putItemByKey(String key, Item value) { throw new UnsupportedOperationException("Operation not defined for type " + this.getDynamicType()); } + /** + * Removes a key-value pair, if it is an object item. + * + * @param key a key. + */ + default void removeItemByKey(String key) { + throw new UnsupportedOperationException("Operation not defined for type " + this.getDynamicType()); + } + /** * Adds a key-value pair, if it is an object item. The value is lazily computed. * diff --git a/src/main/java/org/rumbledb/items/ArrayItem.java b/src/main/java/org/rumbledb/items/ArrayItem.java index e7fce02dee..b213dbf35c 100644 --- a/src/main/java/org/rumbledb/items/ArrayItem.java +++ b/src/main/java/org/rumbledb/items/ArrayItem.java @@ -83,14 +83,17 @@ public void putItem(Item value) { this.arrayItems.add(value); } + @Override public void putItemAt(Item value, int i) { this.arrayItems.add(i, value); } + @Override public void putItemsAt(List values, int i) { this.arrayItems.addAll(i, values); } + @Override public void removeItemAt(int i) { this.arrayItems.remove(i); } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java index 8f0defdc84..1978323886 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java @@ -22,7 +22,7 @@ public DeleteFromArrayPrimitive(Item targetArray, Item positionInt) { @Override public void apply() { - ((ArrayItem) this.target).removeItemAt(this.selector.getIntValue()); + this.target.removeItemAt(this.selector.getIntValue()); } @Override diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java index 273cb9e496..8423332f42 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java @@ -27,7 +27,7 @@ public void apply() { for ( String str : this.content.stream().map(Item::getStringValue).collect(Collectors.toList()) ) { - ((ObjectItem) this.target).removeItemByKey(str); + this.target.removeItemByKey(str); } } @@ -41,11 +41,6 @@ public Item getTarget() { return target; } - @Override - public Item getSelector() { - throw new OurBadException("INVALID SELECTOR GET IN DELETEFROMOBJECT PRIMITIVE"); - } - @Override public List getContentList() { return content; diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java index 6eacc8d122..4497415105 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java @@ -28,7 +28,7 @@ public InsertIntoArrayPrimitive(Item targetArray, Item positionInt, List s @Override public void apply() { - ((ArrayItem) this.target).putItemsAt(this.content, this.selector.getIntValue()); + this.target.putItemsAt(this.content, this.selector.getIntValue()); } @Override diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java index e0182e1420..1b50f1af27 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java @@ -25,7 +25,7 @@ public void apply() { String name = this.selector.getStringValue(); if (this.target.getKeys().contains(name)) { Item item = this.target.getItemByKey(name); - ((ObjectItem) this.target).removeItemByKey(name); + this.target.removeItemByKey(name); this.target.putItemByKey(this.content.getStringValue(), item); } // TODO: implement replace and rename methods for Array & Object to avoid deletion and append diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java index 757be3b00e..f3386ff37b 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java @@ -23,11 +23,11 @@ public ReplaceInArrayPrimitive(Item targetArray, Item positionInt, Item replacem public void apply() { int index = this.selector.getIntValue() - 1; if (index >= 0 || index < this.target.getSize()) { - ((ArrayItem) this.target).removeItemAt(index); + this.target.removeItemAt(index); if (index == this.target.getSize()) { this.target.append(this.content); } else { - ((ArrayItem) this.target).putItemAt(this.content, index); + this.target.putItemAt(this.content, index); } } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java index 430c1a4ecd..3686cc8ed7 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java @@ -24,7 +24,7 @@ public ReplaceInObjectPrimitive(Item targetObject, Item targetName, Item replace public void apply() { String name = this.getSelector().getStringValue(); if (this.getTarget().getKeys().contains(name)) { - ((ObjectItem) this.getTarget()).removeItemByKey(name); + this.getTarget().removeItemByKey(name); this.getTarget().putItemByKey(name, this.getContent()); } } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java index 8583579e8e..bfc30de0de 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java @@ -12,7 +12,7 @@ public interface UpdatePrimitive { Item getTarget(); - Item getSelector(); + default Item getSelector() {throw new UnsupportedOperationException("Operation not defined");} default Item getContent() { throw new UnsupportedOperationException("Operation not defined"); From 831bc4ce3a7d9e49957c6a5a79993d085b84e7af Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 1 May 2023 18:14:24 +0200 Subject: [PATCH 051/119] Create classes for Updating expression iterators --- .../expression/AppendExpressionIterator.java | 47 ++++++++++ .../expression/DeleteExpressionIterator.java | 89 +++++++++++++++++++ .../expression/InsertExpressionIterator.java | 47 ++++++++++ .../expression/RenameExpressionIterator.java | 47 ++++++++++ .../expression/ReplaceExpressionIterator.java | 47 ++++++++++ .../TransformExpressionIterator.java | 67 ++++++++++++++ 6 files changed, 344 insertions(+) create mode 100644 src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java create mode 100644 src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java create mode 100644 src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java create mode 100644 src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java create mode 100644 src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java create mode 100644 src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java diff --git a/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java new file mode 100644 index 0000000000..e06b27cd3b --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java @@ -0,0 +1,47 @@ +package org.rumbledb.runtime.update.expression; + +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.expressions.ExecutionMode; +import org.rumbledb.runtime.HybridRuntimeIterator; +import org.rumbledb.runtime.RuntimeIterator; + +import java.util.List; + +public class AppendExpressionIterator extends HybridRuntimeIterator { + protected AppendExpressionIterator(List children, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { + super(children, executionMode, iteratorMetadata); + } + + @Override + protected JavaRDD getRDDAux(DynamicContext context) { + return null; + } + + @Override + protected void openLocal() { + + } + + @Override + protected void closeLocal() { + + } + + @Override + protected void resetLocal() { + + } + + @Override + protected boolean hasNextLocal() { + return false; + } + + @Override + protected Item nextLocal() { + return null; + } +} diff --git a/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java new file mode 100644 index 0000000000..1967526f67 --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java @@ -0,0 +1,89 @@ +package org.rumbledb.runtime.update.expression; + +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.MoreThanOneItemException; +import org.rumbledb.exceptions.NoItemException; +import org.rumbledb.exceptions.OurBadException; +import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.runtime.HybridRuntimeIterator; +import org.rumbledb.runtime.RuntimeIterator; +import org.rumbledb.runtime.update.PendingUpdateList; +import org.rumbledb.runtime.update.primitives.UpdatePrimitive; +import org.rumbledb.runtime.update.primitives.UpdatePrimitiveFactory; + +import java.util.Arrays; +import java.util.Collections; + +public class DeleteExpressionIterator extends HybridRuntimeIterator { + + private RuntimeIterator mainIterator; + private RuntimeIterator lookupIterator; + + public DeleteExpressionIterator(RuntimeIterator mainIterator, RuntimeIterator lookupIterator, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { + super(Arrays.asList(mainIterator, lookupIterator), executionMode, iteratorMetadata); + this.mainIterator = mainIterator; + this.lookupIterator = lookupIterator; + this.isUpdating = true; + } + + @Override + protected JavaRDD getRDDAux(DynamicContext context) { + return null; + } + + @Override + protected void openLocal() { + + } + + @Override + protected void closeLocal() { + + } + + @Override + protected void resetLocal() { + + } + + @Override + protected boolean hasNextLocal() { + return false; + } + + @Override + protected Item nextLocal() { + return null; + } + + @Override + public PendingUpdateList getPendingUpdateList(DynamicContext dynamicContext) { + PendingUpdateList pul = new PendingUpdateList(); + Item main; + Item lookup; + + try { + main = this.mainIterator.materializeExactlyOneItem(dynamicContext); + lookup = this.lookupIterator.materializeExactlyOneItem(dynamicContext); + } catch (NoItemException | MoreThanOneItemException e) { + throw new RuntimeException(e); + } + + UpdatePrimitiveFactory factory = UpdatePrimitiveFactory.getInstance(); + UpdatePrimitive up; + if (main.isObject()) { + up = factory.createDeleteFromObjectPrimitive(main, Collections.singletonList(lookup)); + } else if (main.isArray()) { + up = factory.createDeleteFromArrayPrimitive(main, lookup); + } else { + throw new OurBadException("Delete iterator cannot handle main items that are not objects or arrays"); + } + + pul.addUpdatePrimitive(up); + + return pul; + } +} diff --git a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java new file mode 100644 index 0000000000..79f24a84ee --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java @@ -0,0 +1,47 @@ +package org.rumbledb.runtime.update.expression; + +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.expressions.ExecutionMode; +import org.rumbledb.runtime.HybridRuntimeIterator; +import org.rumbledb.runtime.RuntimeIterator; + +import java.util.List; + +public class InsertExpressionIterator extends HybridRuntimeIterator { + protected InsertExpressionIterator(List children, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { + super(children, executionMode, iteratorMetadata); + } + + @Override + protected JavaRDD getRDDAux(DynamicContext context) { + return null; + } + + @Override + protected void openLocal() { + + } + + @Override + protected void closeLocal() { + + } + + @Override + protected void resetLocal() { + + } + + @Override + protected boolean hasNextLocal() { + return false; + } + + @Override + protected Item nextLocal() { + return null; + } +} diff --git a/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java new file mode 100644 index 0000000000..32712a3f92 --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java @@ -0,0 +1,47 @@ +package org.rumbledb.runtime.update.expression; + +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.expressions.ExecutionMode; +import org.rumbledb.runtime.HybridRuntimeIterator; +import org.rumbledb.runtime.RuntimeIterator; + +import java.util.List; + +public class RenameExpressionIterator extends HybridRuntimeIterator { + protected RenameExpressionIterator(List children, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { + super(children, executionMode, iteratorMetadata); + } + + @Override + protected JavaRDD getRDDAux(DynamicContext context) { + return null; + } + + @Override + protected void openLocal() { + + } + + @Override + protected void closeLocal() { + + } + + @Override + protected void resetLocal() { + + } + + @Override + protected boolean hasNextLocal() { + return false; + } + + @Override + protected Item nextLocal() { + return null; + } +} diff --git a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java new file mode 100644 index 0000000000..36ac41d1e2 --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java @@ -0,0 +1,47 @@ +package org.rumbledb.runtime.update.expression; + +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.expressions.ExecutionMode; +import org.rumbledb.runtime.HybridRuntimeIterator; +import org.rumbledb.runtime.RuntimeIterator; + +import java.util.List; + +public class ReplaceExpressionIterator extends HybridRuntimeIterator { + protected ReplaceExpressionIterator(List children, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { + super(children, executionMode, iteratorMetadata); + } + + @Override + protected JavaRDD getRDDAux(DynamicContext context) { + return null; + } + + @Override + protected void openLocal() { + + } + + @Override + protected void closeLocal() { + + } + + @Override + protected void resetLocal() { + + } + + @Override + protected boolean hasNextLocal() { + return false; + } + + @Override + protected Item nextLocal() { + return null; + } +} diff --git a/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java new file mode 100644 index 0000000000..78660bf40b --- /dev/null +++ b/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java @@ -0,0 +1,67 @@ +package org.rumbledb.runtime.update.expression; + +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.expressions.ExecutionMode; +import org.rumbledb.runtime.HybridRuntimeIterator; +import org.rumbledb.runtime.RuntimeIterator; +import org.rumbledb.runtime.update.PendingUpdateList; + +import java.util.List; + +public class TransformExpressionIterator extends HybridRuntimeIterator { + + private List copyDeclIterators; + private RuntimeIterator modifyIterator; + private RuntimeIterator returnIterator; + + public TransformExpressionIterator(List copyDeclIterators, RuntimeIterator modifyIterator, RuntimeIterator returnIterator, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { + super(null, executionMode, iteratorMetadata); + this.children.addAll(copyDeclIterators); + this.children.add(modifyIterator); + this.children.add(returnIterator); + + this.copyDeclIterators = copyDeclIterators; + this.modifyIterator = modifyIterator; + this.returnIterator = returnIterator; + this.isUpdating = true; + } + + @Override + protected JavaRDD getRDDAux(DynamicContext context) { + return returnIterator.getRDD(context); + } + + @Override + protected void openLocal() { + returnIterator.open(this.currentDynamicContextForLocalExecution); + } + + @Override + protected void closeLocal() { + returnIterator.close(); + } + + @Override + protected void resetLocal() { + returnIterator.reset(this.currentDynamicContextForLocalExecution); + } + + @Override + protected boolean hasNextLocal() { + return returnIterator.hasNext(); + } + + @Override + protected Item nextLocal() { + return returnIterator.next(); + } + + @Override + public PendingUpdateList getPendingUpdateList(DynamicContext context) { + return modifyIterator.getPendingUpdateList(context); + } + +} From 5e91d67fe7fd6e9ef0cc10681b816403b1ccde2f Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 1 May 2023 18:14:57 +0200 Subject: [PATCH 052/119] Add updating and puls to iterator hierarchy --- src/main/java/org/rumbledb/api/Rumble.java | 17 +++++ .../compiler/RuntimeIteratorVisitor.java | 68 +++++++++++++++++++ .../org/rumbledb/runtime/RuntimeIterator.java | 11 +-- 3 files changed, 91 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/rumbledb/api/Rumble.java b/src/main/java/org/rumbledb/api/Rumble.java index f85d5d65a9..078eace48c 100644 --- a/src/main/java/org/rumbledb/api/Rumble.java +++ b/src/main/java/org/rumbledb/api/Rumble.java @@ -8,6 +8,7 @@ import org.rumbledb.context.DynamicContext; import org.rumbledb.expressions.module.MainModule; import org.rumbledb.runtime.RuntimeIterator; +import org.rumbledb.runtime.update.PendingUpdateList; import sparksoniq.spark.SparkSessionManager; /** @@ -50,6 +51,14 @@ public SequenceOfItems runQuery(String query) { mainModule, this.configuration ); + + if (iterator.isUpdating()) { + PendingUpdateList pul = iterator.getPendingUpdateList(dynamicContext); + pul.applyUpdates(); + } + + System.err.println("final iterator is: " + iterator.isUpdating()); + return new SequenceOfItems(iterator, dynamicContext, this.configuration); } @@ -70,6 +79,14 @@ public SequenceOfItems runQuery(URI location) throws IOException { mainModule, this.configuration ); + + if (iterator.isUpdating()) { + PendingUpdateList pul = iterator.getPendingUpdateList(dynamicContext); + pul.applyUpdates(); + } + + System.err.println("final iterator is: " + iterator.isUpdating()); + return new SequenceOfItems(iterator, dynamicContext, this.configuration); } diff --git a/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java b/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java index b555572329..6528d332f2 100644 --- a/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java +++ b/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java @@ -66,6 +66,7 @@ import org.rumbledb.expressions.typing.InstanceOfExpression; import org.rumbledb.expressions.typing.TreatExpression; import org.rumbledb.expressions.typing.ValidateTypeExpression; +import org.rumbledb.expressions.update.*; import org.rumbledb.items.ItemFactory; import org.rumbledb.expressions.postfix.ArrayLookupExpression; import org.rumbledb.expressions.postfix.ArrayUnboxingExpression; @@ -138,6 +139,9 @@ import org.rumbledb.runtime.primary.ObjectConstructorRuntimeIterator; import org.rumbledb.runtime.primary.StringRuntimeIterator; import org.rumbledb.runtime.primary.VariableReferenceIterator; +import org.rumbledb.runtime.update.PendingUpdateList; +import org.rumbledb.runtime.update.expression.DeleteExpressionIterator; +import org.rumbledb.runtime.update.expression.TransformExpressionIterator; import org.rumbledb.types.BuiltinTypesCatalogue; import org.rumbledb.types.SequenceType; @@ -337,6 +341,70 @@ public RuntimeIterator visitVariableReference(VariableReferenceExpression expres } // endregion + // region updating + + @Override + public RuntimeIterator visitDeleteExpression(DeleteExpression expression, RuntimeIterator argument) { + + RuntimeIterator mainIterator = this.visit(expression.getMainExpression(), argument); + RuntimeIterator lookupIterator = this.visit(expression.getLocatorExpression(), argument); + + RuntimeIterator runtimeIterator = new DeleteExpressionIterator( + mainIterator, + lookupIterator, + expression.getHighestExecutionMode(this.visitorConfig), + expression.getMetadata() + ); + runtimeIterator.setStaticContext(expression.getStaticContext()); + + return runtimeIterator; + } + + @Override + public RuntimeIterator visitRenameExpression(RenameExpression expression, RuntimeIterator argument) { + return super.visitRenameExpression(expression, argument); + } + + @Override + public RuntimeIterator visitReplaceExpression(ReplaceExpression expression, RuntimeIterator argument) { + return super.visitReplaceExpression(expression, argument); + } + + @Override + public RuntimeIterator visitInsertExpression(InsertExpression expression, RuntimeIterator argument) { + return super.visitInsertExpression(expression, argument); + } + + @Override + public RuntimeIterator visitAppendExpression(AppendExpression expression, RuntimeIterator argument) { + return super.visitAppendExpression(expression, argument); + } + + @Override + public RuntimeIterator visitTransformExpression(TransformExpression expression, RuntimeIterator argument) { + + List copyDeclIterators = new ArrayList<>(); + for (Expression childExpr : expression.getCopySourceExpressions()) { + copyDeclIterators.add(this.visit(childExpr, argument)); + } + RuntimeIterator modifyIterator = this.visit(expression.getModifyExpression(), argument); + RuntimeIterator returnIterator = this.visit(expression.getReturnExpression(), argument); + + RuntimeIterator runtimeIterator = new TransformExpressionIterator( + copyDeclIterators, + modifyIterator, + returnIterator, + expression.getHighestExecutionMode(this.visitorConfig), + expression.getMetadata() + ); + runtimeIterator.setStaticContext(expression.getStaticContext()); + + return runtimeIterator; + } + + + // endregion + // region primary @Override public RuntimeIterator visitFilterExpression(FilterExpression expression, RuntimeIterator argument) { diff --git a/src/main/java/org/rumbledb/runtime/RuntimeIterator.java b/src/main/java/org/rumbledb/runtime/RuntimeIterator.java index 1fd9830a63..abae85ef17 100644 --- a/src/main/java/org/rumbledb/runtime/RuntimeIterator.java +++ b/src/main/java/org/rumbledb/runtime/RuntimeIterator.java @@ -64,6 +64,7 @@ public abstract class RuntimeIterator implements RuntimeIteratorInterface, KryoS private static final long serialVersionUID = 1L; protected transient boolean hasNext; protected transient boolean isOpen; + protected transient boolean isUpdating; protected List children; protected transient DynamicContext currentDynamicContextForLocalExecution; private ExceptionMetadata metadata; @@ -75,6 +76,7 @@ public abstract class RuntimeIterator implements RuntimeIteratorInterface, KryoS protected RuntimeIterator(List children, ExecutionMode executionMode, ExceptionMetadata metadata) { this.metadata = metadata; this.isOpen = false; + this.isUpdating = false; this.highestExecutionMode = executionMode; this.children = new ArrayList<>(); if (children != null && !children.isEmpty()) { @@ -275,13 +277,10 @@ public JSoundDataFrame getDataFrame(DynamicContext context) { } public boolean isUpdating() { - throw new OurBadException( - "Updating classification is not implemented for the iterator " + getClass().getCanonicalName(), - getMetadata() - ); + return this.isUpdating; } - public PendingUpdateList getPendingUpdateList() { + public PendingUpdateList getPendingUpdateList(DynamicContext context) { throw new OurBadException( "Pending Update Lists are not implemented for the iterator " + getClass().getCanonicalName(), getMetadata() @@ -393,6 +392,8 @@ public void print(StringBuffer buffer, int indent) { buffer.append(" | "); buffer.append(this.highestExecutionMode); buffer.append(" | "); + buffer.append(this.isUpdating ? "updating" : "simple"); + buffer.append(" | "); buffer.append("Variable dependencies: "); Map dependencies = getVariableDependencies(); From ca883ffe9d6d2a81549703696c0fe4e6b83b5044 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 1 May 2023 18:15:19 +0200 Subject: [PATCH 053/119] Fix copy declaration variable typing --- .../compiler/DynamicContextVisitor.java | 18 ++++++++++++++++++ .../rumbledb/compiler/InferTypeVisitor.java | 3 ++- .../expressions/update/CopyDeclaration.java | 7 ++++++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/rumbledb/compiler/DynamicContextVisitor.java b/src/main/java/org/rumbledb/compiler/DynamicContextVisitor.java index 9ddc97b2a3..9464610d7e 100644 --- a/src/main/java/org/rumbledb/compiler/DynamicContextVisitor.java +++ b/src/main/java/org/rumbledb/compiler/DynamicContextVisitor.java @@ -47,6 +47,8 @@ import org.rumbledb.expressions.module.TypeDeclaration; import org.rumbledb.expressions.module.VariableDeclaration; import org.rumbledb.expressions.primary.InlineFunctionExpression; +import org.rumbledb.expressions.update.CopyDeclaration; +import org.rumbledb.expressions.update.TransformExpression; import org.rumbledb.items.ItemFactory; import org.rumbledb.items.parsing.ItemParser; import org.rumbledb.runtime.RuntimeIterator; @@ -113,6 +115,22 @@ public DynamicContext visitFunctionDeclaration(FunctionDeclaration declaration, return defaultAction(expression, argument); } + @Override + public DynamicContext visitTransformExpression(TransformExpression expression, DynamicContext argument) { + + for (CopyDeclaration copyDecl : expression.getCopyDeclarations()) { + Expression child = copyDecl.getSourceExpression(); + RuntimeIterator iterator = VisitorHelpers.generateRuntimeIterator(child, this.configuration); + iterator.bindToVariableInDynamicContext(argument, copyDecl.getVariableName(), argument); + } + + this.visit(expression.getModifyExpression(), argument); + + this.visit(expression.getReturnExpression(), argument); + + return argument; + } + @Override public DynamicContext visitVariableDeclaration(VariableDeclaration variableDeclaration, DynamicContext argument) { Name name = variableDeclaration.getVariableName(); diff --git a/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java b/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java index 3332eaa865..319260f84d 100644 --- a/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java +++ b/src/main/java/org/rumbledb/compiler/InferTypeVisitor.java @@ -701,7 +701,6 @@ public StaticContext visitAppendExpression(AppendExpression expression, StaticCo @Override public StaticContext visitTransformExpression(TransformExpression expression, StaticContext argument) { - visitDescendants(expression, argument); for (CopyDeclaration copyDecl : expression.getCopyDeclarations()) { visit(copyDecl.getSourceExpression(), argument); SequenceType declaredType = copyDecl.getSourceSequenceType(); @@ -2051,6 +2050,8 @@ public void checkAndUpdateVariableStaticType( } } + + @Override public StaticContext visitVariableDeclaration(VariableDeclaration expression, StaticContext argument) { visitDescendants(expression, argument); diff --git a/src/main/java/org/rumbledb/expressions/update/CopyDeclaration.java b/src/main/java/org/rumbledb/expressions/update/CopyDeclaration.java index fe9d215dcb..f443f4ec8d 100644 --- a/src/main/java/org/rumbledb/expressions/update/CopyDeclaration.java +++ b/src/main/java/org/rumbledb/expressions/update/CopyDeclaration.java @@ -29,7 +29,12 @@ public Expression getSourceExpression() { } public SequenceType getSourceSequenceType() { - return sourceExpression.getStaticSequenceType(); + if (this.sourceExpression != null && this.sourceExpression.getStaticSequenceType() != null) { + return this.sourceExpression.getStaticSequenceType(); + } + return SequenceType.ITEM_STAR; } + + } From dc1f0ce2b9febd27efade5ea26176264ca806554 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 1 May 2023 18:15:36 +0200 Subject: [PATCH 054/119] Fix indexing from 1 error in update prims --- .../runtime/update/primitives/DeleteFromArrayPrimitive.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java index 1978323886..7f1c334ddc 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java @@ -22,7 +22,7 @@ public DeleteFromArrayPrimitive(Item targetArray, Item positionInt) { @Override public void apply() { - this.target.removeItemAt(this.selector.getIntValue()); + this.target.removeItemAt(this.selector.getIntValue() - 1); } @Override From 2d162fd122c3d2c4c7016f338bc0a6bd32a394d8 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 1 May 2023 18:15:58 +0200 Subject: [PATCH 055/119] Create test for transform expression --- .../resources/test_files/runtime/Updating/SimpleTransform1.jq | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleTransform1.jq diff --git a/src/test/resources/test_files/runtime/Updating/SimpleTransform1.jq b/src/test/resources/test_files/runtime/Updating/SimpleTransform1.jq new file mode 100644 index 0000000000..e82633398d --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleTransform1.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="[ 2, 3, 4 ]" :) +copy json $je := [1 to 4] +modify delete json $je[[1]] +return $je From a1668e9c054f3f97b49821f40119d7f2ca3f1508 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 1 May 2023 19:08:20 +0200 Subject: [PATCH 056/119] Implement classes and visits for Append, Insert, Rename, and Replace iterators --- .../compiler/RuntimeIteratorVisitor.java | 65 +++++++++++++++-- .../expression/AppendExpressionIterator.java | 53 +++++++++++++- .../expression/DeleteExpressionIterator.java | 51 ++++++++------ .../expression/InsertExpressionIterator.java | 70 ++++++++++++++++++- .../expression/RenameExpressionIterator.java | 56 ++++++++++++++- .../expression/ReplaceExpressionIterator.java | 56 ++++++++++++++- 6 files changed, 314 insertions(+), 37 deletions(-) diff --git a/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java b/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java index 6528d332f2..7173adf7f1 100644 --- a/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java +++ b/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java @@ -140,8 +140,7 @@ import org.rumbledb.runtime.primary.StringRuntimeIterator; import org.rumbledb.runtime.primary.VariableReferenceIterator; import org.rumbledb.runtime.update.PendingUpdateList; -import org.rumbledb.runtime.update.expression.DeleteExpressionIterator; -import org.rumbledb.runtime.update.expression.TransformExpressionIterator; +import org.rumbledb.runtime.update.expression.*; import org.rumbledb.types.BuiltinTypesCatalogue; import org.rumbledb.types.SequenceType; @@ -362,22 +361,76 @@ public RuntimeIterator visitDeleteExpression(DeleteExpression expression, Runtim @Override public RuntimeIterator visitRenameExpression(RenameExpression expression, RuntimeIterator argument) { - return super.visitRenameExpression(expression, argument); + + RuntimeIterator mainIterator = this.visit(expression.getMainExpression(), argument); + RuntimeIterator lookupIterator = this.visit(expression.getLocatorExpression(), argument); + RuntimeIterator nameIterator = this.visit(expression.getNameExpression(), argument); + + RuntimeIterator runtimeIterator = new RenameExpressionIterator( + mainIterator, + lookupIterator, + nameIterator, + expression.getHighestExecutionMode(this.visitorConfig), + expression.getMetadata() + ); + runtimeIterator.setStaticContext(expression.getStaticContext()); + + return runtimeIterator; } @Override public RuntimeIterator visitReplaceExpression(ReplaceExpression expression, RuntimeIterator argument) { - return super.visitReplaceExpression(expression, argument); + + RuntimeIterator mainIterator = this.visit(expression.getMainExpression(), argument); + RuntimeIterator lookupIterator = this.visit(expression.getLocatorExpression(), argument); + RuntimeIterator replacerIterator = this.visit(expression.getReplacerExpression(), argument); + + RuntimeIterator runtimeIterator = new ReplaceExpressionIterator( + mainIterator, + lookupIterator, + replacerIterator, + expression.getHighestExecutionMode(this.visitorConfig), + expression.getMetadata() + ); + runtimeIterator.setStaticContext(expression.getStaticContext()); + + return runtimeIterator; } @Override public RuntimeIterator visitInsertExpression(InsertExpression expression, RuntimeIterator argument) { - return super.visitInsertExpression(expression, argument); + + RuntimeIterator mainIterator = this.visit(expression.getMainExpression(), argument); + RuntimeIterator toInsertIterator = this.visit(expression.getToInsertExpression(), argument); + RuntimeIterator positionIterator = expression.hasPositionExpression() ? this.visit(expression.getPositionExpression(), argument) : null; + + RuntimeIterator runtimeIterator = new InsertExpressionIterator( + mainIterator, + toInsertIterator, + positionIterator, + expression.getHighestExecutionMode(this.visitorConfig), + expression.getMetadata() + ); + runtimeIterator.setStaticContext(expression.getStaticContext()); + + return runtimeIterator; } @Override public RuntimeIterator visitAppendExpression(AppendExpression expression, RuntimeIterator argument) { - return super.visitAppendExpression(expression, argument); + + RuntimeIterator arrayIterator = this.visit(expression.getArrayExpression(), argument); + RuntimeIterator toAppendIterator = this.visit(expression.getToAppendExpression(), argument); + + RuntimeIterator runtimeIterator = new AppendExpressionIterator( + arrayIterator, + toAppendIterator, + expression.getHighestExecutionMode(this.visitorConfig), + expression.getMetadata() + ); + runtimeIterator.setStaticContext(expression.getStaticContext()); + + return runtimeIterator; } @Override diff --git a/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java index e06b27cd3b..427e8f2d9a 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java @@ -4,15 +4,34 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.exceptions.MoreThanOneItemException; +import org.rumbledb.exceptions.NoItemException; +import org.rumbledb.exceptions.OurBadException; import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.HybridRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; +import org.rumbledb.runtime.update.PendingUpdateList; +import org.rumbledb.runtime.update.primitives.UpdatePrimitive; +import org.rumbledb.runtime.update.primitives.UpdatePrimitiveFactory; +import java.util.Arrays; +import java.util.Collections; import java.util.List; public class AppendExpressionIterator extends HybridRuntimeIterator { - protected AppendExpressionIterator(List children, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { - super(children, executionMode, iteratorMetadata); + + private RuntimeIterator arrayIterator; + private RuntimeIterator toAppendIterator; + private PendingUpdateList pul; + + public AppendExpressionIterator(RuntimeIterator arrayIterator, RuntimeIterator toAppendIterator, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { + super(Arrays.asList(arrayIterator, toAppendIterator), executionMode, iteratorMetadata); + + this.arrayIterator = arrayIterator; + this.toAppendIterator = toAppendIterator; + this.pul = null; + this.isUpdating = true; } @Override @@ -44,4 +63,34 @@ protected boolean hasNextLocal() { protected Item nextLocal() { return null; } + + @Override + public PendingUpdateList getPendingUpdateList(DynamicContext context) { + if (this.pul == null) { + PendingUpdateList pul = new PendingUpdateList(); + Item target; + Item content; + + try { + target = this.arrayIterator.materializeExactlyOneItem(context); + content = this.toAppendIterator.materializeExactlyOneItem(context); + } catch (NoItemException | MoreThanOneItemException e) { + throw new RuntimeException(e); + } + + UpdatePrimitiveFactory factory = UpdatePrimitiveFactory.getInstance(); + UpdatePrimitive up; + if (target.isArray()) { + Item locator = ItemFactory.getInstance().createIntItem(target.getSize()); + up = factory.createInsertIntoArrayPrimitive(target, locator, Collections.singletonList(content)); + } else { + throw new OurBadException("Append iterator cannot handle target items that are not arrays"); + } + + pul.addUpdatePrimitive(up); + this.pul = pul; + } + + return this.pul; + } } diff --git a/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java index 1967526f67..b606cc22da 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java @@ -21,11 +21,13 @@ public class DeleteExpressionIterator extends HybridRuntimeIterator { private RuntimeIterator mainIterator; private RuntimeIterator lookupIterator; + private PendingUpdateList pul; public DeleteExpressionIterator(RuntimeIterator mainIterator, RuntimeIterator lookupIterator, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { super(Arrays.asList(mainIterator, lookupIterator), executionMode, iteratorMetadata); this.mainIterator = mainIterator; this.lookupIterator = lookupIterator; + this.pul = null; this.isUpdating = true; } @@ -60,30 +62,33 @@ protected Item nextLocal() { } @Override - public PendingUpdateList getPendingUpdateList(DynamicContext dynamicContext) { - PendingUpdateList pul = new PendingUpdateList(); - Item main; - Item lookup; - - try { - main = this.mainIterator.materializeExactlyOneItem(dynamicContext); - lookup = this.lookupIterator.materializeExactlyOneItem(dynamicContext); - } catch (NoItemException | MoreThanOneItemException e) { - throw new RuntimeException(e); + public PendingUpdateList getPendingUpdateList(DynamicContext context) { + if (this.pul == null) { + PendingUpdateList pul = new PendingUpdateList(); + Item main; + Item lookup; + + try { + main = this.mainIterator.materializeExactlyOneItem(context); + lookup = this.lookupIterator.materializeExactlyOneItem(context); + } catch (NoItemException | MoreThanOneItemException e) { + throw new RuntimeException(e); + } + + UpdatePrimitiveFactory factory = UpdatePrimitiveFactory.getInstance(); + UpdatePrimitive up; + if (main.isObject()) { + up = factory.createDeleteFromObjectPrimitive(main, Collections.singletonList(lookup)); + } else if (main.isArray()) { + up = factory.createDeleteFromArrayPrimitive(main, lookup); + } else { + throw new OurBadException("Delete iterator cannot handle main items that are not objects or arrays"); + } + + pul.addUpdatePrimitive(up); + this.pul = pul; } - UpdatePrimitiveFactory factory = UpdatePrimitiveFactory.getInstance(); - UpdatePrimitive up; - if (main.isObject()) { - up = factory.createDeleteFromObjectPrimitive(main, Collections.singletonList(lookup)); - } else if (main.isArray()) { - up = factory.createDeleteFromArrayPrimitive(main, lookup); - } else { - throw new OurBadException("Delete iterator cannot handle main items that are not objects or arrays"); - } - - pul.addUpdatePrimitive(up); - - return pul; + return this.pul; } } diff --git a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java index 79f24a84ee..c88bd14168 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java @@ -4,15 +4,46 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.exceptions.MoreThanOneItemException; +import org.rumbledb.exceptions.NoItemException; +import org.rumbledb.exceptions.OurBadException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.runtime.HybridRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; +import org.rumbledb.runtime.update.PendingUpdateList; +import org.rumbledb.runtime.update.primitives.UpdatePrimitive; +import org.rumbledb.runtime.update.primitives.UpdatePrimitiveFactory; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.List; public class InsertExpressionIterator extends HybridRuntimeIterator { - protected InsertExpressionIterator(List children, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { - super(children, executionMode, iteratorMetadata); + + private RuntimeIterator mainIterator; + private RuntimeIterator toInsertIterator; + private RuntimeIterator positionIterator; + private PendingUpdateList pul; + + public InsertExpressionIterator(RuntimeIterator mainIterator, RuntimeIterator toInsertIterator, RuntimeIterator positionIterator, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { + super( + positionIterator == null + ? Arrays.asList(mainIterator, toInsertIterator) + : Arrays.asList(mainIterator, toInsertIterator, positionIterator), + executionMode, + iteratorMetadata + ); + + this.mainIterator = mainIterator; + this.toInsertIterator = toInsertIterator; + this.positionIterator = positionIterator; + this.pul = null; + this.isUpdating = true; + } + + public boolean hasPositionIterator() { + return positionIterator != null; } @Override @@ -44,4 +75,39 @@ protected boolean hasNextLocal() { protected Item nextLocal() { return null; } + + @Override + public PendingUpdateList getPendingUpdateList(DynamicContext context) { + if (this.pul == null) { + PendingUpdateList pul = new PendingUpdateList(); + Item main; + Item content; + Item locator = null; + + try { + main = this.mainIterator.materializeExactlyOneItem(context); + content = this.toInsertIterator.materializeExactlyOneItem(context); + if (this.hasPositionIterator()) { + locator = this.positionIterator.materializeExactlyOneItem(context); + } + } catch (NoItemException | MoreThanOneItemException e) { + throw new RuntimeException(e); + } + + UpdatePrimitiveFactory factory = UpdatePrimitiveFactory.getInstance(); + UpdatePrimitive up; + if (main.isObject()) { + up = factory.createInsertIntoObjectPrimitive(main, content); + } else if (main.isArray()) { + up = factory.createInsertIntoArrayPrimitive(main, locator, Collections.singletonList(content)); + } else { + throw new OurBadException("Insert iterator cannot handle main items that are not objects or arrays"); + } + + pul.addUpdatePrimitive(up); + this.pul = pul; + } + + return this.pul; + } } diff --git a/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java index 32712a3f92..9b76355bb5 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java @@ -4,15 +4,36 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.exceptions.MoreThanOneItemException; +import org.rumbledb.exceptions.NoItemException; +import org.rumbledb.exceptions.OurBadException; import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.HybridRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; +import org.rumbledb.runtime.update.PendingUpdateList; +import org.rumbledb.runtime.update.primitives.UpdatePrimitive; +import org.rumbledb.runtime.update.primitives.UpdatePrimitiveFactory; +import java.util.Arrays; +import java.util.Collections; import java.util.List; public class RenameExpressionIterator extends HybridRuntimeIterator { - protected RenameExpressionIterator(List children, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { - super(children, executionMode, iteratorMetadata); + + private RuntimeIterator mainIterator; + private RuntimeIterator locatorIterator; + private RuntimeIterator nameIterator; + private PendingUpdateList pul; + + public RenameExpressionIterator(RuntimeIterator mainIterator, RuntimeIterator locatorIterator, RuntimeIterator nameIterator, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { + super(Arrays.asList(mainIterator, locatorIterator, nameIterator), executionMode, iteratorMetadata); + + this.mainIterator = mainIterator; + this.locatorIterator = locatorIterator; + this.nameIterator = nameIterator; + this.pul = null; + this.isUpdating = true; } @Override @@ -44,4 +65,35 @@ protected boolean hasNextLocal() { protected Item nextLocal() { return null; } + + @Override + public PendingUpdateList getPendingUpdateList(DynamicContext context) { + if (this.pul == null) { + PendingUpdateList pul = new PendingUpdateList(); + Item target; + Item locator; + Item content; + + try { + target = this.mainIterator.materializeExactlyOneItem(context); + locator = this.locatorIterator.materializeExactlyOneItem(context); + content = this.nameIterator.materializeExactlyOneItem(context); + } catch (NoItemException | MoreThanOneItemException e) { + throw new RuntimeException(e); + } + + UpdatePrimitiveFactory factory = UpdatePrimitiveFactory.getInstance(); + UpdatePrimitive up; + if (target.isObject()) { + up = factory.createRenameInObjectPrimitive(target, locator, content); + } else { + throw new OurBadException("Rename iterator cannot handle target items that are not objects"); + } + + pul.addUpdatePrimitive(up); + this.pul = pul; + } + + return this.pul; + } } diff --git a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java index 36ac41d1e2..d8ac370fb6 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java @@ -4,15 +4,34 @@ import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.ExceptionMetadata; +import org.rumbledb.exceptions.MoreThanOneItemException; +import org.rumbledb.exceptions.NoItemException; +import org.rumbledb.exceptions.OurBadException; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.runtime.HybridRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; +import org.rumbledb.runtime.update.PendingUpdateList; +import org.rumbledb.runtime.update.primitives.UpdatePrimitive; +import org.rumbledb.runtime.update.primitives.UpdatePrimitiveFactory; +import java.util.Arrays; import java.util.List; public class ReplaceExpressionIterator extends HybridRuntimeIterator { - protected ReplaceExpressionIterator(List children, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { - super(children, executionMode, iteratorMetadata); + + private RuntimeIterator mainIterator; + private RuntimeIterator locatorIterator; + private RuntimeIterator replacerIterator; + private PendingUpdateList pul; + + public ReplaceExpressionIterator(RuntimeIterator mainIterator, RuntimeIterator locatorIterator, RuntimeIterator replacerIterator, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { + super(Arrays.asList(mainIterator, locatorIterator, replacerIterator), executionMode, iteratorMetadata); + + this.mainIterator = mainIterator; + this.locatorIterator = locatorIterator; + this.replacerIterator = replacerIterator; + this.pul = null; + this.isUpdating = true; } @Override @@ -44,4 +63,37 @@ protected boolean hasNextLocal() { protected Item nextLocal() { return null; } + + @Override + public PendingUpdateList getPendingUpdateList(DynamicContext context) { + if (this.pul == null) { + PendingUpdateList pul = new PendingUpdateList(); + Item target; + Item locator; + Item content; + + try { + target = this.mainIterator.materializeExactlyOneItem(context); + locator = this.locatorIterator.materializeExactlyOneItem(context); + content = this.replacerIterator.materializeExactlyOneItem(context); + } catch (NoItemException | MoreThanOneItemException e) { + throw new RuntimeException(e); + } + + UpdatePrimitiveFactory factory = UpdatePrimitiveFactory.getInstance(); + UpdatePrimitive up; + if (target.isObject()) { + up = factory.createReplaceInObjectPrimitive(target, locator, content); + } else if (target.isArray()) { + up = factory.createReplaceInArrayPrimitive(target, locator, content); + } else { + throw new OurBadException("Replace iterator cannot handle target items that are not objects or arrays"); + } + + pul.addUpdatePrimitive(up); + this.pul = pul; + } + + return this.pul; + } } From d6e39a1b66f2518aa044b2d49d31a19d69cef041 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Fri, 5 May 2023 20:13:41 +0200 Subject: [PATCH 057/119] Implement a test for each update primitive --- .../runtime/update/expression/AppendExpressionIterator.java | 2 +- .../runtime/update/primitives/InsertIntoArrayPrimitive.java | 2 +- .../runtime/update/primitives/InsertIntoObjectPrimitive.java | 2 +- .../resources/test_files/runtime/Updating/SimpleAppend1.jq | 4 ++++ .../test_files/runtime/Updating/SimpleDeleteFromArray1.jq | 4 ++++ .../test_files/runtime/Updating/SimpleDeleteFromObject1.jq | 4 ++++ .../test_files/runtime/Updating/SimpleInsertIntoArray1.jq | 4 ++++ .../test_files/runtime/Updating/SimpleInsertIntoObject1.jq | 4 ++++ .../test_files/runtime/Updating/SimpleRenameInObject1.jq | 4 ++++ .../test_files/runtime/Updating/SimpleReplaceInArray1.jq | 4 ++++ .../test_files/runtime/Updating/SimpleReplaceInObject1.jq | 4 ++++ 11 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleAppend1.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleDeleteFromArray1.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleDeleteFromObject1.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleInsertIntoArray1.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleInsertIntoObject1.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleRenameInObject1.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleReplaceInArray1.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleReplaceInObject1.jq diff --git a/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java index 427e8f2d9a..51d1e4167b 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java @@ -81,7 +81,7 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { UpdatePrimitiveFactory factory = UpdatePrimitiveFactory.getInstance(); UpdatePrimitive up; if (target.isArray()) { - Item locator = ItemFactory.getInstance().createIntItem(target.getSize()); + Item locator = ItemFactory.getInstance().createIntItem(target.getSize() + 1); up = factory.createInsertIntoArrayPrimitive(target, locator, Collections.singletonList(content)); } else { throw new OurBadException("Append iterator cannot handle target items that are not arrays"); diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java index 4497415105..b2a1dc4b1b 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java @@ -28,7 +28,7 @@ public InsertIntoArrayPrimitive(Item targetArray, Item positionInt, List s @Override public void apply() { - this.target.putItemsAt(this.content, this.selector.getIntValue()); + this.target.putItemsAt(this.content, this.selector.getIntValue() - 1); } @Override diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java index a341b817f4..68564f4cd4 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java @@ -25,7 +25,7 @@ public InsertIntoObjectPrimitive(Item targetObject, Item contentObject) { public void apply() { try { for (String key : this.content.getKeys()) { - this.target.putItemByKey(key, this.target.getItemByKey(key)); + this.target.putItemByKey(key, this.content.getItemByKey(key)); } } catch (DuplicateObjectKeyException e) { throw new DuplicateKeyOnUpdateApplyException(e.getMessage(), ExceptionMetadata.EMPTY_METADATA); diff --git a/src/test/resources/test_files/runtime/Updating/SimpleAppend1.jq b/src/test/resources/test_files/runtime/Updating/SimpleAppend1.jq new file mode 100644 index 0000000000..e2c07d7077 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleAppend1.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="[ 1, 2, 3, 4, 5 ]" :) +copy json $je := [1 to 4] +modify append json 5 into $je +return $je diff --git a/src/test/resources/test_files/runtime/Updating/SimpleDeleteFromArray1.jq b/src/test/resources/test_files/runtime/Updating/SimpleDeleteFromArray1.jq new file mode 100644 index 0000000000..748785a1f4 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleDeleteFromArray1.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="[ 1, 3, 4 ]" :) +copy json $je := [1 to 4] +modify delete json $je[[2]] +return $je diff --git a/src/test/resources/test_files/runtime/Updating/SimpleDeleteFromObject1.jq b/src/test/resources/test_files/runtime/Updating/SimpleDeleteFromObject1.jq new file mode 100644 index 0000000000..91243b4932 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleDeleteFromObject1.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="{ "foo" : "bar" }" :) +copy json $je := {"foo": "bar", "foobar": "barfoo"} +modify delete json $je.foobar +return $je \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleInsertIntoArray1.jq b/src/test/resources/test_files/runtime/Updating/SimpleInsertIntoArray1.jq new file mode 100644 index 0000000000..1c8eb908c3 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleInsertIntoArray1.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="[ 1, 2, 3, 5, 4 ]" :) +copy json $je := [1 to 4] +modify insert json 5 into $je at position 4 +return $je diff --git a/src/test/resources/test_files/runtime/Updating/SimpleInsertIntoObject1.jq b/src/test/resources/test_files/runtime/Updating/SimpleInsertIntoObject1.jq new file mode 100644 index 0000000000..b8536e388c --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleInsertIntoObject1.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="{ "foo" : "bar", "foobar" : "barfoo" }" :) +copy json $je := {"foo": "bar"} +modify insert json "foobar": "barfoo" into $je +return $je diff --git a/src/test/resources/test_files/runtime/Updating/SimpleRenameInObject1.jq b/src/test/resources/test_files/runtime/Updating/SimpleRenameInObject1.jq new file mode 100644 index 0000000000..5222c3a27b --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleRenameInObject1.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="{ "foobar" : "barfoo", "bar" : "bar" }" :) +copy json $je := {"foo": "bar", "foobar": "barfoo"} +modify rename json $je.foo as "bar" +return $je \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleReplaceInArray1.jq b/src/test/resources/test_files/runtime/Updating/SimpleReplaceInArray1.jq new file mode 100644 index 0000000000..d399d69b99 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleReplaceInArray1.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="[ 1, 2, 5, 4 ]" :) +copy json $je := [1 to 4] +modify replace json value of $je[[3]] with 5 +return $je \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleReplaceInObject1.jq b/src/test/resources/test_files/runtime/Updating/SimpleReplaceInObject1.jq new file mode 100644 index 0000000000..c21ff418a8 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleReplaceInObject1.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="{ "foobar" : "barfoo", "foo" : "foo" }" :) +copy json $je := {"foo": "bar", "foobar": "barfoo"} +modify replace json value of $je.foo with "foo" +return $je \ No newline at end of file From 492ba6e1a7467c53ada03487f786bdd8f474d727 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Fri, 5 May 2023 20:18:05 +0200 Subject: [PATCH 058/119] Remove locatorKind class --- .../rumbledb/compiler/TranslationVisitor.java | 19 +------------------ .../expressions/update/DeleteExpression.java | 10 ---------- .../expressions/update/RenameExpression.java | 13 ------------- .../expressions/update/ReplaceExpression.java | 10 ---------- 4 files changed, 1 insertion(+), 51 deletions(-) diff --git a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java index 6b3cb1a64b..2a9a6136be 100644 --- a/src/main/java/org/rumbledb/compiler/TranslationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/TranslationVisitor.java @@ -1173,21 +1173,18 @@ public Node visitInsertExpr(JsoniqParser.InsertExprContext ctx) { public Node visitDeleteExpr(JsoniqParser.DeleteExprContext ctx) { Expression mainExpression = getMainExpressionFromUpdateLocatorContext(ctx.updateLocator()); Expression locatorExpression = getLocatorExpressionFromUpdateLocatorContext(ctx.updateLocator()); - UpdateLocatorKind locatorKind = getLocatorKindFromUpdateLocatorContext(ctx.updateLocator()); - return new DeleteExpression(mainExpression, locatorExpression, locatorKind, createMetadataFromContext(ctx)); + return new DeleteExpression(mainExpression, locatorExpression, createMetadataFromContext(ctx)); } @Override public Node visitRenameExpr(JsoniqParser.RenameExprContext ctx) { Expression mainExpression = getMainExpressionFromUpdateLocatorContext(ctx.updateLocator()); Expression locatorExpression = getLocatorExpressionFromUpdateLocatorContext(ctx.updateLocator()); - UpdateLocatorKind locatorKind = getLocatorKindFromUpdateLocatorContext(ctx.updateLocator()); Expression nameExpression = (Expression) this.visitExprSingle(ctx.name_expr); return new RenameExpression( mainExpression, locatorExpression, nameExpression, - locatorKind, createMetadataFromContext(ctx) ); } @@ -1196,13 +1193,11 @@ public Node visitRenameExpr(JsoniqParser.RenameExprContext ctx) { public Node visitReplaceExpr(JsoniqParser.ReplaceExprContext ctx) { Expression mainExpression = getMainExpressionFromUpdateLocatorContext(ctx.updateLocator()); Expression locatorExpression = getLocatorExpressionFromUpdateLocatorContext(ctx.updateLocator()); - UpdateLocatorKind locatorKind = getLocatorKindFromUpdateLocatorContext(ctx.updateLocator()); Expression newExpression = (Expression) this.visitExprSingle(ctx.replacer_expr); return new ReplaceExpression( mainExpression, locatorExpression, newExpression, - locatorKind, createMetadataFromContext(ctx) ); } @@ -1253,18 +1248,6 @@ public Expression getMainExpressionFromUpdateLocatorContext(JsoniqParser.UpdateL return mainExpression; } - public UpdateLocatorKind getLocatorKindFromUpdateLocatorContext(JsoniqParser.UpdateLocatorContext ctx) { - ParseTree locatorExprCtx = ctx.getChild(ctx.getChildCount() - 1); - if (locatorExprCtx instanceof JsoniqParser.ObjectLookupContext) { - return UpdateLocatorKind.OBJECT_LOOKUP; - } - if (locatorExprCtx instanceof JsoniqParser.ArrayLookupContext) { - return UpdateLocatorKind.ARRAY_LOOKUP; - } else { - throw new OurBadException("Unrecognized locator found in update expression."); - } - } - public Expression getLocatorExpressionFromUpdateLocatorContext(JsoniqParser.UpdateLocatorContext ctx) { ParseTree locatorExprCtx = ctx.getChild(ctx.getChildCount() - 1); if (locatorExprCtx instanceof JsoniqParser.ObjectLookupContext) { diff --git a/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java b/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java index 40363f44af..2882473bb4 100644 --- a/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java @@ -13,12 +13,9 @@ public class DeleteExpression extends Expression { private Expression mainExpression; private Expression locatorExpression; - private UpdateLocatorKind locatorKind; - public DeleteExpression( Expression mainExpression, Expression locatorExpression, - UpdateLocatorKind locatorKind, ExceptionMetadata metadata ) { super(metadata); @@ -28,12 +25,8 @@ public DeleteExpression( if (locatorExpression == null) { throw new OurBadException("Locator expression cannot be null in a delete expression."); } - if (locatorKind == null) { - throw new OurBadException("Locator kind cannot be null in a delete expression."); - } this.mainExpression = mainExpression; this.locatorExpression = locatorExpression; - this.locatorKind = locatorKind; } @Override @@ -49,9 +42,6 @@ public Expression getLocatorExpression() { return locatorExpression; } - public UpdateLocatorKind getLocatorKind() { - return locatorKind; - } @Override public T accept(AbstractNodeVisitor visitor, T argument) { diff --git a/src/main/java/org/rumbledb/expressions/update/RenameExpression.java b/src/main/java/org/rumbledb/expressions/update/RenameExpression.java index 6d4a879e5d..e50fea257b 100644 --- a/src/main/java/org/rumbledb/expressions/update/RenameExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/RenameExpression.java @@ -14,13 +14,11 @@ public class RenameExpression extends Expression { private Expression mainExpression; private Expression locatorExpression; private Expression nameExpression; - private UpdateLocatorKind locatorKind; public RenameExpression( Expression mainExpression, Expression locatorExpression, Expression nameExpression, - UpdateLocatorKind locatorKind, ExceptionMetadata metadata ) { super(metadata); @@ -33,16 +31,9 @@ public RenameExpression( if (nameExpression == null) { throw new OurBadException("Name expression cannot be null in a rename expression."); } - if (locatorKind == null) { - throw new OurBadException("Locator kind cannot be null in a rename expression."); - } - if (!locatorKind.isObjectLookup()) { - throw new OurBadException("Locator kind must be Object Lookup"); - } this.mainExpression = mainExpression; this.locatorExpression = locatorExpression; this.nameExpression = nameExpression; - this.locatorKind = locatorKind; } @Override @@ -62,10 +53,6 @@ public Expression getNameExpression() { return nameExpression; } - public UpdateLocatorKind getLocatorKind() { - return locatorKind; - } - @Override public T accept(AbstractNodeVisitor visitor, T argument) { return visitor.visitRenameExpression(this, argument); diff --git a/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java b/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java index a685095e63..c914f249b4 100644 --- a/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/ReplaceExpression.java @@ -14,13 +14,11 @@ public class ReplaceExpression extends Expression { private Expression mainExpression; private Expression locatorExpression; private Expression replacerExpression; - private UpdateLocatorKind locatorKind; public ReplaceExpression( Expression mainExpression, Expression locatorExpression, Expression replacerExpression, - UpdateLocatorKind locatorKind, ExceptionMetadata metadata ) { super(metadata); @@ -33,13 +31,9 @@ public ReplaceExpression( if (replacerExpression == null) { throw new OurBadException("New replacer expression cannot be null in a replace expression."); } - if (locatorKind == null) { - throw new OurBadException("Locator kind cannot be null in a replace expression."); - } this.mainExpression = mainExpression; this.locatorExpression = locatorExpression; this.replacerExpression = replacerExpression; - this.locatorKind = locatorKind; } @Override @@ -59,10 +53,6 @@ public Expression getReplacerExpression() { return replacerExpression; } - public UpdateLocatorKind getLocatorKind() { - return locatorKind; - } - @Override public T accept(AbstractNodeVisitor visitor, T argument) { return visitor.visitReplaceExpression(this, argument); From 07a27d0874fcde4c0ae4dbc34a6e87da2f5fc8db Mon Sep 17 00:00:00 2001 From: dloughlin Date: Fri, 5 May 2023 20:18:14 +0200 Subject: [PATCH 059/119] Remove locatorKind class file --- .../expressions/update/UpdateLocatorKind.java | 24 ------------------- 1 file changed, 24 deletions(-) delete mode 100644 src/main/java/org/rumbledb/expressions/update/UpdateLocatorKind.java diff --git a/src/main/java/org/rumbledb/expressions/update/UpdateLocatorKind.java b/src/main/java/org/rumbledb/expressions/update/UpdateLocatorKind.java deleted file mode 100644 index c59b1a6e04..0000000000 --- a/src/main/java/org/rumbledb/expressions/update/UpdateLocatorKind.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.rumbledb.expressions.update; - -public enum UpdateLocatorKind { - OBJECT_LOOKUP, - ARRAY_LOOKUP; - - public boolean isObjectLookup() { - return this == UpdateLocatorKind.OBJECT_LOOKUP; - } - - public boolean isArrayLookup() { - return this == UpdateLocatorKind.ARRAY_LOOKUP; - } - - public String toString() { - switch (this) { - case OBJECT_LOOKUP: - return "object_lookup"; - case ARRAY_LOOKUP: - return "array_lookup"; - } - return null; - } -} From 4c1fb769ca4040e44ceef024a24c4bbc93e27bc1 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sat, 6 May 2023 15:49:00 +0200 Subject: [PATCH 060/119] Implement updating commaexpressions and tests --- .../compiler/RuntimeIteratorVisitor.java | 1 + .../runtime/CommaExpressionIterator.java | 25 ++++++++ .../runtime/update/PendingUpdateList.java | 57 ++++++++++++++++--- .../runtime/Updating/MultipleUpdatesArray1.jq | 4 ++ .../Updating/SimpleDeleteFromArray2.jq | 4 ++ .../Updating/SimpleInsertIntoArray2.jq | 4 ++ .../runtime/Updating/SimpleTransform2.jq | 4 ++ .../Updating/UpdatingCommaExpression1.jq | 4 ++ .../Updating/VacuousCommaExpression1.jq | 4 ++ 9 files changed, 98 insertions(+), 9 deletions(-) create mode 100644 src/test/resources/test_files/runtime/Updating/MultipleUpdatesArray1.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleDeleteFromArray2.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleInsertIntoArray2.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleTransform2.jq create mode 100644 src/test/resources/test_files/runtime/Updating/UpdatingCommaExpression1.jq create mode 100644 src/test/resources/test_files/runtime/Updating/VacuousCommaExpression1.jq diff --git a/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java b/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java index 7173adf7f1..73d8d51000 100644 --- a/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java +++ b/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java @@ -190,6 +190,7 @@ public RuntimeIterator visitCommaExpression(CommaExpression expression, RuntimeI } else { RuntimeIterator runtimeIterator = new CommaExpressionIterator( result, + expression.isUpdating(), expression.getHighestExecutionMode(this.visitorConfig), expression.getMetadata() ); diff --git a/src/main/java/org/rumbledb/runtime/CommaExpressionIterator.java b/src/main/java/org/rumbledb/runtime/CommaExpressionIterator.java index b6b4ae8f2c..11cf9c648d 100644 --- a/src/main/java/org/rumbledb/runtime/CommaExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/CommaExpressionIterator.java @@ -28,6 +28,7 @@ import org.rumbledb.exceptions.IteratorFlowException; import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.runtime.update.PendingUpdateList; import sparksoniq.spark.SparkSessionManager; import java.util.List; @@ -39,12 +40,23 @@ public class CommaExpressionIterator extends HybridRuntimeIterator { private Item nextResult; private int childIndex; + public CommaExpressionIterator( List childIterators, + boolean isUpdating, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata ) { super(childIterators, executionMode, iteratorMetadata); + this.isUpdating = isUpdating; + } + + public CommaExpressionIterator( + List childIterators, + ExecutionMode executionMode, + ExceptionMetadata iteratorMetadata + ) { + this(childIterators, false, executionMode, iteratorMetadata); } @Override @@ -138,4 +150,17 @@ public JavaRDD getRDDAux(DynamicContext dynamicContext) { return sparkContext.emptyRDD(); } } + + @Override + public PendingUpdateList getPendingUpdateList(DynamicContext context) { + if (!isUpdating()) { + return new PendingUpdateList(); + } + + PendingUpdateList pul = new PendingUpdateList(); + for (RuntimeIterator child : children) { + pul = PendingUpdateList.mergeUpdates(pul, child.getPendingUpdateList(context)); + } + return pul; + } } diff --git a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java index 90dd9c887a..432e9e807d 100644 --- a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java +++ b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java @@ -6,6 +6,7 @@ import org.rumbledb.exceptions.OurBadException; import org.rumbledb.exceptions.TooManyRenamesOnSameTargetSelectorException; import org.rumbledb.exceptions.TooManyReplacesOnSameTargetSelectorException; +import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.update.primitives.*; import org.rumbledb.types.ItemType; @@ -74,8 +75,21 @@ public void addUpdatePrimitive(UpdatePrimitive updatePrimitive) { } public void applyUpdates() { +// int INS_ARR_IDX = 0; +// int DEL_ARR_IDX = 1; +// int REP_ARR_IDX = 2; +// int INS_OBJ_IDX = 3; +// int DEL_OBJ_IDX = 4; +// int REP_OBJ_IDX = 5; +// int REN_OBJ_IDX = 6; - UpdatePrimitiveFactory factory = UpdatePrimitiveFactory.getInstance(); + Map arrayOffsetMap = new HashMap<>(); + +// Map>> targetPULs = new HashMap<>(); +// List> tempPULs; + + UpdatePrimitiveFactory upFactory = UpdatePrimitiveFactory.getInstance(); + ItemFactory itemFactory = ItemFactory.getInstance(); List pul = new ArrayList<>(); Map tempSelSrcMap; @@ -88,30 +102,37 @@ public void applyUpdates() { // DELETES & REPLACES for (Item target : delReplaceObjMap.keySet()) { List toDel = new ArrayList<>(); +// tempPULs = targetPULs.getOrDefault(target, new ArrayList<>(Arrays.asList(new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>()))); tempSelSrcMap = delReplaceObjMap.get(target); for (Item locator : tempSelSrcMap.keySet()) { tempSrc = tempSelSrcMap.get(locator); if (tempSrc == null) { toDel.add(locator); } else { - pul.add(factory.createReplaceInObjectPrimitive(target, locator, tempSrc)); + pul.add(upFactory.createReplaceInObjectPrimitive(target, locator, tempSrc)); +// tempPULs.get(REP_OBJ_IDX).add(upFactory.createReplaceInObjectPrimitive(target, locator, tempSrc)); } } - pul.add(factory.createDeleteFromObjectPrimitive(target, toDel)); + pul.add(upFactory.createDeleteFromObjectPrimitive(target, toDel)); +// tempPULs.get(DEL_OBJ_IDX).add(upFactory.createDeleteFromObjectPrimitive(target, toDel)); } // INSERTS for (Item target : insertObjMap.keySet()) { - pul.add(factory.createInsertIntoObjectPrimitive(target, insertObjMap.get(target))); +// tempPULs = targetPULs.getOrDefault(target, new ArrayList<>(Arrays.asList(new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>()))); + pul.add(upFactory.createInsertIntoObjectPrimitive(target, insertObjMap.get(target))); +// tempPULs.get(INS_OBJ_IDX).add(upFactory.createInsertIntoObjectPrimitive(target, insertObjMap.get(target))); } // RENAMES for (Item target : renameObjMap.keySet()) { +// tempPULs = targetPULs.getOrDefault(target, new ArrayList<>(Arrays.asList(new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>()))); tempSelSrcMap = renameObjMap.get(target); for (Item locator : tempSelSrcMap.keySet()) { - pul.add(factory.createRenameInObjectPrimitive(target, locator, tempSelSrcMap.get(locator))); + pul.add(upFactory.createRenameInObjectPrimitive(target, locator, tempSelSrcMap.get(locator))); +// tempPULs.get(REN_OBJ_IDX).add(upFactory.createRenameInObjectPrimitive(target, locator, tempSelSrcMap.get(locator))); } } @@ -120,23 +141,36 @@ public void applyUpdates() { // DELETES & REPLACES for (Item target : delReplaceArrayMap.keySet()) { + int num_del = 0; +// tempPULs = targetPULs.getOrDefault(target, new ArrayList<>(Arrays.asList(new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>()))); tempSelSrcMap = delReplaceArrayMap.get(target); for (Item locator : tempSelSrcMap.keySet()) { tempSrc = tempSelSrcMap.get(locator); + Item updatedLocator = itemFactory.createIntItem(locator.getIntValue() - num_del); if (tempSrc == null) { - pul.add(factory.createDeleteFromArrayPrimitive(target, locator)); + pul.add(upFactory.createDeleteFromArrayPrimitive(target, updatedLocator)); +// tempPULs.get(DEL_ARR_IDX).add(upFactory.createDeleteFromArrayPrimitive(target, updatedLocator)); + num_del++; } else { - pul.add(factory.createReplaceInArrayPrimitive(target, locator, tempSrc)); + pul.add(upFactory.createReplaceInArrayPrimitive(target, updatedLocator, tempSrc)); +// tempPULs.get(REP_ARR_IDX).add(upFactory.createReplaceInArrayPrimitive(target, updatedLocator, tempSrc)); } } + arrayOffsetMap.put(target, num_del); } // INSERTS for (Item target : insertArrayMap.keySet()) { + int num_dels = arrayOffsetMap.getOrDefault(target, 0); + int num_ins = 0; +// tempPULs = targetPULs.getOrDefault(target, new ArrayList<>(Arrays.asList(new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>()))); tempSelSrcListMap = insertArrayMap.get(target); for (Item locator : tempSelSrcListMap.keySet()) { - pul.add(factory.createInsertIntoArrayPrimitive(target, locator, tempSelSrcListMap.get(locator))); + Item updatedLocator = itemFactory.createIntItem(locator.getIntValue() + num_ins - num_dels); + pul.add(upFactory.createInsertIntoArrayPrimitive(target, updatedLocator, tempSelSrcListMap.get(locator))); + num_ins++; +// tempPULs.get(INS_ARR_IDX).add(upFactory.createInsertIntoArrayPrimitive(target, updatedLocator, tempSelSrcListMap.get(locator))); } } @@ -145,6 +179,11 @@ public void applyUpdates() { for (UpdatePrimitive updatePrimitive : pul) { updatePrimitive.apply(); } +// +// for (Item target : targetPULs.keySet()) { +// tempPULs = targetPULs.get(target); +// +// } } @@ -273,7 +312,7 @@ public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpda tempSelSrcResListMap = res.insertArrayMap.getOrDefault(target, new HashMap<>()); for (Item selector : tempSelSrcListMap.keySet()) { - tempSrcList = tempSelSrcResListMap.getOrDefault(selector, null); + tempSrcList = tempSelSrcResListMap.getOrDefault(selector, new ArrayList<>()); tempSelSrcResListMap.put(selector, InsertIntoArrayPrimitive.mergeSources(tempSelSrcListMap.get(selector), tempSrcList)); } res.insertArrayMap.put(target,tempSelSrcResListMap); diff --git a/src/test/resources/test_files/runtime/Updating/MultipleUpdatesArray1.jq b/src/test/resources/test_files/runtime/Updating/MultipleUpdatesArray1.jq new file mode 100644 index 0000000000..91a38d2336 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/MultipleUpdatesArray1.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="[ 1, 5, 3, 4 ]" :) +copy json $je := [1 to 4] +modify (delete json $je[[2]], insert json 5 into $je at position 3) +return $je \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleDeleteFromArray2.jq b/src/test/resources/test_files/runtime/Updating/SimpleDeleteFromArray2.jq new file mode 100644 index 0000000000..02dffcaccc --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleDeleteFromArray2.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="[ 1, 4 ]" :) +copy json $je := [1 to 4] +modify (delete json $je[[3]], delete json $je[[2]]) +return $je \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleInsertIntoArray2.jq b/src/test/resources/test_files/runtime/Updating/SimpleInsertIntoArray2.jq new file mode 100644 index 0000000000..66d1afabe9 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleInsertIntoArray2.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="[ 1, 2, 3, 5, 4, 6 ]" :) +copy json $je := [1 to 4] +modify (insert json 5 into $je at position 4, insert json 6 into $je at position 5) +return $je diff --git a/src/test/resources/test_files/runtime/Updating/SimpleTransform2.jq b/src/test/resources/test_files/runtime/Updating/SimpleTransform2.jq new file mode 100644 index 0000000000..f45a508382 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleTransform2.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="[ 1, 2, 3, 4 ]" :) +copy json $je := [1 to 4] +modify () +return $je diff --git a/src/test/resources/test_files/runtime/Updating/UpdatingCommaExpression1.jq b/src/test/resources/test_files/runtime/Updating/UpdatingCommaExpression1.jq new file mode 100644 index 0000000000..adc6c93145 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/UpdatingCommaExpression1.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="[ 3, 4 ]" :) +copy json $je := [1 to 4] +modify ((), delete json $je[[1]], delete json $je[[2]]) +return $je diff --git a/src/test/resources/test_files/runtime/Updating/VacuousCommaExpression1.jq b/src/test/resources/test_files/runtime/Updating/VacuousCommaExpression1.jq new file mode 100644 index 0000000000..2a02b9ab9d --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/VacuousCommaExpression1.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="[ 1, 2, 3, 4 ]" :) +copy json $je := [1 to 4] +modify ((), (), ()) +return $je From 8638154bfbd1e02d55e183f2c89a1df2ae9bd3d2 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sat, 6 May 2023 17:04:52 +0200 Subject: [PATCH 061/119] Implement tests for multiple updates on same array --- .../test_files/runtime/Updating/MultipleUpdatesArray2.jq | 4 ++++ .../test_files/runtime/Updating/MultipleUpdatesArray3.jq | 4 ++++ .../test_files/runtime/Updating/MultipleUpdatesArray4.jq | 4 ++++ .../test_files/runtime/Updating/MultipleUpdatesArray5.jq | 4 ++++ .../test_files/runtime/Updating/SimpleInsertIntoArray3.jq | 4 ++++ 5 files changed, 20 insertions(+) create mode 100644 src/test/resources/test_files/runtime/Updating/MultipleUpdatesArray2.jq create mode 100644 src/test/resources/test_files/runtime/Updating/MultipleUpdatesArray3.jq create mode 100644 src/test/resources/test_files/runtime/Updating/MultipleUpdatesArray4.jq create mode 100644 src/test/resources/test_files/runtime/Updating/MultipleUpdatesArray5.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleInsertIntoArray3.jq diff --git a/src/test/resources/test_files/runtime/Updating/MultipleUpdatesArray2.jq b/src/test/resources/test_files/runtime/Updating/MultipleUpdatesArray2.jq new file mode 100644 index 0000000000..dddcc2be4f --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/MultipleUpdatesArray2.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="[ 1, 2, 5, 4 ]" :) +copy json $je := [1 to 4] +modify (delete json $je[[3]], insert json 5 into $je at position 3) +return $je \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/MultipleUpdatesArray3.jq b/src/test/resources/test_files/runtime/Updating/MultipleUpdatesArray3.jq new file mode 100644 index 0000000000..47217152e1 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/MultipleUpdatesArray3.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="[ 1, 2, 5, 4 ]" :) +copy json $je := [1 to 4] +modify (delete json $je[[3]], insert json 5 into $je at position 3, replace json value of $je[[3]] with 6) +return $je \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/MultipleUpdatesArray4.jq b/src/test/resources/test_files/runtime/Updating/MultipleUpdatesArray4.jq new file mode 100644 index 0000000000..dcddc2dabe --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/MultipleUpdatesArray4.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="[ 1, 2, 5, 6, 4 ]" :) +copy json $je := [1 to 4] +modify (insert json 5 into $je at position 3, replace json value of $je[[3]] with 6) +return $je \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/MultipleUpdatesArray5.jq b/src/test/resources/test_files/runtime/Updating/MultipleUpdatesArray5.jq new file mode 100644 index 0000000000..958d273ad0 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/MultipleUpdatesArray5.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="[ 9, 5, 7, 8, 6 ]" :) +copy json $je := [1 to 4] +modify (delete json $je[[1]], delete json $je[[3]], replace json value of $je[[2]] with 5, replace json value of $je[[4]] with 6, insert json 7 into $je at position 4, insert json 8 into $je at position 4, insert json 9 into $je at position 1) +return $je \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleInsertIntoArray3.jq b/src/test/resources/test_files/runtime/Updating/SimpleInsertIntoArray3.jq new file mode 100644 index 0000000000..a05fb5c349 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleInsertIntoArray3.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="[ 1, 2, 5, 5, 3, 4 ]" :) +copy json $je := [1 to 4] +modify (insert json 5 into $je at position 3, insert json 5 into $je at position 3) +return $je \ No newline at end of file From d3def15528e9df070fba542243af442735ea707c Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sat, 6 May 2023 17:05:44 +0200 Subject: [PATCH 062/119] Fix apply updates to apply array updates in reverse index order and ensure InsertIntoArrayPrimitive merges maintain order --- .../runtime/update/PendingUpdateList.java | 91 ++++++++----------- .../primitives/DeleteFromArrayPrimitive.java | 5 + .../primitives/InsertIntoArrayPrimitive.java | 5 + .../primitives/ReplaceInArrayPrimitive.java | 5 + .../update/primitives/UpdatePrimitive.java | 2 + 5 files changed, 57 insertions(+), 51 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java index 432e9e807d..5a42c083ac 100644 --- a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java +++ b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java @@ -9,6 +9,7 @@ import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.update.primitives.*; import org.rumbledb.types.ItemType; +import shapeless.ops.zipper; import java.util.*; @@ -75,64 +76,45 @@ public void addUpdatePrimitive(UpdatePrimitive updatePrimitive) { } public void applyUpdates() { -// int INS_ARR_IDX = 0; -// int DEL_ARR_IDX = 1; -// int REP_ARR_IDX = 2; -// int INS_OBJ_IDX = 3; -// int DEL_OBJ_IDX = 4; -// int REP_OBJ_IDX = 5; -// int REN_OBJ_IDX = 6; - - Map arrayOffsetMap = new HashMap<>(); - -// Map>> targetPULs = new HashMap<>(); -// List> tempPULs; - UpdatePrimitiveFactory upFactory = UpdatePrimitiveFactory.getInstance(); - ItemFactory itemFactory = ItemFactory.getInstance(); - List pul = new ArrayList<>(); + Map> targetArrayPULs = new HashMap<>(); + List tempArrayPULs; + + List objectPUL = new ArrayList<>(); Map tempSelSrcMap; Map> tempSelSrcListMap; Item tempSrc; - List tempSrcList; ////// OBJECTS // DELETES & REPLACES for (Item target : delReplaceObjMap.keySet()) { List toDel = new ArrayList<>(); -// tempPULs = targetPULs.getOrDefault(target, new ArrayList<>(Arrays.asList(new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>()))); tempSelSrcMap = delReplaceObjMap.get(target); for (Item locator : tempSelSrcMap.keySet()) { tempSrc = tempSelSrcMap.get(locator); if (tempSrc == null) { toDel.add(locator); } else { - pul.add(upFactory.createReplaceInObjectPrimitive(target, locator, tempSrc)); -// tempPULs.get(REP_OBJ_IDX).add(upFactory.createReplaceInObjectPrimitive(target, locator, tempSrc)); + objectPUL.add(upFactory.createReplaceInObjectPrimitive(target, locator, tempSrc)); } } - pul.add(upFactory.createDeleteFromObjectPrimitive(target, toDel)); -// tempPULs.get(DEL_OBJ_IDX).add(upFactory.createDeleteFromObjectPrimitive(target, toDel)); + objectPUL.add(upFactory.createDeleteFromObjectPrimitive(target, toDel)); } // INSERTS for (Item target : insertObjMap.keySet()) { -// tempPULs = targetPULs.getOrDefault(target, new ArrayList<>(Arrays.asList(new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>()))); - pul.add(upFactory.createInsertIntoObjectPrimitive(target, insertObjMap.get(target))); -// tempPULs.get(INS_OBJ_IDX).add(upFactory.createInsertIntoObjectPrimitive(target, insertObjMap.get(target))); + objectPUL.add(upFactory.createInsertIntoObjectPrimitive(target, insertObjMap.get(target))); } // RENAMES for (Item target : renameObjMap.keySet()) { -// tempPULs = targetPULs.getOrDefault(target, new ArrayList<>(Arrays.asList(new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>()))); tempSelSrcMap = renameObjMap.get(target); for (Item locator : tempSelSrcMap.keySet()) { - pul.add(upFactory.createRenameInObjectPrimitive(target, locator, tempSelSrcMap.get(locator))); -// tempPULs.get(REN_OBJ_IDX).add(upFactory.createRenameInObjectPrimitive(target, locator, tempSelSrcMap.get(locator))); + objectPUL.add(upFactory.createRenameInObjectPrimitive(target, locator, tempSelSrcMap.get(locator))); } } @@ -141,49 +123,56 @@ public void applyUpdates() { // DELETES & REPLACES for (Item target : delReplaceArrayMap.keySet()) { - int num_del = 0; -// tempPULs = targetPULs.getOrDefault(target, new ArrayList<>(Arrays.asList(new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>()))); + tempArrayPULs = targetArrayPULs.getOrDefault(target, new ArrayList<>()); tempSelSrcMap = delReplaceArrayMap.get(target); for (Item locator : tempSelSrcMap.keySet()) { + UpdatePrimitive up; tempSrc = tempSelSrcMap.get(locator); - Item updatedLocator = itemFactory.createIntItem(locator.getIntValue() - num_del); if (tempSrc == null) { - pul.add(upFactory.createDeleteFromArrayPrimitive(target, updatedLocator)); -// tempPULs.get(DEL_ARR_IDX).add(upFactory.createDeleteFromArrayPrimitive(target, updatedLocator)); - num_del++; + up = upFactory.createDeleteFromArrayPrimitive(target, locator); } else { - pul.add(upFactory.createReplaceInArrayPrimitive(target, updatedLocator, tempSrc)); -// tempPULs.get(REP_ARR_IDX).add(upFactory.createReplaceInArrayPrimitive(target, updatedLocator, tempSrc)); + up = upFactory.createReplaceInArrayPrimitive(target, locator, tempSrc); + } + int index = Collections.binarySearch(tempArrayPULs, up, Comparator.comparing(UpdatePrimitive::getIntSelector)); + if (index < 0) { + index = -index - 1; } + tempArrayPULs.add(index, up); } - arrayOffsetMap.put(target, num_del); + targetArrayPULs.put(target, tempArrayPULs); } // INSERTS for (Item target : insertArrayMap.keySet()) { - int num_dels = arrayOffsetMap.getOrDefault(target, 0); - int num_ins = 0; -// tempPULs = targetPULs.getOrDefault(target, new ArrayList<>(Arrays.asList(new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>()))); + UpdatePrimitive up; + tempArrayPULs = targetArrayPULs.getOrDefault(target, new ArrayList<>()); tempSelSrcListMap = insertArrayMap.get(target); for (Item locator : tempSelSrcListMap.keySet()) { - Item updatedLocator = itemFactory.createIntItem(locator.getIntValue() + num_ins - num_dels); - pul.add(upFactory.createInsertIntoArrayPrimitive(target, updatedLocator, tempSelSrcListMap.get(locator))); - num_ins++; -// tempPULs.get(INS_ARR_IDX).add(upFactory.createInsertIntoArrayPrimitive(target, updatedLocator, tempSelSrcListMap.get(locator))); + up = upFactory.createInsertIntoArrayPrimitive(target, locator, tempSelSrcListMap.get(locator)); + int index = Collections.binarySearch(tempArrayPULs, up, Comparator.comparing(UpdatePrimitive::getIntSelector)); + if (index < 0) { + index = -index - 1; + } + tempArrayPULs.add(index, up); } + targetArrayPULs.put(target, tempArrayPULs); } - ////// APPLY + ////// APPLY OBJECTS - for (UpdatePrimitive updatePrimitive : pul) { + for (UpdatePrimitive updatePrimitive : objectPUL) { updatePrimitive.apply(); } -// -// for (Item target : targetPULs.keySet()) { -// tempPULs = targetPULs.get(target); -// -// } + + ////// APPLY ARRAYS + + for (Item target : targetArrayPULs.keySet()) { + tempArrayPULs = targetArrayPULs.get(target); + for (int i = tempArrayPULs.size() - 1; i >= 0; i--) { + tempArrayPULs.get(i).apply(); + } + } } @@ -313,7 +302,7 @@ public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpda for (Item selector : tempSelSrcListMap.keySet()) { tempSrcList = tempSelSrcResListMap.getOrDefault(selector, new ArrayList<>()); - tempSelSrcResListMap.put(selector, InsertIntoArrayPrimitive.mergeSources(tempSelSrcListMap.get(selector), tempSrcList)); + tempSelSrcResListMap.put(selector, InsertIntoArrayPrimitive.mergeSources( tempSrcList, tempSelSrcListMap.get(selector))); } res.insertArrayMap.put(target,tempSelSrcResListMap); } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java index 7f1c334ddc..e576a490cb 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java @@ -40,6 +40,11 @@ public Item getSelector() { return selector; } + @Override + public int getIntSelector() { + return selector.getIntValue(); + } + @Override public Item getContent() { return null; diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java index b2a1dc4b1b..1f595c28a8 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java @@ -46,6 +46,11 @@ public Item getSelector() { return selector; } + @Override + public int getIntSelector() { + return selector.getIntValue(); + } + @Override public List getContentList() { return content; diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java index f3386ff37b..692633fe59 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java @@ -47,6 +47,11 @@ public Item getSelector() { return selector; } + @Override + public int getIntSelector() { + return selector.getIntValue(); + } + @Override public Item getContent() { return content; diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java index bfc30de0de..006f7d5842 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java @@ -14,6 +14,8 @@ public interface UpdatePrimitive { default Item getSelector() {throw new UnsupportedOperationException("Operation not defined");} + default int getIntSelector() {throw new UnsupportedOperationException("Operation not defined");} + default Item getContent() { throw new UnsupportedOperationException("Operation not defined"); } From 98bcb527157ed94aa80c2e0781fe0a12067f8cb3 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sat, 6 May 2023 22:50:30 +0200 Subject: [PATCH 063/119] Create tests for multiple of same update primitive on objects --- .../test_files/runtime/Updating/SimpleDeleteFromObject2.jq | 4 ++++ .../test_files/runtime/Updating/SimpleInsertIntoObject2.jq | 4 ++++ .../test_files/runtime/Updating/SimpleRenameInObject2.jq | 4 ++++ .../test_files/runtime/Updating/SimpleReplaceInArray2.jq | 4 ++++ .../test_files/runtime/Updating/SimpleReplaceInObject2.jq | 4 ++++ 5 files changed, 20 insertions(+) create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleDeleteFromObject2.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleInsertIntoObject2.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleRenameInObject2.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleReplaceInArray2.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleReplaceInObject2.jq diff --git a/src/test/resources/test_files/runtime/Updating/SimpleDeleteFromObject2.jq b/src/test/resources/test_files/runtime/Updating/SimpleDeleteFromObject2.jq new file mode 100644 index 0000000000..5eaf4b819a --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleDeleteFromObject2.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="{ }" :) +copy json $je := {"foo": "bar", "foobar": "barfoo"} +modify (delete json $je.foobar, delete json $je.foo) +return $je \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleInsertIntoObject2.jq b/src/test/resources/test_files/runtime/Updating/SimpleInsertIntoObject2.jq new file mode 100644 index 0000000000..39a3a814c4 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleInsertIntoObject2.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="{ "foo" : "bar", "foobar" : "barfoo", "bar" : "foo" }" :) +copy json $je := {"foo" : "bar"} +modify (insert json "foobar": "barfoo" into $je, insert json "bar": "foo" into $je) +return $je \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleRenameInObject2.jq b/src/test/resources/test_files/runtime/Updating/SimpleRenameInObject2.jq new file mode 100644 index 0000000000..60374e527e --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleRenameInObject2.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="{ "barfoo" : "barfoo", "bar" : "bar" }" :) +copy json $je := {"foo": "bar", "foobar": "barfoo"} +modify (rename json $je.foo as "bar", rename json $je.foobar as "barfoo") +return $je \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleReplaceInArray2.jq b/src/test/resources/test_files/runtime/Updating/SimpleReplaceInArray2.jq new file mode 100644 index 0000000000..9be1ca15ca --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleReplaceInArray2.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="[ 1, 2, 5, 6 ]" :) +copy json $je := [1 to 4] +modify (replace json value of $je[[3]] with 5, replace json value of $je[[4]] with 6) +return $je \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleReplaceInObject2.jq b/src/test/resources/test_files/runtime/Updating/SimpleReplaceInObject2.jq new file mode 100644 index 0000000000..c1d0f54d8b --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleReplaceInObject2.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="{ "foobar" : "foobar", "foo" : "foo" }" :) +copy json $je := {"foo": "bar", "foobar": "barfoo"} +modify (replace json value of $je.foo with "foo", replace json value of $je."foobar" with "foobar") +return $je \ No newline at end of file From be0b72041412bade055e1a37e432e134dd1964ac Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sat, 6 May 2023 22:50:50 +0200 Subject: [PATCH 064/119] Fix PUL merge to merge renames properly --- .../java/org/rumbledb/runtime/update/PendingUpdateList.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java index 5a42c083ac..c5416316e1 100644 --- a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java +++ b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java @@ -237,7 +237,7 @@ public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpda for (Item selector : tempSelSrcMap.keySet()) { tempSelSrcResMap.put(selector, tempSelSrcMap.get(selector)); } - res.delReplaceObjMap.put(target,tempSelSrcResMap); + res.renameObjMap.put(target,tempSelSrcResMap); } for (Item target : pul2.renameObjMap.keySet()) { @@ -250,7 +250,7 @@ public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpda } tempSelSrcResMap.put(selector, tempSelSrcMap.get(selector)); } - res.delReplaceObjMap.put(target,tempSelSrcResMap); + res.renameObjMap.put(target,tempSelSrcResMap); } ////// ARRAYS From 43da2ae07bc9f8cf097ad779f663085ddd95ea89 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sat, 6 May 2023 23:26:18 +0200 Subject: [PATCH 065/119] Test multiple update primitives on objects --- .../test_files/runtime/Updating/MultipleUpdatesObject1.jq | 4 ++++ .../test_files/runtime/Updating/MultipleUpdatesObject2.jq | 4 ++++ .../test_files/runtime/Updating/MultipleUpdatesObject3.jq | 4 ++++ .../test_files/runtime/Updating/MultipleUpdatesObject4.jq | 4 ++++ 4 files changed, 16 insertions(+) create mode 100644 src/test/resources/test_files/runtime/Updating/MultipleUpdatesObject1.jq create mode 100644 src/test/resources/test_files/runtime/Updating/MultipleUpdatesObject2.jq create mode 100644 src/test/resources/test_files/runtime/Updating/MultipleUpdatesObject3.jq create mode 100644 src/test/resources/test_files/runtime/Updating/MultipleUpdatesObject4.jq diff --git a/src/test/resources/test_files/runtime/Updating/MultipleUpdatesObject1.jq b/src/test/resources/test_files/runtime/Updating/MultipleUpdatesObject1.jq new file mode 100644 index 0000000000..287ba55bd8 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/MultipleUpdatesObject1.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="{ "b" : 2, "c" : 3, "d" : 4, "e" : 5 }" :) +copy json $je := {"a": 1, "b": 2, "c": 3, "d": 4} +modify (delete json $je.a, insert json "e": 5 into $je) +return $je \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/MultipleUpdatesObject2.jq b/src/test/resources/test_files/runtime/Updating/MultipleUpdatesObject2.jq new file mode 100644 index 0000000000..849d726d31 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/MultipleUpdatesObject2.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="{ "b" : 2, "c" : 3, "d" : 4, "e" : 5 }" :) +copy json $je := {"a": 1, "b": 2, "c": 3, "d": 4} +modify (delete json $je.a, insert json "e": 5 into $je, replace json value of $je.a with 6, rename json $je.a as "f") +return $je \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/MultipleUpdatesObject3.jq b/src/test/resources/test_files/runtime/Updating/MultipleUpdatesObject3.jq new file mode 100644 index 0000000000..cead5245f7 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/MultipleUpdatesObject3.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="{ "b" : 2, "c" : 3, "d" : 4, "e" : 5, "f" : 6 }" :) +copy json $je := {"a": 1, "b": 2, "c": 3, "d": 4} +modify (insert json "e": 5 into $je, replace json value of $je.a with 6, rename json $je.a as "f") +return $je \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/MultipleUpdatesObject4.jq b/src/test/resources/test_files/runtime/Updating/MultipleUpdatesObject4.jq new file mode 100644 index 0000000000..214d5ff248 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/MultipleUpdatesObject4.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="{ "a" : 4, "e" : 5, "g" : 6, "f" : 7 }" :) +copy json $je := {"a": 1, "b": 2, "c": 3, "d": 4} +modify (insert json "e": 5 into $je, replace json value of $je.a with 4, rename json $je.b as "f", replace json value of $je.b with 7, delete json $je.c, delete json $je.d, insert json "g" : 6 into $je) +return $je \ No newline at end of file From f619f475d9d460eb60e4a7b7ed7a6d00c7dba5a8 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 8 May 2023 17:27:11 +0200 Subject: [PATCH 066/119] Create simple tests for basic FLWOR exprs --- .../resources/test_files/runtime/Updating/UpdatingFLWOR1.jq | 6 ++++++ .../resources/test_files/runtime/Updating/UpdatingFLWOR2.jq | 6 ++++++ .../resources/test_files/runtime/Updating/UpdatingFLWOR3.jq | 6 ++++++ 3 files changed, 18 insertions(+) create mode 100644 src/test/resources/test_files/runtime/Updating/UpdatingFLWOR1.jq create mode 100644 src/test/resources/test_files/runtime/Updating/UpdatingFLWOR2.jq create mode 100644 src/test/resources/test_files/runtime/Updating/UpdatingFLWOR3.jq diff --git a/src/test/resources/test_files/runtime/Updating/UpdatingFLWOR1.jq b/src/test/resources/test_files/runtime/Updating/UpdatingFLWOR1.jq new file mode 100644 index 0000000000..23362a38e6 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/UpdatingFLWOR1.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldRun; Output="{ "b" : 1 }" :) +let $a := {"a" : 1} +return + copy json $je := $a + modify rename json $je.a as "b" + return $je \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/UpdatingFLWOR2.jq b/src/test/resources/test_files/runtime/Updating/UpdatingFLWOR2.jq new file mode 100644 index 0000000000..f28cca4b63 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/UpdatingFLWOR2.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldRun; Output="({ "b" : 1 }, { "b" : 2 }, { "b" : 3 }, { "b" : 4 })" :) +for $a in ( {"a" : 1}, {"a" : 2}, {"a" : 3}, {"a" : 4} ) +return + copy json $je := $a + modify rename json $je.a as "b" + return $je \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/UpdatingFLWOR3.jq b/src/test/resources/test_files/runtime/Updating/UpdatingFLWOR3.jq new file mode 100644 index 0000000000..713eb79ff4 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/UpdatingFLWOR3.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldRun; Output="({ "a" : 1 }, { "b" : 1 })" :) +let $oldx := {"a" : 1} +return + copy json $newx := $oldx + modify rename json $newx.a as "b" + return ($oldx, $newx) \ No newline at end of file From 4f2ce57d988d2d98f16d68300b152785c7872888 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 8 May 2023 17:32:13 +0200 Subject: [PATCH 067/119] Remove storage of PUL --- .../expression/AppendExpressionIterator.java | 46 +++++++--------- .../expression/DeleteExpressionIterator.java | 48 ++++++++--------- .../expression/InsertExpressionIterator.java | 52 ++++++++----------- .../expression/RenameExpressionIterator.java | 48 ++++++++--------- .../expression/ReplaceExpressionIterator.java | 52 ++++++++----------- 5 files changed, 108 insertions(+), 138 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java index 51d1e4167b..7cd0641247 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java @@ -23,14 +23,12 @@ public class AppendExpressionIterator extends HybridRuntimeIterator { private RuntimeIterator arrayIterator; private RuntimeIterator toAppendIterator; - private PendingUpdateList pul; public AppendExpressionIterator(RuntimeIterator arrayIterator, RuntimeIterator toAppendIterator, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { super(Arrays.asList(arrayIterator, toAppendIterator), executionMode, iteratorMetadata); this.arrayIterator = arrayIterator; this.toAppendIterator = toAppendIterator; - this.pul = null; this.isUpdating = true; } @@ -66,31 +64,27 @@ protected Item nextLocal() { @Override public PendingUpdateList getPendingUpdateList(DynamicContext context) { - if (this.pul == null) { - PendingUpdateList pul = new PendingUpdateList(); - Item target; - Item content; - - try { - target = this.arrayIterator.materializeExactlyOneItem(context); - content = this.toAppendIterator.materializeExactlyOneItem(context); - } catch (NoItemException | MoreThanOneItemException e) { - throw new RuntimeException(e); - } - - UpdatePrimitiveFactory factory = UpdatePrimitiveFactory.getInstance(); - UpdatePrimitive up; - if (target.isArray()) { - Item locator = ItemFactory.getInstance().createIntItem(target.getSize() + 1); - up = factory.createInsertIntoArrayPrimitive(target, locator, Collections.singletonList(content)); - } else { - throw new OurBadException("Append iterator cannot handle target items that are not arrays"); - } - - pul.addUpdatePrimitive(up); - this.pul = pul; + PendingUpdateList pul = new PendingUpdateList(); + Item target; + Item content; + + try { + target = this.arrayIterator.materializeExactlyOneItem(context); + content = this.toAppendIterator.materializeExactlyOneItem(context); + } catch (NoItemException | MoreThanOneItemException e) { + throw new RuntimeException(e); } - return this.pul; + UpdatePrimitiveFactory factory = UpdatePrimitiveFactory.getInstance(); + UpdatePrimitive up; + if (target.isArray()) { + Item locator = ItemFactory.getInstance().createIntItem(target.getSize() + 1); + up = factory.createInsertIntoArrayPrimitive(target, locator, Collections.singletonList(content)); + } else { + throw new OurBadException("Append iterator cannot handle target items that are not arrays"); + } + + pul.addUpdatePrimitive(up); + return pul; } } diff --git a/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java index b606cc22da..60848c8b29 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java @@ -21,13 +21,11 @@ public class DeleteExpressionIterator extends HybridRuntimeIterator { private RuntimeIterator mainIterator; private RuntimeIterator lookupIterator; - private PendingUpdateList pul; public DeleteExpressionIterator(RuntimeIterator mainIterator, RuntimeIterator lookupIterator, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { super(Arrays.asList(mainIterator, lookupIterator), executionMode, iteratorMetadata); this.mainIterator = mainIterator; this.lookupIterator = lookupIterator; - this.pul = null; this.isUpdating = true; } @@ -63,32 +61,28 @@ protected Item nextLocal() { @Override public PendingUpdateList getPendingUpdateList(DynamicContext context) { - if (this.pul == null) { - PendingUpdateList pul = new PendingUpdateList(); - Item main; - Item lookup; - - try { - main = this.mainIterator.materializeExactlyOneItem(context); - lookup = this.lookupIterator.materializeExactlyOneItem(context); - } catch (NoItemException | MoreThanOneItemException e) { - throw new RuntimeException(e); - } - - UpdatePrimitiveFactory factory = UpdatePrimitiveFactory.getInstance(); - UpdatePrimitive up; - if (main.isObject()) { - up = factory.createDeleteFromObjectPrimitive(main, Collections.singletonList(lookup)); - } else if (main.isArray()) { - up = factory.createDeleteFromArrayPrimitive(main, lookup); - } else { - throw new OurBadException("Delete iterator cannot handle main items that are not objects or arrays"); - } - - pul.addUpdatePrimitive(up); - this.pul = pul; + PendingUpdateList pul = new PendingUpdateList(); + Item main; + Item lookup; + + try { + main = this.mainIterator.materializeExactlyOneItem(context); + lookup = this.lookupIterator.materializeExactlyOneItem(context); + } catch (NoItemException | MoreThanOneItemException e) { + throw new RuntimeException(e); } - return this.pul; + UpdatePrimitiveFactory factory = UpdatePrimitiveFactory.getInstance(); + UpdatePrimitive up; + if (main.isObject()) { + up = factory.createDeleteFromObjectPrimitive(main, Collections.singletonList(lookup)); + } else if (main.isArray()) { + up = factory.createDeleteFromArrayPrimitive(main, lookup); + } else { + throw new OurBadException("Delete iterator cannot handle main items that are not objects or arrays"); + } + + pul.addUpdatePrimitive(up); + return pul; } } diff --git a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java index c88bd14168..588bf982a3 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java @@ -24,7 +24,6 @@ public class InsertExpressionIterator extends HybridRuntimeIterator { private RuntimeIterator mainIterator; private RuntimeIterator toInsertIterator; private RuntimeIterator positionIterator; - private PendingUpdateList pul; public InsertExpressionIterator(RuntimeIterator mainIterator, RuntimeIterator toInsertIterator, RuntimeIterator positionIterator, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { super( @@ -38,7 +37,6 @@ public InsertExpressionIterator(RuntimeIterator mainIterator, RuntimeIterator to this.mainIterator = mainIterator; this.toInsertIterator = toInsertIterator; this.positionIterator = positionIterator; - this.pul = null; this.isUpdating = true; } @@ -78,36 +76,32 @@ protected Item nextLocal() { @Override public PendingUpdateList getPendingUpdateList(DynamicContext context) { - if (this.pul == null) { - PendingUpdateList pul = new PendingUpdateList(); - Item main; - Item content; - Item locator = null; - - try { - main = this.mainIterator.materializeExactlyOneItem(context); - content = this.toInsertIterator.materializeExactlyOneItem(context); - if (this.hasPositionIterator()) { - locator = this.positionIterator.materializeExactlyOneItem(context); - } - } catch (NoItemException | MoreThanOneItemException e) { - throw new RuntimeException(e); - } - - UpdatePrimitiveFactory factory = UpdatePrimitiveFactory.getInstance(); - UpdatePrimitive up; - if (main.isObject()) { - up = factory.createInsertIntoObjectPrimitive(main, content); - } else if (main.isArray()) { - up = factory.createInsertIntoArrayPrimitive(main, locator, Collections.singletonList(content)); - } else { - throw new OurBadException("Insert iterator cannot handle main items that are not objects or arrays"); + PendingUpdateList pul = new PendingUpdateList(); + Item main; + Item content; + Item locator = null; + + try { + main = this.mainIterator.materializeExactlyOneItem(context); + content = this.toInsertIterator.materializeExactlyOneItem(context); + if (this.hasPositionIterator()) { + locator = this.positionIterator.materializeExactlyOneItem(context); } + } catch (NoItemException | MoreThanOneItemException e) { + throw new RuntimeException(e); + } - pul.addUpdatePrimitive(up); - this.pul = pul; + UpdatePrimitiveFactory factory = UpdatePrimitiveFactory.getInstance(); + UpdatePrimitive up; + if (main.isObject()) { + up = factory.createInsertIntoObjectPrimitive(main, content); + } else if (main.isArray()) { + up = factory.createInsertIntoArrayPrimitive(main, locator, Collections.singletonList(content)); + } else { + throw new OurBadException("Insert iterator cannot handle main items that are not objects or arrays"); } - return this.pul; + pul.addUpdatePrimitive(up); + return pul; } } diff --git a/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java index 9b76355bb5..ba06c4c51d 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java @@ -24,7 +24,6 @@ public class RenameExpressionIterator extends HybridRuntimeIterator { private RuntimeIterator mainIterator; private RuntimeIterator locatorIterator; private RuntimeIterator nameIterator; - private PendingUpdateList pul; public RenameExpressionIterator(RuntimeIterator mainIterator, RuntimeIterator locatorIterator, RuntimeIterator nameIterator, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { super(Arrays.asList(mainIterator, locatorIterator, nameIterator), executionMode, iteratorMetadata); @@ -32,7 +31,6 @@ public RenameExpressionIterator(RuntimeIterator mainIterator, RuntimeIterator lo this.mainIterator = mainIterator; this.locatorIterator = locatorIterator; this.nameIterator = nameIterator; - this.pul = null; this.isUpdating = true; } @@ -68,32 +66,28 @@ protected Item nextLocal() { @Override public PendingUpdateList getPendingUpdateList(DynamicContext context) { - if (this.pul == null) { - PendingUpdateList pul = new PendingUpdateList(); - Item target; - Item locator; - Item content; - - try { - target = this.mainIterator.materializeExactlyOneItem(context); - locator = this.locatorIterator.materializeExactlyOneItem(context); - content = this.nameIterator.materializeExactlyOneItem(context); - } catch (NoItemException | MoreThanOneItemException e) { - throw new RuntimeException(e); - } - - UpdatePrimitiveFactory factory = UpdatePrimitiveFactory.getInstance(); - UpdatePrimitive up; - if (target.isObject()) { - up = factory.createRenameInObjectPrimitive(target, locator, content); - } else { - throw new OurBadException("Rename iterator cannot handle target items that are not objects"); - } - - pul.addUpdatePrimitive(up); - this.pul = pul; + PendingUpdateList pul = new PendingUpdateList(); + Item target; + Item locator; + Item content; + + try { + target = this.mainIterator.materializeExactlyOneItem(context); + locator = this.locatorIterator.materializeExactlyOneItem(context); + content = this.nameIterator.materializeExactlyOneItem(context); + } catch (NoItemException | MoreThanOneItemException e) { + throw new RuntimeException(e); } - return this.pul; + UpdatePrimitiveFactory factory = UpdatePrimitiveFactory.getInstance(); + UpdatePrimitive up; + if (target.isObject()) { + up = factory.createRenameInObjectPrimitive(target, locator, content); + } else { + throw new OurBadException("Rename iterator cannot handle target items that are not objects"); + } + + pul.addUpdatePrimitive(up); + return pul; } } diff --git a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java index d8ac370fb6..66c9d7839d 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java @@ -22,7 +22,6 @@ public class ReplaceExpressionIterator extends HybridRuntimeIterator { private RuntimeIterator mainIterator; private RuntimeIterator locatorIterator; private RuntimeIterator replacerIterator; - private PendingUpdateList pul; public ReplaceExpressionIterator(RuntimeIterator mainIterator, RuntimeIterator locatorIterator, RuntimeIterator replacerIterator, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { super(Arrays.asList(mainIterator, locatorIterator, replacerIterator), executionMode, iteratorMetadata); @@ -30,7 +29,6 @@ public ReplaceExpressionIterator(RuntimeIterator mainIterator, RuntimeIterator l this.mainIterator = mainIterator; this.locatorIterator = locatorIterator; this.replacerIterator = replacerIterator; - this.pul = null; this.isUpdating = true; } @@ -66,34 +64,30 @@ protected Item nextLocal() { @Override public PendingUpdateList getPendingUpdateList(DynamicContext context) { - if (this.pul == null) { - PendingUpdateList pul = new PendingUpdateList(); - Item target; - Item locator; - Item content; - - try { - target = this.mainIterator.materializeExactlyOneItem(context); - locator = this.locatorIterator.materializeExactlyOneItem(context); - content = this.replacerIterator.materializeExactlyOneItem(context); - } catch (NoItemException | MoreThanOneItemException e) { - throw new RuntimeException(e); - } - - UpdatePrimitiveFactory factory = UpdatePrimitiveFactory.getInstance(); - UpdatePrimitive up; - if (target.isObject()) { - up = factory.createReplaceInObjectPrimitive(target, locator, content); - } else if (target.isArray()) { - up = factory.createReplaceInArrayPrimitive(target, locator, content); - } else { - throw new OurBadException("Replace iterator cannot handle target items that are not objects or arrays"); - } - - pul.addUpdatePrimitive(up); - this.pul = pul; + PendingUpdateList pul = new PendingUpdateList(); + Item target; + Item locator; + Item content; + + try { + target = this.mainIterator.materializeExactlyOneItem(context); + locator = this.locatorIterator.materializeExactlyOneItem(context); + content = this.replacerIterator.materializeExactlyOneItem(context); + } catch (NoItemException | MoreThanOneItemException e) { + throw new RuntimeException(e); } - return this.pul; + UpdatePrimitiveFactory factory = UpdatePrimitiveFactory.getInstance(); + UpdatePrimitive up; + if (target.isObject()) { + up = factory.createReplaceInObjectPrimitive(target, locator, content); + } else if (target.isArray()) { + up = factory.createReplaceInArrayPrimitive(target, locator, content); + } else { + throw new OurBadException("Replace iterator cannot handle target items that are not objects or arrays"); + } + + pul.addUpdatePrimitive(up); + return pul; } } From cc92a9fbd73ac07fb43284e36ba119bb401dad57 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 8 May 2023 17:33:29 +0200 Subject: [PATCH 068/119] Update transform expr to copy, have scoped context, and not be updating, and implement PULs for Return --- .../compiler/DynamicContextVisitor.java | 32 +++++----- .../ExpressionClassificationVisitor.java | 4 +- .../compiler/RuntimeIteratorVisitor.java | 12 ++-- .../clauses/ReturnClauseSparkIterator.java | 62 +++++++++++++++++++ .../TransformExpressionIterator.java | 37 +++++++++-- 5 files changed, 120 insertions(+), 27 deletions(-) diff --git a/src/main/java/org/rumbledb/compiler/DynamicContextVisitor.java b/src/main/java/org/rumbledb/compiler/DynamicContextVisitor.java index 9464610d7e..0e724947e0 100644 --- a/src/main/java/org/rumbledb/compiler/DynamicContextVisitor.java +++ b/src/main/java/org/rumbledb/compiler/DynamicContextVisitor.java @@ -41,6 +41,7 @@ import org.rumbledb.expressions.AbstractNodeVisitor; import org.rumbledb.expressions.Expression; import org.rumbledb.expressions.Node; +import org.rumbledb.expressions.flowr.ReturnClause; import org.rumbledb.expressions.module.FunctionDeclaration; import org.rumbledb.expressions.module.LibraryModule; import org.rumbledb.expressions.module.Prolog; @@ -115,21 +116,22 @@ public DynamicContext visitFunctionDeclaration(FunctionDeclaration declaration, return defaultAction(expression, argument); } - @Override - public DynamicContext visitTransformExpression(TransformExpression expression, DynamicContext argument) { - - for (CopyDeclaration copyDecl : expression.getCopyDeclarations()) { - Expression child = copyDecl.getSourceExpression(); - RuntimeIterator iterator = VisitorHelpers.generateRuntimeIterator(child, this.configuration); - iterator.bindToVariableInDynamicContext(argument, copyDecl.getVariableName(), argument); - } - - this.visit(expression.getModifyExpression(), argument); - - this.visit(expression.getReturnExpression(), argument); - - return argument; - } +// @Override +// public DynamicContext visitTransformExpression(TransformExpression expression, DynamicContext argument) { +// +// for (CopyDeclaration copyDecl : expression.getCopyDeclarations()) { +// Expression child = copyDecl.getSourceExpression(); +// this.visit(child, argument); +// RuntimeIterator iterator = VisitorHelpers.generateRuntimeIterator(child, this.configuration); +// iterator.bindToVariableInDynamicContext(argument, copyDecl.getVariableName(), argument); +// } +// +// this.visit(expression.getModifyExpression(), argument); +// +// this.visit(expression.getReturnExpression(), argument); +// +// return argument; +// } @Override public DynamicContext visitVariableDeclaration(VariableDeclaration variableDeclaration, DynamicContext argument) { diff --git a/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java b/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java index ac62249090..940894cd41 100644 --- a/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java +++ b/src/main/java/org/rumbledb/compiler/ExpressionClassificationVisitor.java @@ -457,8 +457,8 @@ public ExpressionClassification visitTransformExpression( ); } - expression.setExpressionClassification(ExpressionClassification.BASIC_UPDATING); - return ExpressionClassification.BASIC_UPDATING; + expression.setExpressionClassification(ExpressionClassification.SIMPLE); + return ExpressionClassification.SIMPLE; } // Endregion diff --git a/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java b/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java index 73d8d51000..c02f176bbf 100644 --- a/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java +++ b/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java @@ -144,10 +144,7 @@ import org.rumbledb.types.BuiltinTypesCatalogue; import org.rumbledb.types.SequenceType; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; public class RuntimeIteratorVisitor extends AbstractNodeVisitor { @@ -219,6 +216,7 @@ public RuntimeIterator visitFlowrExpression(FlworExpression expression, RuntimeI (expression.getReturnClause()).getReturnExpr(), argument ), + expression.isUpdating(), expression.getReturnClause().getHighestExecutionMode(this.visitorConfig), expression.getReturnClause().getMetadata(), expression.getStaticSequenceType() @@ -438,6 +436,10 @@ public RuntimeIterator visitAppendExpression(AppendExpression expression, Runtim public RuntimeIterator visitTransformExpression(TransformExpression expression, RuntimeIterator argument) { List copyDeclIterators = new ArrayList<>(); + Map copyDeclMap = new HashMap<>(); + for (CopyDeclaration copyDecl : expression.getCopyDeclarations()) { + copyDeclMap.put(copyDecl.getVariableName(), this.visit(copyDecl.getSourceExpression(), argument)); + } for (Expression childExpr : expression.getCopySourceExpressions()) { copyDeclIterators.add(this.visit(childExpr, argument)); } @@ -445,7 +447,7 @@ public RuntimeIterator visitTransformExpression(TransformExpression expression, RuntimeIterator returnIterator = this.visit(expression.getReturnExpression(), argument); RuntimeIterator runtimeIterator = new TransformExpressionIterator( - copyDeclIterators, + copyDeclMap, modifyIterator, returnIterator, expression.getHighestExecutionMode(this.visitorConfig), diff --git a/src/main/java/org/rumbledb/runtime/flwor/clauses/ReturnClauseSparkIterator.java b/src/main/java/org/rumbledb/runtime/flwor/clauses/ReturnClauseSparkIterator.java index a6482c85fa..3f462e4ce6 100644 --- a/src/main/java/org/rumbledb/runtime/flwor/clauses/ReturnClauseSparkIterator.java +++ b/src/main/java/org/rumbledb/runtime/flwor/clauses/ReturnClauseSparkIterator.java @@ -20,6 +20,7 @@ package org.rumbledb.runtime.flwor.clauses; +import org.apache.hadoop.yarn.webapp.hamlet2.Hamlet; import org.apache.log4j.LogManager; import org.apache.spark.api.java.JavaRDD; import org.apache.spark.sql.Dataset; @@ -44,6 +45,7 @@ import org.rumbledb.runtime.flwor.NativeClauseContext; import org.rumbledb.runtime.flwor.closures.ReturnFlatMapClosure; import org.rumbledb.runtime.typing.ValidateTypeIterator; +import org.rumbledb.runtime.update.PendingUpdateList; import org.rumbledb.types.SequenceType; import sparksoniq.jsoniq.tuple.FlworTuple; @@ -72,6 +74,7 @@ public class ReturnClauseSparkIterator extends HybridRuntimeIterator { public ReturnClauseSparkIterator( RuntimeTupleIterator child, RuntimeIterator expression, + boolean isUpdating, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata, SequenceType sequenceType @@ -80,9 +83,20 @@ public ReturnClauseSparkIterator( this.child = child; this.expression = expression; this.sequenceType = sequenceType; + this.isUpdating = isUpdating; setInputAndOutputTupleVariableDependencies(); } + public ReturnClauseSparkIterator( + RuntimeTupleIterator child, + RuntimeIterator expression, + ExecutionMode executionMode, + ExceptionMetadata iteratorMetadata, + SequenceType sequenceType + ) { + this(child, expression, false, executionMode, iteratorMetadata, sequenceType); + } + @Override public JavaRDD getRDDAux(DynamicContext context) { RuntimeIterator expression = this.children.get(0); @@ -371,4 +385,52 @@ public static Dataset tryNativeQuery( return result; } + @Override + public PendingUpdateList getPendingUpdateList(DynamicContext context) { + if (!isUpdating()) { + return new PendingUpdateList(); + } + PendingUpdateList result = new PendingUpdateList(); + + if (!isRDDOrDataFrame()) { + this.child.open(context); + this.tupleContext = new DynamicContext(context); // assign current context + + while (this.child.hasNext()) { + FlworTuple tuple = this.child.next(); + this.tupleContext.getVariableValues().removeAllVariables(); // clear the previous variables + this.tupleContext.getVariableValues().setBindingsFromTuple(tuple, getMetadata()); // assign new variables + // from new tuple + + result = PendingUpdateList.mergeUpdates(result, this.expression.getPendingUpdateList(this.tupleContext)); + + } + this.child.close(); + return result; + + // execution reaches here when there are no more results + } + + RuntimeIterator expression = this.children.get(0); + if (expression.isRDDOrDataFrame()) { + if (this.child.isDataFrame()) + throw new JobWithinAJobException( + "A return clause expression cannot produce a big sequence of items for a big number of tuples, as this would lead to a data flow explosion.", + getMetadata() + ); + // context + this.child.open(context); + while (this.child.hasNext()) { + FlworTuple tuple = this.child.next(); + // We need a fresh context every time, because the evaluation of RDD is lazy. + DynamicContext dynamicContext = new DynamicContext(context); + dynamicContext.getVariableValues().setBindingsFromTuple(tuple, getMetadata()); // assign new variables + // from new tuple + + PendingUpdateList intermediateResult = this.expression.getPendingUpdateList(dynamicContext); + result = PendingUpdateList.mergeUpdates(result, intermediateResult); + } + } + return result; + } } diff --git a/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java index 78660bf40b..eb1d29c144 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java @@ -1,41 +1,53 @@ package org.rumbledb.runtime.update.expression; import org.apache.spark.api.java.JavaRDD; +import org.apache.commons.lang.SerializationUtils; import org.rumbledb.api.Item; +import org.rumbledb.compiler.VisitorHelpers; import org.rumbledb.context.DynamicContext; +import org.rumbledb.context.Name; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.expressions.Expression; +import org.rumbledb.expressions.update.CopyDeclaration; import org.rumbledb.runtime.HybridRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.update.PendingUpdateList; +import java.util.ArrayList; import java.util.List; +import java.util.Map; public class TransformExpressionIterator extends HybridRuntimeIterator { - private List copyDeclIterators; + private Map copyDeclMap; private RuntimeIterator modifyIterator; private RuntimeIterator returnIterator; - public TransformExpressionIterator(List copyDeclIterators, RuntimeIterator modifyIterator, RuntimeIterator returnIterator, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { + public TransformExpressionIterator(Map copyDeclMap, RuntimeIterator modifyIterator, RuntimeIterator returnIterator, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { super(null, executionMode, iteratorMetadata); - this.children.addAll(copyDeclIterators); + this.children.addAll(copyDeclMap.values()); this.children.add(modifyIterator); this.children.add(returnIterator); - this.copyDeclIterators = copyDeclIterators; + this.copyDeclMap = copyDeclMap; this.modifyIterator = modifyIterator; this.returnIterator = returnIterator; - this.isUpdating = true; +// this.updateContext = null; + this.isUpdating = false; } @Override protected JavaRDD getRDDAux(DynamicContext context) { + PendingUpdateList pul = getPendingUpdateList(context); + pul.applyUpdates(); return returnIterator.getRDD(context); } @Override protected void openLocal() { + PendingUpdateList pul = getPendingUpdateList(this.currentDynamicContextForLocalExecution); + pul.applyUpdates(); returnIterator.open(this.currentDynamicContextForLocalExecution); } @@ -46,6 +58,8 @@ protected void closeLocal() { @Override protected void resetLocal() { + PendingUpdateList pul = getPendingUpdateList(this.currentDynamicContextForLocalExecution); + pul.applyUpdates(); returnIterator.reset(this.currentDynamicContextForLocalExecution); } @@ -61,7 +75,20 @@ protected Item nextLocal() { @Override public PendingUpdateList getPendingUpdateList(DynamicContext context) { + bindCopyDeclarations(context); return modifyIterator.getPendingUpdateList(context); } + private void bindCopyDeclarations(DynamicContext context) { + for (Name copyVar : copyDeclMap.keySet()) { + RuntimeIterator copyIterator = copyDeclMap.get(copyVar); + List toCopy = copyIterator.materialize(context); + List copy = new ArrayList<>(); + for (Item item : toCopy) { + copy.add((Item) SerializationUtils.clone(item)); + } + context.getVariableValues().addVariableValue(copyVar, copy); + } + } + } From 5cb6e40a5d61056d6a31dcf497f13b20b8f68f4f Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 8 May 2023 18:07:18 +0200 Subject: [PATCH 069/119] Create simple test for updating type switch --- .../runtime/Updating/UpdatingTypeswitchExpression1.jq | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/test/resources/test_files/runtime/Updating/UpdatingTypeswitchExpression1.jq diff --git a/src/test/resources/test_files/runtime/Updating/UpdatingTypeswitchExpression1.jq b/src/test/resources/test_files/runtime/Updating/UpdatingTypeswitchExpression1.jq new file mode 100644 index 0000000000..840b8583fd --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/UpdatingTypeswitchExpression1.jq @@ -0,0 +1,9 @@ +(:JIQS: ShouldRun; Output="{ "b" : 2, "c" : 3, "a" : 4 }" :) +copy json $je := { "a" : 1, "b" : 2, "c" : 3 } +modify + typeswitch($je.a) + case boolean+ return replace json value of $je.a with false + case decimal return replace json value of $je.a with 4 + case string* return replace json value of $je.a with "not this" + default return () +return $je \ No newline at end of file From b14ae114f2377c6c8573ce4057fa425a75ec3dca Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 8 May 2023 18:07:37 +0200 Subject: [PATCH 070/119] Implement getPUL for typeswitch --- .../compiler/RuntimeIteratorVisitor.java | 1 + .../control/TypeswitchRuntimeIterator.java | 49 +++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java b/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java index c02f176bbf..c4a01e741b 100644 --- a/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java +++ b/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java @@ -1103,6 +1103,7 @@ public RuntimeIterator visitTypeSwitchExpression(TypeSwitchExpression expression this.visit(expression.getTestCondition(), argument), cases, defaultCase, + expression.isUpdating(), expression.getHighestExecutionMode(this.visitorConfig), expression.getMetadata() ); diff --git a/src/main/java/org/rumbledb/runtime/control/TypeswitchRuntimeIterator.java b/src/main/java/org/rumbledb/runtime/control/TypeswitchRuntimeIterator.java index 9a3aa848d3..86c55cff75 100644 --- a/src/main/java/org/rumbledb/runtime/control/TypeswitchRuntimeIterator.java +++ b/src/main/java/org/rumbledb/runtime/control/TypeswitchRuntimeIterator.java @@ -9,6 +9,7 @@ import org.rumbledb.runtime.HybridRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.typing.InstanceOfIterator; +import org.rumbledb.runtime.update.PendingUpdateList; import org.rumbledb.types.SequenceType; import java.util.Collections; @@ -28,6 +29,7 @@ public TypeswitchRuntimeIterator( RuntimeIterator test, List cases, TypeswitchRuntimeIteratorCase defaultCase, + boolean isUpdating, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata ) { @@ -41,9 +43,21 @@ public TypeswitchRuntimeIterator( this.testField = test; this.cases = cases; this.defaultCase = defaultCase; + this.isUpdating = isUpdating; this.matchingIterator = null; } + public TypeswitchRuntimeIterator( + RuntimeIterator test, + List cases, + TypeswitchRuntimeIteratorCase defaultCase, + ExecutionMode executionMode, + ExceptionMetadata iteratorMetadata + ) { + this(test, cases, defaultCase, false, executionMode, iteratorMetadata); + } + + @Override public void openLocal() { // this.matchingIterator is null at that point; @@ -174,4 +188,39 @@ public JavaRDD getRDDAux(DynamicContext dynamicContext) { return this.defaultCase.getReturnIterator().getRDD(dynamicContext); } + + @Override + public PendingUpdateList getPendingUpdateList(DynamicContext context) { + if (!isUpdating()) { + return new PendingUpdateList(); + } + + this.testValue = this.testField.materializeFirstItemOrNull(context); + RuntimeIterator localMatchingIterator; + + for (TypeswitchRuntimeIteratorCase typeSwitchCase : this.cases) { + localMatchingIterator = testTypeMatchAndReturnCorrespondingIterator(typeSwitchCase); + if (localMatchingIterator != null) { + if (typeSwitchCase.getVariableName() != null) { + context.getVariableValues() + .addVariableValue( + typeSwitchCase.getVariableName(), + Collections.singletonList(this.testValue) + ); + } + + return localMatchingIterator.getPendingUpdateList(context); + } + } + + if (this.defaultCase.getVariableName() != null) { + context.getVariableValues() + .addVariableValue( + this.defaultCase.getVariableName(), + Collections.singletonList(this.testValue) + ); + } + + return this.defaultCase.getReturnIterator().getPendingUpdateList(context); + } } From 61b129839dabe2e67f7a516ef5207bdc69d2dbf8 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 8 May 2023 18:55:31 +0200 Subject: [PATCH 071/119] Create simple test for If expr --- .../test_files/runtime/Updating/UpdatingIfExpr1.jq | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/test/resources/test_files/runtime/Updating/UpdatingIfExpr1.jq diff --git a/src/test/resources/test_files/runtime/Updating/UpdatingIfExpr1.jq b/src/test/resources/test_files/runtime/Updating/UpdatingIfExpr1.jq new file mode 100644 index 0000000000..bc3d653a45 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/UpdatingIfExpr1.jq @@ -0,0 +1,8 @@ +(:JIQS: ShouldRun; Output="{ "a" : 1, "b" : 2, "c" : 3 }" :) +copy json $je := {"a" : 1, "b" : 2} +modify if($je.c) + then + delete json $je.c + else + insert json "c" : 3 into $je +return $je From 7644fef8352f072b888fbdc7c93e9aa0190f6483 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 8 May 2023 18:55:57 +0200 Subject: [PATCH 072/119] Implement getPUL for IfRuntimeIterator --- .../compiler/RuntimeIteratorVisitor.java | 1 + .../runtime/control/IfRuntimeIterator.java | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java b/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java index c4a01e741b..7b3f95eb90 100644 --- a/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java +++ b/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java @@ -1051,6 +1051,7 @@ public RuntimeIterator visitConditionalExpression(ConditionalExpression expressi conditionIterator, thenIterator, elseIterator, + expression.isUpdating(), expression.getHighestExecutionMode(this.visitorConfig), expression.getMetadata() ); diff --git a/src/main/java/org/rumbledb/runtime/control/IfRuntimeIterator.java b/src/main/java/org/rumbledb/runtime/control/IfRuntimeIterator.java index 852ff162f1..48ce73c58b 100644 --- a/src/main/java/org/rumbledb/runtime/control/IfRuntimeIterator.java +++ b/src/main/java/org/rumbledb/runtime/control/IfRuntimeIterator.java @@ -29,6 +29,7 @@ import org.rumbledb.items.structured.JSoundDataFrame; import org.rumbledb.runtime.HybridRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; +import org.rumbledb.runtime.update.PendingUpdateList; public class IfRuntimeIterator extends HybridRuntimeIterator { @@ -40,6 +41,7 @@ public IfRuntimeIterator( RuntimeIterator condition, RuntimeIterator branch, RuntimeIterator elseBranch, + boolean isUpdating, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata ) { @@ -47,6 +49,17 @@ public IfRuntimeIterator( this.children.add(condition); this.children.add(branch); this.children.add(elseBranch); + this.isUpdating = isUpdating; + } + + public IfRuntimeIterator( + RuntimeIterator condition, + RuntimeIterator branch, + RuntimeIterator elseBranch, + ExecutionMode executionMode, + ExceptionMetadata iteratorMetadata + ) { + this(condition, branch, elseBranch, false, executionMode, iteratorMetadata); } @Override @@ -111,4 +124,14 @@ public JSoundDataFrame getDataFrame(DynamicContext dynamicContext) { return iterator.getDataFrame(dynamicContext); } + + @Override + public PendingUpdateList getPendingUpdateList(DynamicContext context) { + if (!isUpdating()) { + return new PendingUpdateList(); + } + + RuntimeIterator iterator = selectApplicableIterator(context); + return iterator.getPendingUpdateList(context); + } } From 62633674f61ec41cdcc4a7fb43faca986e77f179 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Fri, 19 May 2023 02:42:03 +0200 Subject: [PATCH 073/119] Refactor updating FLWOR tests --- .../test_files/runtime/Updating/TransformFLWOR1.jq | 6 ++++++ .../test_files/runtime/Updating/TransformFLWOR2.jq | 6 ++++++ .../{UpdatingFLWOR3.jq => TransformFLWOR3.jq} | 0 .../test_files/runtime/Updating/UpdatingFLWOR1.jq | 13 +++++++------ 4 files changed, 19 insertions(+), 6 deletions(-) create mode 100644 src/test/resources/test_files/runtime/Updating/TransformFLWOR1.jq create mode 100644 src/test/resources/test_files/runtime/Updating/TransformFLWOR2.jq rename src/test/resources/test_files/runtime/Updating/{UpdatingFLWOR3.jq => TransformFLWOR3.jq} (100%) diff --git a/src/test/resources/test_files/runtime/Updating/TransformFLWOR1.jq b/src/test/resources/test_files/runtime/Updating/TransformFLWOR1.jq new file mode 100644 index 0000000000..23362a38e6 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/TransformFLWOR1.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldRun; Output="{ "b" : 1 }" :) +let $a := {"a" : 1} +return + copy json $je := $a + modify rename json $je.a as "b" + return $je \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/TransformFLWOR2.jq b/src/test/resources/test_files/runtime/Updating/TransformFLWOR2.jq new file mode 100644 index 0000000000..f28cca4b63 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/TransformFLWOR2.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldRun; Output="({ "b" : 1 }, { "b" : 2 }, { "b" : 3 }, { "b" : 4 })" :) +for $a in ( {"a" : 1}, {"a" : 2}, {"a" : 3}, {"a" : 4} ) +return + copy json $je := $a + modify rename json $je.a as "b" + return $je \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/UpdatingFLWOR3.jq b/src/test/resources/test_files/runtime/Updating/TransformFLWOR3.jq similarity index 100% rename from src/test/resources/test_files/runtime/Updating/UpdatingFLWOR3.jq rename to src/test/resources/test_files/runtime/Updating/TransformFLWOR3.jq diff --git a/src/test/resources/test_files/runtime/Updating/UpdatingFLWOR1.jq b/src/test/resources/test_files/runtime/Updating/UpdatingFLWOR1.jq index 23362a38e6..1d2227f21c 100644 --- a/src/test/resources/test_files/runtime/Updating/UpdatingFLWOR1.jq +++ b/src/test/resources/test_files/runtime/Updating/UpdatingFLWOR1.jq @@ -1,6 +1,7 @@ -(:JIQS: ShouldRun; Output="{ "b" : 1 }" :) -let $a := {"a" : 1} -return - copy json $je := $a - modify rename json $je.a as "b" - return $je \ No newline at end of file +(:JIQS: ShouldRun; Output="{ "a" : { "b" : 1 } }" :) +copy json $je := { "a" : {"foo" : 1}} +modify + let $l := $je.a + return + rename json $l.foo as "b" +return $je \ No newline at end of file From 80e25dba85976f40ffa1f4dbc0a4f6dc052caa74 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Fri, 19 May 2023 18:46:58 +0200 Subject: [PATCH 074/119] Add original hashing to object hashcode --- .../java/org/rumbledb/items/ObjectItem.java | 9 ++++---- .../runtime/Updating/UpdatingFLWOR2.jq | 23 ++++++++++++++----- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/rumbledb/items/ObjectItem.java b/src/main/java/org/rumbledb/items/ObjectItem.java index a29b71decf..cb67a40da0 100644 --- a/src/main/java/org/rumbledb/items/ObjectItem.java +++ b/src/main/java/org/rumbledb/items/ObjectItem.java @@ -28,10 +28,8 @@ import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.types.BuiltinTypesCatalogue; import org.rumbledb.types.ItemType; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; + +import java.util.*; public class ObjectItem implements Item { @@ -152,6 +150,7 @@ public void putItemByKey(String s, Item value) { checkForDuplicateKeys(this.keys, ExceptionMetadata.EMPTY_METADATA); } + @Override public void removeItemByKey(String s) { if (this.keys.contains(s)) { int index = this.keys.indexOf(s); @@ -184,6 +183,7 @@ public int hashCode() { for (String s : getKeys()) { result += getItemByKey(s).hashCode(); } + result += System.identityHashCode(this); return result; } @@ -196,5 +196,4 @@ public ItemType getDynamicType() { public boolean getEffectiveBooleanValue() { return true; } - } diff --git a/src/test/resources/test_files/runtime/Updating/UpdatingFLWOR2.jq b/src/test/resources/test_files/runtime/Updating/UpdatingFLWOR2.jq index f28cca4b63..8f86c6538b 100644 --- a/src/test/resources/test_files/runtime/Updating/UpdatingFLWOR2.jq +++ b/src/test/resources/test_files/runtime/Updating/UpdatingFLWOR2.jq @@ -1,6 +1,17 @@ -(:JIQS: ShouldRun; Output="({ "b" : 1 }, { "b" : 2 }, { "b" : 3 }, { "b" : 4 })" :) -for $a in ( {"a" : 1}, {"a" : 2}, {"a" : 3}, {"a" : 4} ) -return - copy json $je := $a - modify rename json $je.a as "b" - return $je \ No newline at end of file +(:JIQS: ShouldRun; Output="({ "a" : { "bar" : 1 } }, { "b" : { "foo" : 2 } }, { "a" : { "bar" : 1 } }, { "b" : { "foo" : 2 } })" :) +copy json $je := for $i in (1 to 4) + return + if($i mod 2 eq 0) + then + {"b" : {"foo" : 1}} + else + {"a" : {"foo" : 1}} +modify + for $l in $je + return + if($l.a) + then + rename json $l.a.foo as "bar" + else + replace json value of $l.b.foo with 2 +return $je \ No newline at end of file From 724dbc173e97b1fe2e2654666703343bdc7b822d Mon Sep 17 00:00:00 2001 From: dloughlin Date: Fri, 19 May 2023 19:19:26 +0200 Subject: [PATCH 075/119] Refactor object hashcode to not use original hash and implement custom item comparator for PULs --- .../java/org/rumbledb/items/ObjectItem.java | 1 - .../runtime/update/PendingUpdateList.java | 21 ++++++++++++++----- .../runtime/Updating/UpdatingFLWOR3.jq | 12 +++++++++++ 3 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 src/test/resources/test_files/runtime/Updating/UpdatingFLWOR3.jq diff --git a/src/main/java/org/rumbledb/items/ObjectItem.java b/src/main/java/org/rumbledb/items/ObjectItem.java index cb67a40da0..3155bd9f7e 100644 --- a/src/main/java/org/rumbledb/items/ObjectItem.java +++ b/src/main/java/org/rumbledb/items/ObjectItem.java @@ -183,7 +183,6 @@ public int hashCode() { for (String s : getKeys()) { result += getItemByKey(s).hashCode(); } - result += System.identityHashCode(this); return result; } diff --git a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java index c5416316e1..593f3c6dd5 100644 --- a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java +++ b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java @@ -20,13 +20,24 @@ public class PendingUpdateList { private Map> delReplaceObjMap; private Map> delReplaceArrayMap; private Map> renameObjMap; + private Comparator targetComparator; public PendingUpdateList() { - this.insertObjMap = new HashMap<>(); - this.insertArrayMap = new HashMap<>(); - this.delReplaceObjMap = new HashMap<>(); - this.delReplaceArrayMap = new HashMap<>(); - this.renameObjMap = new HashMap<>(); + this.targetComparator = (item1, item2) -> { + int hashCompare = Integer.compare(item1.hashCode(), item2.hashCode()); + if (item1.hashCode() != item2.hashCode()) { + return hashCompare; + } + if (!item1.equals(item2)) { + return hashCompare; + } + return Integer.compare(System.identityHashCode(item1), System.identityHashCode(item2)); + }; + this.insertObjMap = new TreeMap<>(this.targetComparator); + this.insertArrayMap = new TreeMap<>(this.targetComparator); + this.delReplaceObjMap = new TreeMap<>(this.targetComparator); + this.delReplaceArrayMap = new TreeMap<>(this.targetComparator); + this.renameObjMap = new TreeMap<>(this.targetComparator); } public PendingUpdateList(UpdatePrimitive updatePrimitive) { diff --git a/src/test/resources/test_files/runtime/Updating/UpdatingFLWOR3.jq b/src/test/resources/test_files/runtime/Updating/UpdatingFLWOR3.jq new file mode 100644 index 0000000000..18919a5887 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/UpdatingFLWOR3.jq @@ -0,0 +1,12 @@ +(:JIQS: ShouldRun; Output="([ 0 ], [ 1 ], [ 0 ], [ 1 ])" :) +copy json $je := for $i in (1 to 4) + return [$i mod 2] +modify + for $l in $je + return + if($l[[1]] eq 0) + then + replace json value of $l[[1]] with 1 + else + replace json value of $l[[1]] with 0 +return $je \ No newline at end of file From 7f2680517ec239705c694cb7e6af1f09179a4301 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 22 May 2023 02:09:31 +0200 Subject: [PATCH 076/119] Add errorcodes and exception classes for unhandled exceptions --- .../org/rumbledb/errorcodes/ErrorCode.java | 15 ++++++++- .../CannotCastUpdateSelectorException.java | 32 +++++++++++++++++++ .../CannotResolveUpdateSelectorException.java | 32 +++++++++++++++++++ .../DeleteTargetNotSeqException.java | 32 +++++++++++++++++++ .../InvalidUpdateTargetException.java | 32 +++++++++++++++++++ ...tInsertContentIsNotObjectSeqException.java | 32 +++++++++++++++++++ .../RenameTargetBadNonEmptySeqException.java | 32 +++++++++++++++++++ .../ReplaceTargetBadNonEmptySeqException.java | 32 +++++++++++++++++++ .../TransformBadCopySourceException.java | 32 +++++++++++++++++++ ...nsformModifiesNonCopiedValueException.java | 32 +++++++++++++++++++ .../UpdateTargetIsEmptySeqException.java | 32 +++++++++++++++++++ 11 files changed, 334 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/rumbledb/exceptions/CannotCastUpdateSelectorException.java create mode 100644 src/main/java/org/rumbledb/exceptions/CannotResolveUpdateSelectorException.java create mode 100644 src/main/java/org/rumbledb/exceptions/DeleteTargetNotSeqException.java create mode 100644 src/main/java/org/rumbledb/exceptions/InvalidUpdateTargetException.java create mode 100644 src/main/java/org/rumbledb/exceptions/ObjectInsertContentIsNotObjectSeqException.java create mode 100644 src/main/java/org/rumbledb/exceptions/RenameTargetBadNonEmptySeqException.java create mode 100644 src/main/java/org/rumbledb/exceptions/ReplaceTargetBadNonEmptySeqException.java create mode 100644 src/main/java/org/rumbledb/exceptions/TransformBadCopySourceException.java create mode 100644 src/main/java/org/rumbledb/exceptions/TransformModifiesNonCopiedValueException.java create mode 100644 src/main/java/org/rumbledb/exceptions/UpdateTargetIsEmptySeqException.java diff --git a/src/main/java/org/rumbledb/errorcodes/ErrorCode.java b/src/main/java/org/rumbledb/errorcodes/ErrorCode.java index 8c13473945..2fb3c69411 100644 --- a/src/main/java/org/rumbledb/errorcodes/ErrorCode.java +++ b/src/main/java/org/rumbledb/errorcodes/ErrorCode.java @@ -125,10 +125,23 @@ public enum ErrorCode { InvalidUpdatingExpressionPositionErrorCode("XUST0001"), SimpleExpressionMustBeVacuousErrorCode("XUST0002"), + DeleteTargetNotSequence("XUTY0007"), + ReplaceTargetBadNonEmptySequence("XUTY0008"), + RenameTargetBadNonEmptySequence("XUTY0012"), + TransformBadCopySource("XUTY0013"), + + + TransformModifiesNonCopiedValue("XUDY0014"), + UpdateTargetIsEmptySeqErrorCode("XUDY0027"), + DuplicateObjectInsertSourceErrorCode("JNUP0005"), DuplicateKeyOnUpdateApplyErrorCode("JNUP0006"), + CannotCastUpdateSelectorErrorCode("JNUP0007"), + InvalidUpdateTargetErrorCode("JNUP0008"), TooManyReplacesOnSameTargetSelectorErrorCode("JNUP0009"), - TooManyRenamesOnSameTargetSelectorErrorCode("JNUP0010"); + TooManyRenamesOnSameTargetSelectorErrorCode("JNUP0010"), + CannotResolveUpdateSelectorErrorCode("JNUP0016"), + ObjectInsertContentIsNotObjectSeqErrorCode("JNUP0019"); diff --git a/src/main/java/org/rumbledb/exceptions/CannotCastUpdateSelectorException.java b/src/main/java/org/rumbledb/exceptions/CannotCastUpdateSelectorException.java new file mode 100644 index 0000000000..34b0dcbcfd --- /dev/null +++ b/src/main/java/org/rumbledb/exceptions/CannotCastUpdateSelectorException.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 CannotCastUpdateSelectorException extends RumbleException { + + private static final long serialVersionUID = 1L; + + public CannotCastUpdateSelectorException(String message, ExceptionMetadata metadata) { + super(message, ErrorCode.CannotCastUpdateSelectorErrorCode, metadata); + } +} diff --git a/src/main/java/org/rumbledb/exceptions/CannotResolveUpdateSelectorException.java b/src/main/java/org/rumbledb/exceptions/CannotResolveUpdateSelectorException.java new file mode 100644 index 0000000000..b1a6b7c603 --- /dev/null +++ b/src/main/java/org/rumbledb/exceptions/CannotResolveUpdateSelectorException.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 CannotResolveUpdateSelectorException extends RumbleException { + + private static final long serialVersionUID = 1L; + + public CannotResolveUpdateSelectorException(String message, ExceptionMetadata metadata) { + super(message, ErrorCode.CannotResolveUpdateSelectorErrorCode, metadata); + } +} diff --git a/src/main/java/org/rumbledb/exceptions/DeleteTargetNotSeqException.java b/src/main/java/org/rumbledb/exceptions/DeleteTargetNotSeqException.java new file mode 100644 index 0000000000..bb9c4f05e2 --- /dev/null +++ b/src/main/java/org/rumbledb/exceptions/DeleteTargetNotSeqException.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 DeleteTargetNotSeqException extends RumbleException { + + private static final long serialVersionUID = 1L; + + public DeleteTargetNotSeqException(String message, ExceptionMetadata metadata) { + super(message, ErrorCode.DeleteTargetNotSequence, metadata); + } +} diff --git a/src/main/java/org/rumbledb/exceptions/InvalidUpdateTargetException.java b/src/main/java/org/rumbledb/exceptions/InvalidUpdateTargetException.java new file mode 100644 index 0000000000..c407ee559d --- /dev/null +++ b/src/main/java/org/rumbledb/exceptions/InvalidUpdateTargetException.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 InvalidUpdateTargetException extends RumbleException { + + private static final long serialVersionUID = 1L; + + public InvalidUpdateTargetException(String message, ExceptionMetadata metadata) { + super(message, ErrorCode.InvalidUpdateTargetErrorCode, metadata); + } +} diff --git a/src/main/java/org/rumbledb/exceptions/ObjectInsertContentIsNotObjectSeqException.java b/src/main/java/org/rumbledb/exceptions/ObjectInsertContentIsNotObjectSeqException.java new file mode 100644 index 0000000000..96dabf2a18 --- /dev/null +++ b/src/main/java/org/rumbledb/exceptions/ObjectInsertContentIsNotObjectSeqException.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 ObjectInsertContentIsNotObjectSeqException extends RumbleException { + + private static final long serialVersionUID = 1L; + + public ObjectInsertContentIsNotObjectSeqException(String message, ExceptionMetadata metadata) { + super(message, ErrorCode.ObjectInsertContentIsNotObjectSeqErrorCode, metadata); + } +} diff --git a/src/main/java/org/rumbledb/exceptions/RenameTargetBadNonEmptySeqException.java b/src/main/java/org/rumbledb/exceptions/RenameTargetBadNonEmptySeqException.java new file mode 100644 index 0000000000..e568af9638 --- /dev/null +++ b/src/main/java/org/rumbledb/exceptions/RenameTargetBadNonEmptySeqException.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 RenameTargetBadNonEmptySeqException extends RumbleException { + + private static final long serialVersionUID = 1L; + + public RenameTargetBadNonEmptySeqException(String message, ExceptionMetadata metadata) { + super(message, ErrorCode.RenameTargetBadNonEmptySequence, metadata); + } +} diff --git a/src/main/java/org/rumbledb/exceptions/ReplaceTargetBadNonEmptySeqException.java b/src/main/java/org/rumbledb/exceptions/ReplaceTargetBadNonEmptySeqException.java new file mode 100644 index 0000000000..af5529d04d --- /dev/null +++ b/src/main/java/org/rumbledb/exceptions/ReplaceTargetBadNonEmptySeqException.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 ReplaceTargetBadNonEmptySeqException extends RumbleException { + + private static final long serialVersionUID = 1L; + + public ReplaceTargetBadNonEmptySeqException(String message, ExceptionMetadata metadata) { + super(message, ErrorCode.ReplaceTargetBadNonEmptySequence, metadata); + } +} diff --git a/src/main/java/org/rumbledb/exceptions/TransformBadCopySourceException.java b/src/main/java/org/rumbledb/exceptions/TransformBadCopySourceException.java new file mode 100644 index 0000000000..91cb324c95 --- /dev/null +++ b/src/main/java/org/rumbledb/exceptions/TransformBadCopySourceException.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 TransformBadCopySourceException extends RumbleException { + + private static final long serialVersionUID = 1L; + + public TransformBadCopySourceException(String message, ExceptionMetadata metadata) { + super(message, ErrorCode.TransformBadCopySource, metadata); + } +} diff --git a/src/main/java/org/rumbledb/exceptions/TransformModifiesNonCopiedValueException.java b/src/main/java/org/rumbledb/exceptions/TransformModifiesNonCopiedValueException.java new file mode 100644 index 0000000000..0d425cc2bf --- /dev/null +++ b/src/main/java/org/rumbledb/exceptions/TransformModifiesNonCopiedValueException.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 TransformModifiesNonCopiedValueException extends RumbleException { + + private static final long serialVersionUID = 1L; + + public TransformModifiesNonCopiedValueException(String message, ExceptionMetadata metadata) { + super(message, ErrorCode.TransformModifiesNonCopiedValue, metadata); + } +} diff --git a/src/main/java/org/rumbledb/exceptions/UpdateTargetIsEmptySeqException.java b/src/main/java/org/rumbledb/exceptions/UpdateTargetIsEmptySeqException.java new file mode 100644 index 0000000000..9ee42d6e3e --- /dev/null +++ b/src/main/java/org/rumbledb/exceptions/UpdateTargetIsEmptySeqException.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 UpdateTargetIsEmptySeqException extends RumbleException { + + private static final long serialVersionUID = 1L; + + public UpdateTargetIsEmptySeqException(String message, ExceptionMetadata metadata) { + super(message, ErrorCode.UpdateTargetIsEmptySeqErrorCode, metadata); + } +} From 7dcf8e683d7952bcba1b519291e90523d22a5b50 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 22 May 2023 02:10:17 +0200 Subject: [PATCH 077/119] Add error tests for XUST0001 --- .../test_files/runtime/Updating/SimpleDeleteErr1.jq | 6 ++++++ .../test_files/runtime/Updating/SimpleInsertErr1.jq | 6 ++++++ .../test_files/runtime/Updating/SimpleInsertErr2.jq | 6 ++++++ .../test_files/runtime/Updating/SimpleRenameErr1.jq | 6 ++++++ .../test_files/runtime/Updating/SimpleRenameErr2.jq | 6 ++++++ .../test_files/runtime/Updating/SimpleReplaceErr1.jq | 6 ++++++ .../test_files/runtime/Updating/SimpleReplaceErr2.jq | 6 ++++++ .../runtime/Updating/SimpleTransformErr1.jq | 6 ++++++ .../runtime/Updating/SimpleTransformErr2.jq | 6 ++++++ .../runtime/Updating/UpdatingCommaExpressionErr1.jq | 6 ++++++ .../test_files/runtime/Updating/UpdatingFLWORErr1.jq | 9 +++++++++ .../test_files/runtime/Updating/UpdatingFLWORErr2.jq | 10 ++++++++++ .../test_files/runtime/Updating/UpdatingFLWORErr3.jq | 11 +++++++++++ .../test_files/runtime/Updating/UpdatingFLWORErr4.jq | 11 +++++++++++ .../test_files/runtime/Updating/UpdatingIfExprErr1.jq | 10 ++++++++++ .../test_files/runtime/Updating/UpdatingIfExprErr2.jq | 10 ++++++++++ .../test_files/runtime/Updating/UpdatingOtherErr1.jq | 11 +++++++++++ .../Updating/UpdatingTypeswitchExpressionErr1.jq | 11 +++++++++++ .../Updating/UpdatingTypeswitchExpressionErr2.jq | 11 +++++++++++ 19 files changed, 154 insertions(+) create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleDeleteErr1.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleInsertErr1.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleInsertErr2.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleRenameErr1.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleRenameErr2.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleReplaceErr1.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleReplaceErr2.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleTransformErr1.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleTransformErr2.jq create mode 100644 src/test/resources/test_files/runtime/Updating/UpdatingCommaExpressionErr1.jq create mode 100644 src/test/resources/test_files/runtime/Updating/UpdatingFLWORErr1.jq create mode 100644 src/test/resources/test_files/runtime/Updating/UpdatingFLWORErr2.jq create mode 100644 src/test/resources/test_files/runtime/Updating/UpdatingFLWORErr3.jq create mode 100644 src/test/resources/test_files/runtime/Updating/UpdatingFLWORErr4.jq create mode 100644 src/test/resources/test_files/runtime/Updating/UpdatingIfExprErr1.jq create mode 100644 src/test/resources/test_files/runtime/Updating/UpdatingIfExprErr2.jq create mode 100644 src/test/resources/test_files/runtime/Updating/UpdatingOtherErr1.jq create mode 100644 src/test/resources/test_files/runtime/Updating/UpdatingTypeswitchExpressionErr1.jq create mode 100644 src/test/resources/test_files/runtime/Updating/UpdatingTypeswitchExpressionErr2.jq diff --git a/src/test/resources/test_files/runtime/Updating/SimpleDeleteErr1.jq b/src/test/resources/test_files/runtime/Updating/SimpleDeleteErr1.jq new file mode 100644 index 0000000000..a76c4325b0 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleDeleteErr1.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="XUST0001"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := [1 to 4] +modify delete json (delete json $je[[1]])[[1]] +return $je + +(: source expr is not simple :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleInsertErr1.jq b/src/test/resources/test_files/runtime/Updating/SimpleInsertErr1.jq new file mode 100644 index 0000000000..92e70e81c6 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleInsertErr1.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="XUST0001"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := [1 to 4] +modify insert json (insert json 5 into $je at position 4) into $je at position 4 +return $je + +(: source expr is not simple :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleInsertErr2.jq b/src/test/resources/test_files/runtime/Updating/SimpleInsertErr2.jq new file mode 100644 index 0000000000..f97efd438e --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleInsertErr2.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="XUST0001"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := [1 to 4] +modify insert json 5 into (insert json 5 into $je at position 4) at position 4 +return $je + +(: target expr is not simple :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleRenameErr1.jq b/src/test/resources/test_files/runtime/Updating/SimpleRenameErr1.jq new file mode 100644 index 0000000000..246d808234 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleRenameErr1.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="XUST0001"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := {"foo": "bar", "foobar": "barfoo"} +modify rename json (rename json $je.foo as "bar").foo as "bar" +return $je + +(: target expr is not simple :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleRenameErr2.jq b/src/test/resources/test_files/runtime/Updating/SimpleRenameErr2.jq new file mode 100644 index 0000000000..bd1dfe8a43 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleRenameErr2.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="XUST0001"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := {"foo": "bar", "foobar": "barfoo"} +modify rename json $je.foo as (rename json $je.foo as "bar") +return $je + +(: source expr is not simple :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleReplaceErr1.jq b/src/test/resources/test_files/runtime/Updating/SimpleReplaceErr1.jq new file mode 100644 index 0000000000..104d0d563d --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleReplaceErr1.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="XUST0001"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := {"foo": "bar", "foobar": "barfoo"} +modify replace json value of $je.foo with (replace json value of $je.foo with "foo") +return $je + +(: source expr is not simple :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleReplaceErr2.jq b/src/test/resources/test_files/runtime/Updating/SimpleReplaceErr2.jq new file mode 100644 index 0000000000..12efb7776c --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleReplaceErr2.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="XUST0001"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := {"foo": "bar", "foobar": "barfoo"} +modify replace json value of (replace json value of $je.foo with "foo").foo with "foo" +return $je + +(: target expr is not simple :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleTransformErr1.jq b/src/test/resources/test_files/runtime/Updating/SimpleTransformErr1.jq new file mode 100644 index 0000000000..7f6b7c251c --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleTransformErr1.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="XUST0001"; ErrorMetadata="LINE:2:COLUMN:0:" :) +copy json $je := rename json {"bar" : 1}.bar as "bar" +modify rename json $je.foo as "bar" +return $je + +(: source expr is not simple :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleTransformErr2.jq b/src/test/resources/test_files/runtime/Updating/SimpleTransformErr2.jq new file mode 100644 index 0000000000..da1f19b81d --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleTransformErr2.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="XUST0001"; ErrorMetadata="LINE:2:COLUMN:0:" :) +copy json $je := {"foo" : 1} +modify rename json $je.foo as "bar" +return rename json {"bar" : 1}.bar as "bar" + +(: return expr is not simple :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/UpdatingCommaExpressionErr1.jq b/src/test/resources/test_files/runtime/Updating/UpdatingCommaExpressionErr1.jq new file mode 100644 index 0000000000..4089ceb660 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/UpdatingCommaExpressionErr1.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="XUST0001"; ErrorMetadata="LINE:3:COLUMN:8:" :) +copy json $je := [1 to 4] +modify (3, delete json $je[[1]], delete json $je[[2]]) +return $je + +(: at least one expr is not simple :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/UpdatingFLWORErr1.jq b/src/test/resources/test_files/runtime/Updating/UpdatingFLWORErr1.jq new file mode 100644 index 0000000000..71abe65c7b --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/UpdatingFLWORErr1.jq @@ -0,0 +1,9 @@ +(:JIQS: ShouldCrash; ErrorCode="XUST0001"; ErrorMetadata="LINE:4:COLUMN:8:" :) +copy json $je := { "a" : {"foo" : 1}} +modify + let $l := rename json $je.a.foo as "b" + return + rename json $l.foo as "b" +return $je + +(: expr in let clause is not simple :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/UpdatingFLWORErr2.jq b/src/test/resources/test_files/runtime/Updating/UpdatingFLWORErr2.jq new file mode 100644 index 0000000000..551ed9858f --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/UpdatingFLWORErr2.jq @@ -0,0 +1,10 @@ +(:JIQS: ShouldCrash; ErrorCode="XUST0001"; ErrorMetadata="LINE:5:COLUMN:8:" :) +copy json $je := for $i in (1 to 4) + return [$i mod 2] +modify + for $l in replace json value of [2,2,3][[1]] with 1 + return + replace json value of $l[[1]] with 1 +return $je + +(: expr in for clause is not simple :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/UpdatingFLWORErr3.jq b/src/test/resources/test_files/runtime/Updating/UpdatingFLWORErr3.jq new file mode 100644 index 0000000000..ce128561d8 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/UpdatingFLWORErr3.jq @@ -0,0 +1,11 @@ +(:JIQS: ShouldCrash; ErrorCode="XUST0001"; ErrorMetadata="LINE:6:COLUMN:4:" :) +copy json $je := for $i in (1 to 4) + return [$i mod 2] +modify + for $l in $je + where replace json value of $l[[1]] with 1 + return + replace json value of $l[[1]] with 1 +return $je + +(: expr in where clause is not simple :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/UpdatingFLWORErr4.jq b/src/test/resources/test_files/runtime/Updating/UpdatingFLWORErr4.jq new file mode 100644 index 0000000000..db44c01546 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/UpdatingFLWORErr4.jq @@ -0,0 +1,11 @@ +(:JIQS: ShouldCrash; ErrorCode="XUST0001"; ErrorMetadata="LINE:6:COLUMN:4:" :) +copy json $je := for $i in (1 to 4) + return [$i mod 2] +modify + for $l in $je + order by replace json value of $l[[1]] with 1 + return + replace json value of $l[[1]] with 1 +return $je + +(: expr in order by clause is not simple :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/UpdatingIfExprErr1.jq b/src/test/resources/test_files/runtime/Updating/UpdatingIfExprErr1.jq new file mode 100644 index 0000000000..2cd6df152e --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/UpdatingIfExprErr1.jq @@ -0,0 +1,10 @@ +(:JIQS: ShouldCrash; ErrorCode="XUST0001"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := {"a" : 1, "b" : 2} +modify if(delete json $je.c) + then + delete json $je.c + else + insert json "c" : 3 into $je +return $je + +(: expr in if clause is not simple :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/UpdatingIfExprErr2.jq b/src/test/resources/test_files/runtime/Updating/UpdatingIfExprErr2.jq new file mode 100644 index 0000000000..ee1f0e2fe9 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/UpdatingIfExprErr2.jq @@ -0,0 +1,10 @@ +(:JIQS: ShouldCrash; ErrorCode="XUST0001"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := {"a" : 1, "b" : 2} +modify if(delete json $je.c) + then + delete json $je.c + else + 3 +return $je + +(: one branch expr is not simple :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/UpdatingOtherErr1.jq b/src/test/resources/test_files/runtime/Updating/UpdatingOtherErr1.jq new file mode 100644 index 0000000000..f6e4603f28 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/UpdatingOtherErr1.jq @@ -0,0 +1,11 @@ +(:JIQS: ShouldCrash; ErrorCode="XUST0001"; ErrorMetadata="LINE:4:COLUMN:4:" :) +copy json $je := { "a" : 1, "b" : 2, "c" : 3 } +modify + switch($je.a) + case 1 return replace json value of $je.a with false + case 2 return replace json value of $je.a with 4 + case 3 return replace json value of $je.a with "not this" + default return () +return $je + +(: switch cannot house updating exprs :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/UpdatingTypeswitchExpressionErr1.jq b/src/test/resources/test_files/runtime/Updating/UpdatingTypeswitchExpressionErr1.jq new file mode 100644 index 0000000000..7f5d16b946 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/UpdatingTypeswitchExpressionErr1.jq @@ -0,0 +1,11 @@ +(:JIQS: ShouldCrash; ErrorCode="XUST0001"; ErrorMetadata="LINE:4:COLUMN:4:" :) +copy json $je := { "a" : 1, "b" : 2, "c" : 3 } +modify + typeswitch(replace json value of $je.a with 4) + case boolean+ return replace json value of $je.a with false + case decimal return replace json value of $je.a with 4 + case string* return replace json value of $je.a with "not this" + default return () +return $je + +(: typeswitch condition expr is not simple :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/UpdatingTypeswitchExpressionErr2.jq b/src/test/resources/test_files/runtime/Updating/UpdatingTypeswitchExpressionErr2.jq new file mode 100644 index 0000000000..c55cb45cc0 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/UpdatingTypeswitchExpressionErr2.jq @@ -0,0 +1,11 @@ +(:JIQS: ShouldCrash; ErrorCode="XUST0001"; ErrorMetadata="LINE:4:COLUMN:4:" :) +copy json $je := { "a" : 1, "b" : 2, "c" : 3 } +modify + typeswitch($je.a) + case boolean+ return replace json value of $je.a with false + case decimal return 4 + case string* return replace json value of $je.a with "not this" + default return () +return $je + +(: at least one branch expr is not simple :) \ No newline at end of file From 7dd0cce06ae292727e1122f452d75cee021eec3d Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 22 May 2023 02:19:25 +0200 Subject: [PATCH 078/119] Remove redundant error codes and exceptions --- .../org/rumbledb/errorcodes/ErrorCode.java | 3 -- .../DeleteTargetNotSeqException.java | 32 ------------------- .../RenameTargetBadNonEmptySeqException.java | 32 ------------------- .../ReplaceTargetBadNonEmptySeqException.java | 32 ------------------- 4 files changed, 99 deletions(-) delete mode 100644 src/main/java/org/rumbledb/exceptions/DeleteTargetNotSeqException.java delete mode 100644 src/main/java/org/rumbledb/exceptions/RenameTargetBadNonEmptySeqException.java delete mode 100644 src/main/java/org/rumbledb/exceptions/ReplaceTargetBadNonEmptySeqException.java diff --git a/src/main/java/org/rumbledb/errorcodes/ErrorCode.java b/src/main/java/org/rumbledb/errorcodes/ErrorCode.java index 2fb3c69411..a143cc31ec 100644 --- a/src/main/java/org/rumbledb/errorcodes/ErrorCode.java +++ b/src/main/java/org/rumbledb/errorcodes/ErrorCode.java @@ -125,9 +125,6 @@ public enum ErrorCode { InvalidUpdatingExpressionPositionErrorCode("XUST0001"), SimpleExpressionMustBeVacuousErrorCode("XUST0002"), - DeleteTargetNotSequence("XUTY0007"), - ReplaceTargetBadNonEmptySequence("XUTY0008"), - RenameTargetBadNonEmptySequence("XUTY0012"), TransformBadCopySource("XUTY0013"), diff --git a/src/main/java/org/rumbledb/exceptions/DeleteTargetNotSeqException.java b/src/main/java/org/rumbledb/exceptions/DeleteTargetNotSeqException.java deleted file mode 100644 index bb9c4f05e2..0000000000 --- a/src/main/java/org/rumbledb/exceptions/DeleteTargetNotSeqException.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 DeleteTargetNotSeqException extends RumbleException { - - private static final long serialVersionUID = 1L; - - public DeleteTargetNotSeqException(String message, ExceptionMetadata metadata) { - super(message, ErrorCode.DeleteTargetNotSequence, metadata); - } -} diff --git a/src/main/java/org/rumbledb/exceptions/RenameTargetBadNonEmptySeqException.java b/src/main/java/org/rumbledb/exceptions/RenameTargetBadNonEmptySeqException.java deleted file mode 100644 index e568af9638..0000000000 --- a/src/main/java/org/rumbledb/exceptions/RenameTargetBadNonEmptySeqException.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 RenameTargetBadNonEmptySeqException extends RumbleException { - - private static final long serialVersionUID = 1L; - - public RenameTargetBadNonEmptySeqException(String message, ExceptionMetadata metadata) { - super(message, ErrorCode.RenameTargetBadNonEmptySequence, metadata); - } -} diff --git a/src/main/java/org/rumbledb/exceptions/ReplaceTargetBadNonEmptySeqException.java b/src/main/java/org/rumbledb/exceptions/ReplaceTargetBadNonEmptySeqException.java deleted file mode 100644 index af5529d04d..0000000000 --- a/src/main/java/org/rumbledb/exceptions/ReplaceTargetBadNonEmptySeqException.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 ReplaceTargetBadNonEmptySeqException extends RumbleException { - - private static final long serialVersionUID = 1L; - - public ReplaceTargetBadNonEmptySeqException(String message, ExceptionMetadata metadata) { - super(message, ErrorCode.ReplaceTargetBadNonEmptySequence, metadata); - } -} From 7398da96fe987285e9d491b28b0b500e319cebcd Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 22 May 2023 02:19:41 +0200 Subject: [PATCH 079/119] Add tests for XUST0002 --- .../test_files/runtime/Updating/SimpleTransformErr3.jq | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleTransformErr3.jq diff --git a/src/test/resources/test_files/runtime/Updating/SimpleTransformErr3.jq b/src/test/resources/test_files/runtime/Updating/SimpleTransformErr3.jq new file mode 100644 index 0000000000..684458c588 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleTransformErr3.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="XUST0002"; ErrorMetadata="LINE:2:COLUMN:0:" :) +copy json $je := {"foo" : 1} +modify 3 +return $je + +(: modify expr is simple :) \ No newline at end of file From 26be43a44e8cec73d9d436af046c80bc0e7ea589 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 22 May 2023 02:26:01 +0200 Subject: [PATCH 080/119] Add tests for XUDY0027 --- .../test_files/runtime/Updating/SimpleInsertErr3.jq | 6 ++++++ .../test_files/runtime/Updating/SimpleRenameErr3.jq | 6 ++++++ .../test_files/runtime/Updating/SimpleReplaceErr3.jq | 6 ++++++ 3 files changed, 18 insertions(+) create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleInsertErr3.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleRenameErr3.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleReplaceErr3.jq diff --git a/src/test/resources/test_files/runtime/Updating/SimpleInsertErr3.jq b/src/test/resources/test_files/runtime/Updating/SimpleInsertErr3.jq new file mode 100644 index 0000000000..3c4d65196e --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleInsertErr3.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="XUDY0027"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := [1 to 4] +modify insert json 5 into () at position 4 +return $je + +(: target expr is empty seq :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleRenameErr3.jq b/src/test/resources/test_files/runtime/Updating/SimpleRenameErr3.jq new file mode 100644 index 0000000000..92d4685f76 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleRenameErr3.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="XUDY0027"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := {"foo": "bar", "foobar": "barfoo"} +modify rename json ().foo as "bar" +return $je + +(: target expr is empty seq :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleReplaceErr3.jq b/src/test/resources/test_files/runtime/Updating/SimpleReplaceErr3.jq new file mode 100644 index 0000000000..979187a3e3 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleReplaceErr3.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="XUDY0027"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := {"foo": "bar", "foobar": "barfoo"} +modify replace json value of ().foo with "foo" +return $je + +(: target expr is empty seq :) \ No newline at end of file From b5d6eaa9e8f5c4519384599525c86ab0d3ade5a1 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 22 May 2023 02:26:19 +0200 Subject: [PATCH 081/119] Implement exception throws for XUDY0027 --- .../update/expression/InsertExpressionIterator.java | 9 ++++----- .../update/expression/RenameExpressionIterator.java | 9 ++++----- .../update/expression/ReplaceExpressionIterator.java | 9 ++++----- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java index 588bf982a3..c069970855 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java @@ -3,10 +3,7 @@ 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.MoreThanOneItemException; -import org.rumbledb.exceptions.NoItemException; -import org.rumbledb.exceptions.OurBadException; +import org.rumbledb.exceptions.*; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.runtime.HybridRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; @@ -87,7 +84,9 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { if (this.hasPositionIterator()) { locator = this.positionIterator.materializeExactlyOneItem(context); } - } catch (NoItemException | MoreThanOneItemException e) { + } catch (NoItemException e) { + throw new UpdateTargetIsEmptySeqException("Target of insert expression is empty", this.getMetadata()); + } catch (MoreThanOneItemException e) { throw new RuntimeException(e); } diff --git a/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java index ba06c4c51d..fc86db1f57 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java @@ -3,10 +3,7 @@ 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.MoreThanOneItemException; -import org.rumbledb.exceptions.NoItemException; -import org.rumbledb.exceptions.OurBadException; +import org.rumbledb.exceptions.*; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.HybridRuntimeIterator; @@ -75,7 +72,9 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { target = this.mainIterator.materializeExactlyOneItem(context); locator = this.locatorIterator.materializeExactlyOneItem(context); content = this.nameIterator.materializeExactlyOneItem(context); - } catch (NoItemException | MoreThanOneItemException e) { + } catch (NoItemException e) { + throw new UpdateTargetIsEmptySeqException("Target of rename expression is empty", this.getMetadata()); + } catch (MoreThanOneItemException e) { throw new RuntimeException(e); } diff --git a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java index 66c9d7839d..f67e931fd5 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java @@ -3,10 +3,7 @@ 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.MoreThanOneItemException; -import org.rumbledb.exceptions.NoItemException; -import org.rumbledb.exceptions.OurBadException; +import org.rumbledb.exceptions.*; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.runtime.HybridRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; @@ -73,7 +70,9 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { target = this.mainIterator.materializeExactlyOneItem(context); locator = this.locatorIterator.materializeExactlyOneItem(context); content = this.replacerIterator.materializeExactlyOneItem(context); - } catch (NoItemException | MoreThanOneItemException e) { + } catch (NoItemException e) { + throw new UpdateTargetIsEmptySeqException("Target of replace expression is empty", this.getMetadata()); + } catch (MoreThanOneItemException e) { throw new RuntimeException(e); } From 8b1aa14db794cf04ad732b6c0c19577d585b5f40 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 22 May 2023 02:35:40 +0200 Subject: [PATCH 082/119] Create test for JNUP0005 --- .../resources/test_files/runtime/Updating/PULMergeErr1.jq | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/test/resources/test_files/runtime/Updating/PULMergeErr1.jq diff --git a/src/test/resources/test_files/runtime/Updating/PULMergeErr1.jq b/src/test/resources/test_files/runtime/Updating/PULMergeErr1.jq new file mode 100644 index 0000000000..ec035042a7 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/PULMergeErr1.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="JNUP0005"; ErrorMetadata="LINE:3:COLUMN:8:" :) +copy json $je := { "a" : 1, "b" : 2, "c" : 3 } +modify (insert json "foobar": "barfoo" into $je, insert json "foobar": "barfoo" into $je) +return $je + +(: insert same key into same object :) \ No newline at end of file From a6f204bac2610cfadaddd2b646d2f5dc6588c9c6 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 22 May 2023 02:36:05 +0200 Subject: [PATCH 083/119] Implement error throw for JNUP0005 --- .../java/org/rumbledb/runtime/CommaExpressionIterator.java | 2 +- .../runtime/flwor/clauses/ReturnClauseSparkIterator.java | 4 ++-- .../org/rumbledb/runtime/update/PendingUpdateList.java | 4 ++-- .../update/primitives/InsertIntoObjectPrimitive.java | 7 +++---- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/CommaExpressionIterator.java b/src/main/java/org/rumbledb/runtime/CommaExpressionIterator.java index 11cf9c648d..6cbb301aad 100644 --- a/src/main/java/org/rumbledb/runtime/CommaExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/CommaExpressionIterator.java @@ -159,7 +159,7 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { PendingUpdateList pul = new PendingUpdateList(); for (RuntimeIterator child : children) { - pul = PendingUpdateList.mergeUpdates(pul, child.getPendingUpdateList(context)); + pul = PendingUpdateList.mergeUpdates(pul, child.getPendingUpdateList(context), this.getMetadata()); } return pul; } diff --git a/src/main/java/org/rumbledb/runtime/flwor/clauses/ReturnClauseSparkIterator.java b/src/main/java/org/rumbledb/runtime/flwor/clauses/ReturnClauseSparkIterator.java index 3f462e4ce6..fe6b670668 100644 --- a/src/main/java/org/rumbledb/runtime/flwor/clauses/ReturnClauseSparkIterator.java +++ b/src/main/java/org/rumbledb/runtime/flwor/clauses/ReturnClauseSparkIterator.java @@ -402,7 +402,7 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { this.tupleContext.getVariableValues().setBindingsFromTuple(tuple, getMetadata()); // assign new variables // from new tuple - result = PendingUpdateList.mergeUpdates(result, this.expression.getPendingUpdateList(this.tupleContext)); + result = PendingUpdateList.mergeUpdates(result, this.expression.getPendingUpdateList(this.tupleContext), this.getMetadata()); } this.child.close(); @@ -428,7 +428,7 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { // from new tuple PendingUpdateList intermediateResult = this.expression.getPendingUpdateList(dynamicContext); - result = PendingUpdateList.mergeUpdates(result, intermediateResult); + result = PendingUpdateList.mergeUpdates(result, intermediateResult, this.getMetadata()); } } return result; diff --git a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java index 593f3c6dd5..5fb8383bb4 100644 --- a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java +++ b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java @@ -187,7 +187,7 @@ public void applyUpdates() { } - public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpdateList pul2) { + public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpdateList pul2, ExceptionMetadata metadata) { PendingUpdateList res = new PendingUpdateList(); Map tempSelSrcMap; Map> tempSelSrcListMap; @@ -234,7 +234,7 @@ public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpda for (Item target : pul2.insertObjMap.keySet()) { tempSrc = pul2.insertObjMap.get(target); if (res.insertObjMap.containsKey(target)) { - tempSrc = InsertIntoObjectPrimitive.mergeSources(res.insertObjMap.get(target), tempSrc); + tempSrc = InsertIntoObjectPrimitive.mergeSources(res.insertObjMap.get(target), tempSrc, metadata); } res.insertObjMap.put(target,tempSrc); } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java index 68564f4cd4..7a2a659b0b 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoObjectPrimitive.java @@ -57,8 +57,7 @@ public boolean isInsertObject() { return true; } - public static Item mergeSources(Item first, Item second) { - // TODO: ADD METADATA + public static Item mergeSources(Item first, Item second, ExceptionMetadata metadata) { Item res; List keys = new ArrayList<>(first.getKeys()); @@ -68,9 +67,9 @@ public static Item mergeSources(Item first, Item second) { values.addAll(second.getValues()); try { - res = ItemFactory.getInstance().createObjectItem(keys, values, ExceptionMetadata.EMPTY_METADATA); + res = ItemFactory.getInstance().createObjectItem(keys, values, metadata); } catch (DuplicateObjectKeyException e) { - throw new DuplicateObjectInsertSourceException(e.getMessage(), ExceptionMetadata.EMPTY_METADATA); + throw new DuplicateObjectInsertSourceException(e.getMessage(), metadata); } return res; From 315efafc4a820688ae8b6e7b901d162d4aa5dbe7 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 22 May 2023 02:39:42 +0200 Subject: [PATCH 084/119] Create tests for JNUP0009 --- .../resources/test_files/runtime/Updating/PULMergeErr2.jq | 6 ++++++ .../resources/test_files/runtime/Updating/PULMergeErr3.jq | 6 ++++++ 2 files changed, 12 insertions(+) create mode 100644 src/test/resources/test_files/runtime/Updating/PULMergeErr2.jq create mode 100644 src/test/resources/test_files/runtime/Updating/PULMergeErr3.jq diff --git a/src/test/resources/test_files/runtime/Updating/PULMergeErr2.jq b/src/test/resources/test_files/runtime/Updating/PULMergeErr2.jq new file mode 100644 index 0000000000..f2c9cf7e8e --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/PULMergeErr2.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="JNUP0009"; ErrorMetadata="LINE:3:COLUMN:8:" :) +copy json $je := { "a" : 1, "b" : 2, "c" : 3 } +modify (replace json value of $je.foo with "foo", replace json value of $je.foo with "bar") +return $je + +(: replace at same object with same selector :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/PULMergeErr3.jq b/src/test/resources/test_files/runtime/Updating/PULMergeErr3.jq new file mode 100644 index 0000000000..bb64655941 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/PULMergeErr3.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="JNUP0009"; ErrorMetadata="LINE:3:COLUMN:8:" :) +copy json $je := [1 to 4] +modify (replace json value of $je[[1]] with "foo", replace json value of $je[[1]] with "bar") +return $je + +(: replace at same array with same selector :) \ No newline at end of file From 730bc3a047b371f7aca3ca7b2c0a97c47198ee6a Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 22 May 2023 02:39:56 +0200 Subject: [PATCH 085/119] Implement metadata for JNUP0009 --- .../java/org/rumbledb/runtime/update/PendingUpdateList.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java index 5fb8383bb4..0b64232515 100644 --- a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java +++ b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java @@ -218,7 +218,7 @@ public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpda if (tempSelSrcResMap.containsKey(selector)) { tempSrc = tempSelSrcResMap.get(selector); if (tempSrc != null) { - throw new TooManyReplacesOnSameTargetSelectorException(target.getDynamicType().getName().toString(), selector.getStringValue(), ExceptionMetadata.EMPTY_METADATA); + throw new TooManyReplacesOnSameTargetSelectorException(target.getDynamicType().getName().toString(), selector.getStringValue(), metadata); } continue; } @@ -257,7 +257,7 @@ public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpda for (Item selector : tempSelSrcMap.keySet()) { if (tempSelSrcResMap.containsKey(selector)) { - throw new TooManyRenamesOnSameTargetSelectorException(selector.getStringValue(), ExceptionMetadata.EMPTY_METADATA); + throw new TooManyRenamesOnSameTargetSelectorException(selector.getStringValue(), metadata); } tempSelSrcResMap.put(selector, tempSelSrcMap.get(selector)); } @@ -286,7 +286,7 @@ public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpda if (tempSelSrcResMap.containsKey(selector)) { tempSrc = tempSelSrcResMap.get(selector); if (tempSrc != null) { - throw new TooManyReplacesOnSameTargetSelectorException(target.getDynamicType().getName().toString(), Integer.toString(selector.getIntValue()), ExceptionMetadata.EMPTY_METADATA); + throw new TooManyReplacesOnSameTargetSelectorException(target.getDynamicType().getName().toString(), Integer.toString(selector.getIntValue()), metadata); } continue; } From 8422cef85cb7be302d7a3ca57da3dfb2253371be Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 22 May 2023 02:41:44 +0200 Subject: [PATCH 086/119] Create test for JNUP0010 --- .../resources/test_files/runtime/Updating/PULMergeErr4.jq | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/test/resources/test_files/runtime/Updating/PULMergeErr4.jq diff --git a/src/test/resources/test_files/runtime/Updating/PULMergeErr4.jq b/src/test/resources/test_files/runtime/Updating/PULMergeErr4.jq new file mode 100644 index 0000000000..d3b098e6ab --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/PULMergeErr4.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="JNUP0010"; ErrorMetadata="LINE:3:COLUMN:8:" :) +copy json $je := { "a" : 1, "b" : 2, "c" : 3 } +modify (rename json $je.a as "foo", rename json $je.a as "bar") +return $je + +(: rename at same object with same selector :) \ No newline at end of file From 93e405bdc7264647aa2aed2d72a5365e4272d7cc Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 22 May 2023 03:13:34 +0200 Subject: [PATCH 087/119] Create tests for JNUP0008 --- .../test_files/runtime/Updating/SimpleAppendErr1.jq | 6 ++++++ .../test_files/runtime/Updating/SimpleDeleteErr2.jq | 6 ++++++ .../test_files/runtime/Updating/SimpleInsertErr4.jq | 6 ++++++ .../test_files/runtime/Updating/SimpleInsertErr5.jq | 6 ++++++ .../test_files/runtime/Updating/SimpleRenameErr4.jq | 6 ++++++ .../test_files/runtime/Updating/SimpleReplaceErr4.jq | 6 ++++++ 6 files changed, 36 insertions(+) create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleAppendErr1.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleDeleteErr2.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleInsertErr4.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleInsertErr5.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleRenameErr4.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleReplaceErr4.jq diff --git a/src/test/resources/test_files/runtime/Updating/SimpleAppendErr1.jq b/src/test/resources/test_files/runtime/Updating/SimpleAppendErr1.jq new file mode 100644 index 0000000000..091bbd3ec9 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleAppendErr1.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="JNUP0008"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := { "a" : 1, "b" : 2, "c" : 3 } +modify append json 5 into false +return $je + +(: target expr does not evaluate to array :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleDeleteErr2.jq b/src/test/resources/test_files/runtime/Updating/SimpleDeleteErr2.jq new file mode 100644 index 0000000000..ef9c745905 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleDeleteErr2.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="JNUP0008"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := { "a" : 1, "b" : 2, "c" : 3 } +modify delete json false[[1]] +return $je + +(: target expr does not evaluate to array or object :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleInsertErr4.jq b/src/test/resources/test_files/runtime/Updating/SimpleInsertErr4.jq new file mode 100644 index 0000000000..24319487d4 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleInsertErr4.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="JNUP0008"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := {"foo": "bar"} +modify insert json "foobar": "barfoo" into false +return $je + +(: target expr must be object :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleInsertErr5.jq b/src/test/resources/test_files/runtime/Updating/SimpleInsertErr5.jq new file mode 100644 index 0000000000..a46f340652 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleInsertErr5.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="JNUP0008"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := [1 to 4] +modify insert json 5 into false at position 4 +return $je + +(: target expr must be array :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleRenameErr4.jq b/src/test/resources/test_files/runtime/Updating/SimpleRenameErr4.jq new file mode 100644 index 0000000000..074a8ee88f --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleRenameErr4.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="JNUP0008"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := {"foo": "bar", "foobar": "barfoo"} +modify rename json false.foo as "bar" +return $je + +(: target expr must be object :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleReplaceErr4.jq b/src/test/resources/test_files/runtime/Updating/SimpleReplaceErr4.jq new file mode 100644 index 0000000000..eaa7c13a4c --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleReplaceErr4.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="JNUP0008"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := [1 to 4] +modify replace json value of false[[1]] with "foo" +return $je + +(: target expr does not evaluate to single array or object :) \ No newline at end of file From d6c740ea756a7827a6ce466766d7d9c70f758ec7 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 22 May 2023 03:14:00 +0200 Subject: [PATCH 088/119] Implement check and throw for JNUP0008 --- .../update/expression/AppendExpressionIterator.java | 7 ++----- .../update/expression/DeleteExpressionIterator.java | 10 +++++----- .../update/expression/InsertExpressionIterator.java | 2 +- .../update/expression/RenameExpressionIterator.java | 2 +- .../update/expression/ReplaceExpressionIterator.java | 2 +- .../test_files/runtime/Updating/PULMergeErr1.jq | 2 +- 6 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java index 7cd0641247..f40412cd1d 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java @@ -3,10 +3,7 @@ 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.MoreThanOneItemException; -import org.rumbledb.exceptions.NoItemException; -import org.rumbledb.exceptions.OurBadException; +import org.rumbledb.exceptions.*; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.HybridRuntimeIterator; @@ -81,7 +78,7 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { Item locator = ItemFactory.getInstance().createIntItem(target.getSize() + 1); up = factory.createInsertIntoArrayPrimitive(target, locator, Collections.singletonList(content)); } else { - throw new OurBadException("Append iterator cannot handle target items that are not arrays"); + throw new InvalidUpdateTargetException("Append expression target must be a single array", this.getMetadata()); } pul.addUpdatePrimitive(up); diff --git a/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java index 60848c8b29..804fa6480b 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java @@ -3,10 +3,7 @@ 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.MoreThanOneItemException; -import org.rumbledb.exceptions.NoItemException; -import org.rumbledb.exceptions.OurBadException; +import org.rumbledb.exceptions.*; import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.runtime.HybridRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; @@ -75,11 +72,14 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { UpdatePrimitiveFactory factory = UpdatePrimitiveFactory.getInstance(); UpdatePrimitive up; if (main.isObject()) { + if (!lookup.isString()) { + throw new CannotCastUpdateSelectorException("Delete expression selection cannot be cast to String type", this.getMetadata()); + } up = factory.createDeleteFromObjectPrimitive(main, Collections.singletonList(lookup)); } else if (main.isArray()) { up = factory.createDeleteFromArrayPrimitive(main, lookup); } else { - throw new OurBadException("Delete iterator cannot handle main items that are not objects or arrays"); + throw new InvalidUpdateTargetException("Delete expression target must be a single array or object", this.getMetadata()); } pul.addUpdatePrimitive(up); diff --git a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java index c069970855..6569667bba 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java @@ -97,7 +97,7 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { } else if (main.isArray()) { up = factory.createInsertIntoArrayPrimitive(main, locator, Collections.singletonList(content)); } else { - throw new OurBadException("Insert iterator cannot handle main items that are not objects or arrays"); + throw new InvalidUpdateTargetException("Insert expression target must be a single array or object", this.getMetadata()); } pul.addUpdatePrimitive(up); diff --git a/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java index fc86db1f57..da904fe8bb 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java @@ -83,7 +83,7 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { if (target.isObject()) { up = factory.createRenameInObjectPrimitive(target, locator, content); } else { - throw new OurBadException("Rename iterator cannot handle target items that are not objects"); + throw new InvalidUpdateTargetException("Rename expression target must be a single object", this.getMetadata()); } pul.addUpdatePrimitive(up); diff --git a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java index f67e931fd5..5201c5a032 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java @@ -83,7 +83,7 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { } else if (target.isArray()) { up = factory.createReplaceInArrayPrimitive(target, locator, content); } else { - throw new OurBadException("Replace iterator cannot handle target items that are not objects or arrays"); + throw new InvalidUpdateTargetException("Replace expression target must be a single array or object", this.getMetadata()); } pul.addUpdatePrimitive(up); diff --git a/src/test/resources/test_files/runtime/Updating/PULMergeErr1.jq b/src/test/resources/test_files/runtime/Updating/PULMergeErr1.jq index ec035042a7..9453c81e19 100644 --- a/src/test/resources/test_files/runtime/Updating/PULMergeErr1.jq +++ b/src/test/resources/test_files/runtime/Updating/PULMergeErr1.jq @@ -3,4 +3,4 @@ copy json $je := { "a" : 1, "b" : 2, "c" : 3 } modify (insert json "foobar": "barfoo" into $je, insert json "foobar": "barfoo" into $je) return $je -(: insert same key into same object :) \ No newline at end of file +(: insert same key into same object with 2 inserts :) \ No newline at end of file From a58f2a38a4053fc65bbdbddb1774d2e1b8eb59d9 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 22 May 2023 03:24:37 +0200 Subject: [PATCH 089/119] Create tests for JNUP0007 --- .../test_files/runtime/Updating/SimpleDeleteErr3.jq | 6 ++++++ .../test_files/runtime/Updating/SimpleDeleteErr4.jq | 6 ++++++ .../test_files/runtime/Updating/SimpleInsertErr6.jq | 6 ++++++ .../test_files/runtime/Updating/SimpleRenameErr5.jq | 6 ++++++ .../test_files/runtime/Updating/SimpleReplaceErr5.jq | 6 ++++++ .../test_files/runtime/Updating/SimpleReplaceErr6.jq | 6 ++++++ 6 files changed, 36 insertions(+) create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleDeleteErr3.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleDeleteErr4.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleInsertErr6.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleRenameErr5.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleReplaceErr5.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleReplaceErr6.jq diff --git a/src/test/resources/test_files/runtime/Updating/SimpleDeleteErr3.jq b/src/test/resources/test_files/runtime/Updating/SimpleDeleteErr3.jq new file mode 100644 index 0000000000..c9fb5ad8f2 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleDeleteErr3.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="JNUP0007"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := [1 to 4] +modify delete json $je[["foo"]] +return $je + +(: selector expr does not evaluate to int :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleDeleteErr4.jq b/src/test/resources/test_files/runtime/Updating/SimpleDeleteErr4.jq new file mode 100644 index 0000000000..78bc4cab0c --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleDeleteErr4.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="JNUP0007"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := {"a" : 1} +modify delete json $je.$je +return $je + +(: target expr does not evaluate to string :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleInsertErr6.jq b/src/test/resources/test_files/runtime/Updating/SimpleInsertErr6.jq new file mode 100644 index 0000000000..dc1aaa6b5c --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleInsertErr6.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="JNUP0007"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := [1 to 4] +modify insert json 5 into $je at position false +return $je + +(: selector expr does not evaluate to int :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleRenameErr5.jq b/src/test/resources/test_files/runtime/Updating/SimpleRenameErr5.jq new file mode 100644 index 0000000000..88129f30df --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleRenameErr5.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="JNUP0007"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := {"foo": "bar", "foobar": "barfoo"} +modify rename json $je.$je as "bar" +return $je + +(: selector expr does not evaluate to String :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleReplaceErr5.jq b/src/test/resources/test_files/runtime/Updating/SimpleReplaceErr5.jq new file mode 100644 index 0000000000..10432d3a9e --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleReplaceErr5.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="JNUP0007"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := [1 to 4] +modify replace json value of $je[["foo"]] with "foo" +return $je + +(: selector expr does not evaluate to Int :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleReplaceErr6.jq b/src/test/resources/test_files/runtime/Updating/SimpleReplaceErr6.jq new file mode 100644 index 0000000000..be6f6e3bab --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleReplaceErr6.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="JNUP0007"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := {"a" : 1} +modify replace json value of $je.$je with "foo" +return $je + +(: selector expr does not evaluate to String :) \ No newline at end of file From 0e286cb1dc919972c3313bdec580077b2233c89e Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 22 May 2023 03:24:58 +0200 Subject: [PATCH 090/119] Implement checks and throws for JNUP0007 --- .../runtime/update/expression/DeleteExpressionIterator.java | 3 +++ .../runtime/update/expression/InsertExpressionIterator.java | 3 +++ .../runtime/update/expression/RenameExpressionIterator.java | 3 +++ .../update/expression/ReplaceExpressionIterator.java | 6 ++++++ 4 files changed, 15 insertions(+) diff --git a/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java index 804fa6480b..aa4129765d 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java @@ -77,6 +77,9 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { } up = factory.createDeleteFromObjectPrimitive(main, Collections.singletonList(lookup)); } else if (main.isArray()) { + if (!lookup.isInt()) { + throw new CannotCastUpdateSelectorException("Delete expression selection cannot be cast to Int type", this.getMetadata()); + } up = factory.createDeleteFromArrayPrimitive(main, lookup); } else { throw new InvalidUpdateTargetException("Delete expression target must be a single array or object", this.getMetadata()); diff --git a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java index 6569667bba..6922890df3 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java @@ -95,6 +95,9 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { if (main.isObject()) { up = factory.createInsertIntoObjectPrimitive(main, content); } else if (main.isArray()) { + if (locator != null && !locator.isInt()) { + throw new CannotCastUpdateSelectorException("Insert expression selection cannot be cast to Int type", this.getMetadata()); + } up = factory.createInsertIntoArrayPrimitive(main, locator, Collections.singletonList(content)); } else { throw new InvalidUpdateTargetException("Insert expression target must be a single array or object", this.getMetadata()); diff --git a/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java index da904fe8bb..b704ac4e17 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java @@ -81,6 +81,9 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { UpdatePrimitiveFactory factory = UpdatePrimitiveFactory.getInstance(); UpdatePrimitive up; if (target.isObject()) { + if (!locator.isString()) { + throw new CannotCastUpdateSelectorException("Rename expression selection cannot be cast to String type", this.getMetadata()); + } up = factory.createRenameInObjectPrimitive(target, locator, content); } else { throw new InvalidUpdateTargetException("Rename expression target must be a single object", this.getMetadata()); diff --git a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java index 5201c5a032..e5f58e7c6c 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java @@ -79,8 +79,14 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { UpdatePrimitiveFactory factory = UpdatePrimitiveFactory.getInstance(); UpdatePrimitive up; if (target.isObject()) { + if (!locator.isString()) { + throw new CannotCastUpdateSelectorException("Replace expression selection cannot be cast to String type", this.getMetadata()); + } up = factory.createReplaceInObjectPrimitive(target, locator, content); } else if (target.isArray()) { + if (!locator.isInt()) { + throw new CannotCastUpdateSelectorException("Replace expression selection cannot be cast to Int type", this.getMetadata()); + } up = factory.createReplaceInArrayPrimitive(target, locator, content); } else { throw new InvalidUpdateTargetException("Replace expression target must be a single array or object", this.getMetadata()); From 832d38b1867a927d868af66b027160210faef96d Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 22 May 2023 19:38:27 +0200 Subject: [PATCH 091/119] Create tests for JNUP0016 --- .../resources/test_files/runtime/Updating/PULMergeErr2.jq | 2 +- .../test_files/runtime/Updating/SimpleDeleteErr5.jq | 6 ++++++ .../test_files/runtime/Updating/SimpleDeleteErr6.jq | 6 ++++++ .../test_files/runtime/Updating/SimpleRenameErr6.jq | 6 ++++++ .../test_files/runtime/Updating/SimpleReplaceErr7.jq | 6 ++++++ .../test_files/runtime/Updating/SimpleReplaceErr8.jq | 6 ++++++ 6 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleDeleteErr5.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleDeleteErr6.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleRenameErr6.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleReplaceErr7.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleReplaceErr8.jq diff --git a/src/test/resources/test_files/runtime/Updating/PULMergeErr2.jq b/src/test/resources/test_files/runtime/Updating/PULMergeErr2.jq index f2c9cf7e8e..e28aa8e154 100644 --- a/src/test/resources/test_files/runtime/Updating/PULMergeErr2.jq +++ b/src/test/resources/test_files/runtime/Updating/PULMergeErr2.jq @@ -1,6 +1,6 @@ (:JIQS: ShouldCrash; ErrorCode="JNUP0009"; ErrorMetadata="LINE:3:COLUMN:8:" :) copy json $je := { "a" : 1, "b" : 2, "c" : 3 } -modify (replace json value of $je.foo with "foo", replace json value of $je.foo with "bar") +modify (replace json value of $je.a with "foo", replace json value of $je.a with "bar") return $je (: replace at same object with same selector :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleDeleteErr5.jq b/src/test/resources/test_files/runtime/Updating/SimpleDeleteErr5.jq new file mode 100644 index 0000000000..651e42ebd9 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleDeleteErr5.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="JNUP0016"; ErrorMetadata="LINE:3:COLUMN:8:" :) +copy json $je := [1 to 4] +modify (delete json $je[[0]], delete json $je[[5]]) +return $je + +(: selector int is out of range of target array :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleDeleteErr6.jq b/src/test/resources/test_files/runtime/Updating/SimpleDeleteErr6.jq new file mode 100644 index 0000000000..c271fe92e6 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleDeleteErr6.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="JNUP0016"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := {"a" : 1} +modify delete json $je.b +return $je + +(: selector string does not exist in target object :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleRenameErr6.jq b/src/test/resources/test_files/runtime/Updating/SimpleRenameErr6.jq new file mode 100644 index 0000000000..928cae94f8 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleRenameErr6.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="JNUP0016"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := {"foo": "bar", "foobar": "barfoo"} +modify rename json $je."bar" as "barbar" +return $je + +(: selector string does not exist in target object :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleReplaceErr7.jq b/src/test/resources/test_files/runtime/Updating/SimpleReplaceErr7.jq new file mode 100644 index 0000000000..eff2f04653 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleReplaceErr7.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="JNUP0016"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := [1 to 4] +modify replace json value of $je[[0]] with "foo" +return $je + +(: selector int is out of range of target array :) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleReplaceErr8.jq b/src/test/resources/test_files/runtime/Updating/SimpleReplaceErr8.jq new file mode 100644 index 0000000000..b972da1437 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleReplaceErr8.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="JNUP0016"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := {"a" : 1} +modify replace json value of $je."b" with "foo" +return $je + +(: selector string does not exist in target object :) \ No newline at end of file From eb2b21f5a40f7ce5b49d57c448b588be1c650ae6 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 22 May 2023 19:38:55 +0200 Subject: [PATCH 092/119] Implement checks, throws, and metadata for JNUP0016 --- .../runtime/update/PendingUpdateList.java | 12 +++++----- .../expression/DeleteExpressionIterator.java | 4 ++-- .../expression/RenameExpressionIterator.java | 2 +- .../expression/ReplaceExpressionIterator.java | 4 ++-- .../TransformExpressionIterator.java | 6 ++--- .../primitives/DeleteFromArrayPrimitive.java | 11 ++++----- .../primitives/DeleteFromObjectPrimitive.java | 13 +++++++---- .../primitives/RenameInObjectPrimitive.java | 9 +++++--- .../primitives/ReplaceInArrayPrimitive.java | 8 ++++--- .../primitives/ReplaceInObjectPrimitive.java | 8 ++++--- .../primitives/UpdatePrimitiveFactory.java | 23 ++++++++++--------- 11 files changed, 56 insertions(+), 44 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java index 0b64232515..cfec75912a 100644 --- a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java +++ b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java @@ -86,7 +86,7 @@ public void addUpdatePrimitive(UpdatePrimitive updatePrimitive) { } } - public void applyUpdates() { + public void applyUpdates(ExceptionMetadata metadata) { UpdatePrimitiveFactory upFactory = UpdatePrimitiveFactory.getInstance(); Map> targetArrayPULs = new HashMap<>(); @@ -108,10 +108,10 @@ public void applyUpdates() { if (tempSrc == null) { toDel.add(locator); } else { - objectPUL.add(upFactory.createReplaceInObjectPrimitive(target, locator, tempSrc)); + objectPUL.add(upFactory.createReplaceInObjectPrimitive(target, locator, tempSrc, metadata)); } } - objectPUL.add(upFactory.createDeleteFromObjectPrimitive(target, toDel)); + objectPUL.add(upFactory.createDeleteFromObjectPrimitive(target, toDel, metadata)); } // INSERTS @@ -125,7 +125,7 @@ public void applyUpdates() { for (Item target : renameObjMap.keySet()) { tempSelSrcMap = renameObjMap.get(target); for (Item locator : tempSelSrcMap.keySet()) { - objectPUL.add(upFactory.createRenameInObjectPrimitive(target, locator, tempSelSrcMap.get(locator))); + objectPUL.add(upFactory.createRenameInObjectPrimitive(target, locator, tempSelSrcMap.get(locator), metadata)); } } @@ -140,9 +140,9 @@ public void applyUpdates() { UpdatePrimitive up; tempSrc = tempSelSrcMap.get(locator); if (tempSrc == null) { - up = upFactory.createDeleteFromArrayPrimitive(target, locator); + up = upFactory.createDeleteFromArrayPrimitive(target, locator, metadata); } else { - up = upFactory.createReplaceInArrayPrimitive(target, locator, tempSrc); + up = upFactory.createReplaceInArrayPrimitive(target, locator, tempSrc, metadata); } int index = Collections.binarySearch(tempArrayPULs, up, Comparator.comparing(UpdatePrimitive::getIntSelector)); if (index < 0) { diff --git a/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java index aa4129765d..c7d05275d1 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java @@ -75,12 +75,12 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { if (!lookup.isString()) { throw new CannotCastUpdateSelectorException("Delete expression selection cannot be cast to String type", this.getMetadata()); } - up = factory.createDeleteFromObjectPrimitive(main, Collections.singletonList(lookup)); + up = factory.createDeleteFromObjectPrimitive(main, Collections.singletonList(lookup), this.getMetadata()); } else if (main.isArray()) { if (!lookup.isInt()) { throw new CannotCastUpdateSelectorException("Delete expression selection cannot be cast to Int type", this.getMetadata()); } - up = factory.createDeleteFromArrayPrimitive(main, lookup); + up = factory.createDeleteFromArrayPrimitive(main, lookup, this.getMetadata()); } else { throw new InvalidUpdateTargetException("Delete expression target must be a single array or object", this.getMetadata()); } diff --git a/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java index b704ac4e17..f8e9c90a98 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java @@ -84,7 +84,7 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { if (!locator.isString()) { throw new CannotCastUpdateSelectorException("Rename expression selection cannot be cast to String type", this.getMetadata()); } - up = factory.createRenameInObjectPrimitive(target, locator, content); + up = factory.createRenameInObjectPrimitive(target, locator, content, this.getMetadata()); } else { throw new InvalidUpdateTargetException("Rename expression target must be a single object", this.getMetadata()); } diff --git a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java index e5f58e7c6c..4c4f52df5c 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java @@ -82,12 +82,12 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { if (!locator.isString()) { throw new CannotCastUpdateSelectorException("Replace expression selection cannot be cast to String type", this.getMetadata()); } - up = factory.createReplaceInObjectPrimitive(target, locator, content); + up = factory.createReplaceInObjectPrimitive(target, locator, content, this.getMetadata()); } else if (target.isArray()) { if (!locator.isInt()) { throw new CannotCastUpdateSelectorException("Replace expression selection cannot be cast to Int type", this.getMetadata()); } - up = factory.createReplaceInArrayPrimitive(target, locator, content); + up = factory.createReplaceInArrayPrimitive(target, locator, content, this.getMetadata()); } else { throw new InvalidUpdateTargetException("Replace expression target must be a single array or object", this.getMetadata()); } diff --git a/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java index eb1d29c144..739f673f43 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java @@ -40,14 +40,14 @@ public TransformExpressionIterator(Map copyDeclMap, Runti @Override protected JavaRDD getRDDAux(DynamicContext context) { PendingUpdateList pul = getPendingUpdateList(context); - pul.applyUpdates(); + pul.applyUpdates(this.getMetadata()); return returnIterator.getRDD(context); } @Override protected void openLocal() { PendingUpdateList pul = getPendingUpdateList(this.currentDynamicContextForLocalExecution); - pul.applyUpdates(); + pul.applyUpdates(this.getMetadata()); returnIterator.open(this.currentDynamicContextForLocalExecution); } @@ -59,7 +59,7 @@ protected void closeLocal() { @Override protected void resetLocal() { PendingUpdateList pul = getPendingUpdateList(this.currentDynamicContextForLocalExecution); - pul.applyUpdates(); + pul.applyUpdates(this.getMetadata()); returnIterator.reset(this.currentDynamicContextForLocalExecution); } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java index e576a490cb..4d013869b2 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java @@ -1,6 +1,8 @@ package org.rumbledb.runtime.update.primitives; import org.rumbledb.api.Item; +import org.rumbledb.exceptions.CannotResolveUpdateSelectorException; +import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.items.ArrayItem; public class DeleteFromArrayPrimitive implements UpdatePrimitive { @@ -9,12 +11,9 @@ public class DeleteFromArrayPrimitive implements UpdatePrimitive { private Item target; private Item selector; - public DeleteFromArrayPrimitive(Item targetArray, Item positionInt) { - if (!targetArray.isArray() || !positionInt.isNumeric()) { - // TODO ERROR - } - if (positionInt.getIntValue() < 0 || positionInt.getIntValue() >= targetArray.getSize()) { - // TODO throw error or do nothing? + public DeleteFromArrayPrimitive(Item targetArray, Item positionInt, ExceptionMetadata metadata) { + if (positionInt.getIntValue() <= 0 || positionInt.getIntValue() > targetArray.getSize()) { + throw new CannotResolveUpdateSelectorException("Cannot delete item at index out of range of target array", metadata); } this.target = targetArray; this.selector = positionInt; diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java index 8423332f42..79cf30d52c 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java @@ -1,6 +1,8 @@ package org.rumbledb.runtime.update.primitives; import org.rumbledb.api.Item; +import org.rumbledb.exceptions.CannotResolveUpdateSelectorException; +import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.OurBadException; import org.rumbledb.items.ObjectItem; @@ -13,12 +15,15 @@ public class DeleteFromObjectPrimitive implements UpdatePrimitive { private Item target; private List content; - public DeleteFromObjectPrimitive(Item targetObject, List namesToRemove) { - if (!targetObject.isObject() || !namesToRemove.stream().allMatch(Item::isString)) { - // TODO ERROR + public DeleteFromObjectPrimitive(Item targetObject, List namesToRemove, ExceptionMetadata metadata) { + + for (Item item : namesToRemove) { + if (targetObject.getItemByKey(item.getStringValue()) == null) { + throw new CannotResolveUpdateSelectorException("Cannot delete key that does not exist in target object", metadata); + } } - this.target = targetObject; + this.target = targetObject; this.content = namesToRemove; } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java index 1b50f1af27..aaff6e3498 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java @@ -1,6 +1,8 @@ package org.rumbledb.runtime.update.primitives; import org.rumbledb.api.Item; +import org.rumbledb.exceptions.CannotResolveUpdateSelectorException; +import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.items.ObjectItem; public class RenameInObjectPrimitive implements UpdatePrimitive { @@ -9,12 +11,13 @@ public class RenameInObjectPrimitive implements UpdatePrimitive { private Item selector; private Item content; - public RenameInObjectPrimitive(Item targetObject, Item targetName, Item replacementName) { + public RenameInObjectPrimitive(Item targetObject, Item targetName, Item replacementName, ExceptionMetadata metadata) { - if (!targetObject.isObject() || !targetName.isString() || !replacementName.isString()) { - // TODO ERROR + if (targetObject.getItemByKey(targetName.getStringValue()) == null) { + throw new CannotResolveUpdateSelectorException("Cannot rename key that does not exist in target object", metadata); } + this.target = targetObject; this.selector = targetName; this.content = replacementName; diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java index 692633fe59..5522e2b8cb 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java @@ -1,6 +1,8 @@ package org.rumbledb.runtime.update.primitives; import org.rumbledb.api.Item; +import org.rumbledb.exceptions.CannotResolveUpdateSelectorException; +import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.items.ArrayItem; public class ReplaceInArrayPrimitive implements UpdatePrimitive { @@ -9,9 +11,9 @@ public class ReplaceInArrayPrimitive implements UpdatePrimitive { private Item selector; private Item content; - public ReplaceInArrayPrimitive(Item targetArray, Item positionInt, Item replacementItem) { - if (!targetArray.isArray() || !positionInt.isNumeric()) { - // TODO ERROR + public ReplaceInArrayPrimitive(Item targetArray, Item positionInt, Item replacementItem, ExceptionMetadata metadata) { + if (positionInt.getIntValue() <= 0 || positionInt.getIntValue() > targetArray.getSize()) { + throw new CannotResolveUpdateSelectorException("Cannot replace item at index out of range of target array", metadata); } this.target = targetArray; diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java index 3686cc8ed7..77f85e7cce 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java @@ -1,6 +1,8 @@ package org.rumbledb.runtime.update.primitives; import org.rumbledb.api.Item; +import org.rumbledb.exceptions.CannotResolveUpdateSelectorException; +import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.items.ObjectItem; public class ReplaceInObjectPrimitive implements UpdatePrimitive { @@ -9,10 +11,10 @@ public class ReplaceInObjectPrimitive implements UpdatePrimitive { private Item selector; private Item content; - public ReplaceInObjectPrimitive(Item targetObject, Item targetName, Item replacementItem) { + public ReplaceInObjectPrimitive(Item targetObject, Item targetName, Item replacementItem, ExceptionMetadata metadata) { - if (!targetObject.isObject() || !targetName.isString()) { - // TODO ERROR + if (targetObject.getItemByKey(targetName.getStringValue()) == null) { + throw new CannotResolveUpdateSelectorException("Cannot delete key that does not exist in target object", metadata); } this.target = targetObject; diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveFactory.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveFactory.java index 7fd01b9a78..33ad107788 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveFactory.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveFactory.java @@ -1,6 +1,7 @@ package org.rumbledb.runtime.update.primitives; import org.rumbledb.api.Item; +import org.rumbledb.exceptions.ExceptionMetadata; import java.util.List; @@ -15,15 +16,15 @@ public static UpdatePrimitiveFactory getInstance() { return instance; } - public UpdatePrimitive createDeleteFromArrayPrimitive(Item targetArray, Item selectorInt) { - return new DeleteFromArrayPrimitive(targetArray, selectorInt); + public UpdatePrimitive createDeleteFromArrayPrimitive(Item targetArray, Item selectorInt, ExceptionMetadata metadata) { + return new DeleteFromArrayPrimitive(targetArray, selectorInt, metadata); } - public UpdatePrimitive createDeleteFromObjectPrimitive(Item targetObject, List selectorStrs) { - return new DeleteFromObjectPrimitive(targetObject, selectorStrs); + public UpdatePrimitive createDeleteFromObjectPrimitive(Item targetObject, List selectorStrs, ExceptionMetadata metadata) { + return new DeleteFromObjectPrimitive(targetObject, selectorStrs, metadata); } - public UpdatePrimitive createInsertIntoArrayPrimitive(Item targetArray, Item selectorInt, List contents ) { + public UpdatePrimitive createInsertIntoArrayPrimitive(Item targetArray, Item selectorInt, List contents) { return new InsertIntoArrayPrimitive(targetArray, selectorInt, contents); } @@ -31,16 +32,16 @@ public UpdatePrimitive createInsertIntoObjectPrimitive(Item targetObject, Item c return new InsertIntoObjectPrimitive(targetObject, contentsObject); } - public UpdatePrimitive createReplaceInArrayPrimitive(Item targetArray, Item selectorInt, Item content) { - return new ReplaceInArrayPrimitive(targetArray, selectorInt, content); + public UpdatePrimitive createReplaceInArrayPrimitive(Item targetArray, Item selectorInt, Item content, ExceptionMetadata metadata) { + return new ReplaceInArrayPrimitive(targetArray, selectorInt, content, metadata); } - public UpdatePrimitive createReplaceInObjectPrimitive(Item targetObject, Item selectorStr, Item content) { - return new ReplaceInObjectPrimitive(targetObject, selectorStr, content); + public UpdatePrimitive createReplaceInObjectPrimitive(Item targetObject, Item selectorStr, Item content, ExceptionMetadata metadata) { + return new ReplaceInObjectPrimitive(targetObject, selectorStr, content, metadata); } - public UpdatePrimitive createRenameInObjectPrimitive(Item targetObject, Item selectorStr, Item content) { - return new RenameInObjectPrimitive(targetObject, selectorStr, content); + public UpdatePrimitive createRenameInObjectPrimitive(Item targetObject, Item selectorStr, Item content, ExceptionMetadata metadata) { + return new RenameInObjectPrimitive(targetObject, selectorStr, content, metadata); } From cc96b956d786f1e796e02ee9fcbee934f113e102 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 22 May 2023 19:46:37 +0200 Subject: [PATCH 093/119] Create tests for JNUP0019 --- .../test_files/runtime/Updating/SimpleInsertErr7.jq | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleInsertErr7.jq diff --git a/src/test/resources/test_files/runtime/Updating/SimpleInsertErr7.jq b/src/test/resources/test_files/runtime/Updating/SimpleInsertErr7.jq new file mode 100644 index 0000000000..2ab096ab18 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleInsertErr7.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="JNUP0019"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $je := {"a" : 1} +modify insert json false into $je +return $je + +(: content expr does not evaluate to object :) \ No newline at end of file From bac7acfbd27ce38e9fce267796bad7354b15abe9 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 22 May 2023 19:47:06 +0200 Subject: [PATCH 094/119] Implement check and throws for JNUP0019 --- src/main/java/org/rumbledb/api/Rumble.java | 4 ++-- .../runtime/update/expression/InsertExpressionIterator.java | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/rumbledb/api/Rumble.java b/src/main/java/org/rumbledb/api/Rumble.java index 078eace48c..35f4ce95ee 100644 --- a/src/main/java/org/rumbledb/api/Rumble.java +++ b/src/main/java/org/rumbledb/api/Rumble.java @@ -54,7 +54,7 @@ public SequenceOfItems runQuery(String query) { if (iterator.isUpdating()) { PendingUpdateList pul = iterator.getPendingUpdateList(dynamicContext); - pul.applyUpdates(); + pul.applyUpdates(iterator.getMetadata()); } System.err.println("final iterator is: " + iterator.isUpdating()); @@ -82,7 +82,7 @@ public SequenceOfItems runQuery(URI location) throws IOException { if (iterator.isUpdating()) { PendingUpdateList pul = iterator.getPendingUpdateList(dynamicContext); - pul.applyUpdates(); + pul.applyUpdates(iterator.getMetadata()); } System.err.println("final iterator is: " + iterator.isUpdating()); diff --git a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java index 6922890df3..7c7129cf15 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java @@ -93,10 +93,13 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { UpdatePrimitiveFactory factory = UpdatePrimitiveFactory.getInstance(); UpdatePrimitive up; if (main.isObject()) { + if (!content.isObject()) { + throw new ObjectInsertContentIsNotObjectSeqException("Insert exoression content is not an object", this.getMetadata()); + } up = factory.createInsertIntoObjectPrimitive(main, content); } else if (main.isArray()) { if (locator != null && !locator.isInt()) { - throw new CannotCastUpdateSelectorException("Insert expression selection cannot be cast to Int type", this.getMetadata()); + throw new CannotCastUpdateSelectorException("Insert expression selector cannot be cast to Int type", this.getMetadata()); } up = factory.createInsertIntoArrayPrimitive(main, locator, Collections.singletonList(content)); } else { From 8ca1fe646b3050815cfdb20ff87032d7d911267a Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 22 May 2023 19:53:10 +0200 Subject: [PATCH 095/119] Create tests for JNDY0003 --- .../test_files/runtime/Updating/SimpleInsertErr8.jq | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleInsertErr8.jq diff --git a/src/test/resources/test_files/runtime/Updating/SimpleInsertErr8.jq b/src/test/resources/test_files/runtime/Updating/SimpleInsertErr8.jq new file mode 100644 index 0000000000..9c3bb1318a --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleInsertErr8.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldCrash; ErrorCode="JNDY0003"; ErrorMetadata="LINE:3:COLUMN:32:" :) +copy json $je := {"a" : 1} +modify insert json "b" : 3 into {"a" : 1, "a" : 2} +return $je + +(: content expr does not evaluate to object :) \ No newline at end of file From 7554da1b56c61b4848afe4872a4b85b4a76a9c34 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Mon, 22 May 2023 19:59:24 +0200 Subject: [PATCH 096/119] Add content copy semantics --- .../runtime/update/expression/InsertExpressionIterator.java | 5 +++-- .../runtime/update/expression/ReplaceExpressionIterator.java | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java index 7c7129cf15..5d9410f55a 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java @@ -1,5 +1,6 @@ package org.rumbledb.runtime.update.expression; +import org.apache.commons.lang.SerializationUtils; import org.apache.spark.api.java.JavaRDD; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; @@ -80,7 +81,7 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { try { main = this.mainIterator.materializeExactlyOneItem(context); - content = this.toInsertIterator.materializeExactlyOneItem(context); + content = (Item) SerializationUtils.clone(this.toInsertIterator.materializeExactlyOneItem(context)); if (this.hasPositionIterator()) { locator = this.positionIterator.materializeExactlyOneItem(context); } @@ -94,7 +95,7 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { UpdatePrimitive up; if (main.isObject()) { if (!content.isObject()) { - throw new ObjectInsertContentIsNotObjectSeqException("Insert exoression content is not an object", this.getMetadata()); + throw new ObjectInsertContentIsNotObjectSeqException("Insert expression content is not an object", this.getMetadata()); } up = factory.createInsertIntoObjectPrimitive(main, content); } else if (main.isArray()) { diff --git a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java index 4c4f52df5c..167e327505 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java @@ -1,5 +1,6 @@ package org.rumbledb.runtime.update.expression; +import org.apache.commons.lang.SerializationUtils; import org.apache.spark.api.java.JavaRDD; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; @@ -69,7 +70,7 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { try { target = this.mainIterator.materializeExactlyOneItem(context); locator = this.locatorIterator.materializeExactlyOneItem(context); - content = this.replacerIterator.materializeExactlyOneItem(context); + content = (Item) SerializationUtils.clone(this.replacerIterator.materializeExactlyOneItem(context)); } catch (NoItemException e) { throw new UpdateTargetIsEmptySeqException("Target of replace expression is empty", this.getMetadata()); } catch (MoreThanOneItemException e) { From c6100f12d4ee96903d548a88a35438cf8b23f455 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Tue, 23 May 2023 00:12:55 +0200 Subject: [PATCH 097/119] Create tests for replace with empty sequence and more than one value sequence --- .../test_files/runtime/Updating/SimpleReplaceInArray3.jq | 4 ++++ .../test_files/runtime/Updating/SimpleReplaceInArray4.jq | 4 ++++ .../test_files/runtime/Updating/SimpleReplaceInObject3.jq | 4 ++++ .../test_files/runtime/Updating/SimpleReplaceInObject4.jq | 4 ++++ 4 files changed, 16 insertions(+) create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleReplaceInArray3.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleReplaceInArray4.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleReplaceInObject3.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleReplaceInObject4.jq diff --git a/src/test/resources/test_files/runtime/Updating/SimpleReplaceInArray3.jq b/src/test/resources/test_files/runtime/Updating/SimpleReplaceInArray3.jq new file mode 100644 index 0000000000..6d25d42306 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleReplaceInArray3.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="[ 1, 2, [ 5, 6 ], 4 ]" :) +copy json $je := [1 to 4] +modify replace json value of $je[[3]] with (5, 6) +return $je \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleReplaceInArray4.jq b/src/test/resources/test_files/runtime/Updating/SimpleReplaceInArray4.jq new file mode 100644 index 0000000000..d4781d042a --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleReplaceInArray4.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="[ 1, 2, null, 4 ]" :) +copy json $je := [1 to 4] +modify replace json value of $je[[3]] with () +return $je \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleReplaceInObject3.jq b/src/test/resources/test_files/runtime/Updating/SimpleReplaceInObject3.jq new file mode 100644 index 0000000000..07b92e8304 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleReplaceInObject3.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="{ "foobar" : "barfoo", "foo" : [ "foo", "bar" ] }" :) +copy json $je := {"foo": "bar", "foobar": "barfoo"} +modify replace json value of $je.foo with ("foo", "bar") +return $je \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/SimpleReplaceInObject4.jq b/src/test/resources/test_files/runtime/Updating/SimpleReplaceInObject4.jq new file mode 100644 index 0000000000..bdb7dabd7d --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleReplaceInObject4.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldRun; Output="{ "foobar" : "barfoo", "foo" : null }" :) +copy json $je := {"foo": "bar", "foobar": "barfoo"} +modify replace json value of $je.foo with () +return $je \ No newline at end of file From ddb741d40374e4364ea786c8a007a9c02a02491b Mon Sep 17 00:00:00 2001 From: dloughlin Date: Tue, 23 May 2023 00:13:15 +0200 Subject: [PATCH 098/119] Implement semantics for replace with empty sequence and more than one value sequence --- .../expression/ReplaceExpressionIterator.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java index 167e327505..1e1d36997d 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java @@ -6,12 +6,14 @@ import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.*; import org.rumbledb.expressions.ExecutionMode; +import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.HybridRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.update.PendingUpdateList; import org.rumbledb.runtime.update.primitives.UpdatePrimitive; import org.rumbledb.runtime.update.primitives.UpdatePrimitiveFactory; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -70,13 +72,25 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { try { target = this.mainIterator.materializeExactlyOneItem(context); locator = this.locatorIterator.materializeExactlyOneItem(context); - content = (Item) SerializationUtils.clone(this.replacerIterator.materializeExactlyOneItem(context)); } catch (NoItemException e) { throw new UpdateTargetIsEmptySeqException("Target of replace expression is empty", this.getMetadata()); } catch (MoreThanOneItemException e) { throw new RuntimeException(e); } + List tempContent = this.replacerIterator.materialize(context); + if (tempContent.isEmpty()) { + content = ItemFactory.getInstance().createNullItem(); + } else if (tempContent.size() == 1) { + content = (Item) SerializationUtils.clone(tempContent.get(0)); + } else { + List copyContent = new ArrayList<>(); + for (Item item : tempContent) { + copyContent.add((Item) SerializationUtils.clone(item)); + } + content = ItemFactory.getInstance().createArrayItem(copyContent); + } + UpdatePrimitiveFactory factory = UpdatePrimitiveFactory.getInstance(); UpdatePrimitive up; if (target.isObject()) { From 55bf850fda67cf3bd3eed542de7598eb6ae0a0d7 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Tue, 23 May 2023 17:17:25 +0200 Subject: [PATCH 099/119] Add test to check selector of insert into array is not null --- .../resources/test_files/runtime/Updating/SimpleInsertErr9.jq | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleInsertErr9.jq diff --git a/src/test/resources/test_files/runtime/Updating/SimpleInsertErr9.jq b/src/test/resources/test_files/runtime/Updating/SimpleInsertErr9.jq new file mode 100644 index 0000000000..350bbb8b40 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleInsertErr9.jq @@ -0,0 +1,4 @@ +(:JIQS: ShouldCrash; ErrorCode="JNUP0007"; ErrorMetadata="LINE:3:COLUMN:7:" :) +copy json $users := [] +modify insert json {"userID" : "U07", "name" : "Annabel Lee"} into $users +return $users[] \ No newline at end of file From d3b2d6c02606eb6cf98723b314319d7462a56e45 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Tue, 23 May 2023 17:17:49 +0200 Subject: [PATCH 100/119] Implement null check for selector of insert into array --- .../runtime/update/expression/InsertExpressionIterator.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java index 5d9410f55a..9bd9213693 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java @@ -99,7 +99,10 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { } up = factory.createInsertIntoObjectPrimitive(main, content); } else if (main.isArray()) { - if (locator != null && !locator.isInt()) { + if (locator == null) { + throw new CannotCastUpdateSelectorException("Insert expression selector is null", this.getMetadata()); + } + if (!locator.isInt()) { throw new CannotCastUpdateSelectorException("Insert expression selector cannot be cast to Int type", this.getMetadata()); } up = factory.createInsertIntoArrayPrimitive(main, locator, Collections.singletonList(content)); From bb7f982bbad9fb10d00e71fffeaee94b66ce2bfe Mon Sep 17 00:00:00 2001 From: dloughlin Date: Wed, 24 May 2023 01:28:15 +0200 Subject: [PATCH 101/119] Create updates use case test with small datasets --- .../runtime/Updating/UseCasesR1to6.jq | 72 +++++++++++++++++++ .../runtime/Updating/datasets/bids.json | 16 +++++ .../runtime/Updating/datasets/items.json | 8 +++ .../runtime/Updating/datasets/users.json | 6 ++ 4 files changed, 102 insertions(+) create mode 100644 src/test/resources/test_files/runtime/Updating/UseCasesR1to6.jq create mode 100644 src/test/resources/test_files/runtime/Updating/datasets/bids.json create mode 100644 src/test/resources/test_files/runtime/Updating/datasets/items.json create mode 100644 src/test/resources/test_files/runtime/Updating/datasets/users.json diff --git a/src/test/resources/test_files/runtime/Updating/UseCasesR1to6.jq b/src/test/resources/test_files/runtime/Updating/UseCasesR1to6.jq new file mode 100644 index 0000000000..92d0f8e602 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/UseCasesR1to6.jq @@ -0,0 +1,72 @@ +(:JIQS: ShouldRun; Output="(USERS:, { "userID" : "U01", "name" : "Tom Jones", "rating" : "B" }, { "userID" : "U02", "name" : "Mary Doe", "rating" : "A" }, { "userID" : "U04", "name" : "Roger Smith", "rating" : "C" }, { "userID" : "U05", "name" : "Jack Sprat", "rating" : "B" }, { "userID" : "U06", "name" : "Rip Van Winkle", "rating" : "B" }, { "userID" : "U07", "name" : "Annabel Lee", "rating" : "B" }, ITEMS:, { "itemNO" : "1001", "description" : "Red Bicycle", "offered_by" : "U01", "start_date" : "1999-01-05", "end_date" : "1999-01-20", "reserve_price" : 40 }, { "itemNO" : "1002", "description" : "Motorcycle", "offered_by" : "U02", "start_date" : "1999-02-11", "end_date" : "1999-03-15", "reserve_price" : 500 }, { "itemNO" : "1003", "description" : "Old Bicycle", "offered_by" : "U02", "start_date" : "1999-01-10", "end_date" : "1999-02-20", "reserve_price" : 25 }, { "itemNO" : "1004", "description" : "Tricycle", "offered_by" : "U01", "start_date" : "1999-02-25", "end_date" : "1999-03-08", "reserve_price" : 15 }, { "itemNO" : "1007", "description" : "Racing Bicycle", "offered_by" : "U04", "start_date" : "1999-01-20", "end_date" : "1999-02-20", "reserve_price" : 200 }, { "itemNO" : "1008", "description" : "Broken Bicycle", "offered_by" : "U01", "start_date" : "1999-02-05", "end_date" : "1999-03-06", "reserve_price" : 25 }, BIDS:, { "userID" : "U02", "itemNO" : 1001, "bid" : 35, "bid_date" : "1999-01-07" }, { "userID" : "U04", "itemNO" : 1001, "bid" : 40, "bid_date" : "1999-01-08" }, { "userID" : "U02", "itemNO" : 1001, "bid" : 45, "bid_date" : "1999-01-11" }, { "userID" : "U04", "itemNO" : 1001, "bid" : 50, "bid_date" : "1999-01-13" }, { "userID" : "U02", "itemNO" : 1001, "bid" : 55, "bid_date" : "1999-01-15" }, { "userID" : "U01", "itemNO" : 1002, "bid" : 400, "bid_date" : "1999-02-14" }, { "userID" : "U02", "itemNO" : 1002, "bid" : 600, "bid_date" : "1999-02-16" }, { "userID" : "U04", "itemNO" : 1002, "bid" : 1000, "bid_date" : "1999-02-25" }, { "userID" : "U02", "itemNO" : 1002, "bid" : 1200, "bid_date" : "1999-03-02" }, { "userID" : "U04", "itemNO" : 1003, "bid" : 15, "bid_date" : "1999-01-22" }, { "userID" : "U05", "itemNO" : 1003, "bid" : 20, "bid_date" : "1999-02-03" }, { "userID" : "U01", "itemNO" : 1004, "bid" : 40, "bid_date" : "1999-03-05" }, { "userID" : "U05", "itemNO" : 1007, "bid" : 200, "bid_date" : "1999-02-08" }, { "userID" : "U04", "itemNO" : 1007, "bid" : 225, "bid_date" : "1999-02-12" }, { "userID" : "U07", "itemNO" : 1001, "bid" : 60, "bid_date" : "1999-02-01" }, { "userID" : "U07", "itemNO" : 1002, "bid" : 1320, "bid_date" : "1999-02-01" })" :) +let $users := json-file("./datasets/users.json") +let $items := json-file("./datasets/items.json") +let $bids := json-file("./datasets/bids.json") + +let $q1_users := copy json $copy_users := [$users] + modify append json {"userID" : "U07", "name" : "Annabel Lee"} into $copy_users + return $copy_users[] + +let $q2_bids := copy json $copy_bids := [$bids] + modify append json {"userID" : "U07", "itemNO" : 1001, "bid" : 60, "bid_date" : "1999-02-01"} into $copy_bids + return $copy_bids[] + +let $q3_bids := copy json $copy_bids := [$q2_bids], $uid := $q1_users[$$.name eq "Annabel Lee"].userID, $top_bid := max($q2_bids[$$.itemNO eq 1002].bid) + modify append json {"userID" : $uid, "itemNO" : 1002, "bid" : $top_bid * 1.1, "bid_date" : "1999-02-01"} into $copy_bids + return $copy_bids[] + +let $q4_users := copy json $copy_users := [$q1_users] + modify + for $user in $copy_users[] + where $user.name eq "Annabel Lee" + return + if ($user.rating) + then + replace json value of $user.rating with "B" + else + insert json "rating" : "B" into $user + return $copy_users[] + +let $q5_bids := copy json $copy_bids := [$q3_bids], $uid := $q4_users[$$.name eq "Annabel Lee"].userID, $top_bid := max($q3_bids[$$.itemNO eq 1007].bid) + modify + if ($top_bid * 1.1 le 200) + then + append json {"userID" : $uid, "itemNO" : 1007, "bid" : $top_bid * 1.1, "bid_date" : "1999-02-01"} into $copy_bids + else + () + return $copy_bids[] + +let $to_copy_remove_uid := $q4_users[$$.name eq "Dee Linquent"].userID +let $q6_items := copy json $copy_items := [$items], $remove_uid := $to_copy_remove_uid + modify + for $i in (1 to size($copy_items)) + return + if ($copy_items[[$i]].offered_by eq $remove_uid) + then + delete json $copy_items[[$i]] + else + () + return $copy_items[] + let $q6_bids := copy json $copy_bids := [$q5_bids], $remove_uid := $to_copy_remove_uid + modify + for $i in (1 to size($copy_bids)) + return + if ($copy_bids[[$i]].userID eq $remove_uid) + then + delete json $copy_bids[[$i]] + else + () + return $copy_bids[] +let $q6_users := copy json $copy_users := [$q4_users] + modify + for $i in (1 to size($copy_users)) + return + if ($copy_users[[$i]].name eq "Dee Linquent") + then + delete json $copy_users[[$i]] + else + () + return $copy_users[] + + +return ("USERS:", $q6_users, "ITEMS:" , $q6_items, "BIDS:", $q6_bids) \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/datasets/bids.json b/src/test/resources/test_files/runtime/Updating/datasets/bids.json new file mode 100644 index 0000000000..7dbe1dcba8 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/datasets/bids.json @@ -0,0 +1,16 @@ +{"userID" : "U02", "itemNO" : 1001, "bid" : 35, "bid_date" : "1999-01-07"} +{"userID" : "U04", "itemNO" : 1001, "bid" : 40, "bid_date" : "1999-01-08"} +{"userID" : "U02", "itemNO" : 1001, "bid" : 45, "bid_date" : "1999-01-11"} +{"userID" : "U04", "itemNO" : 1001, "bid" : 50, "bid_date" : "1999-01-13"} +{"userID" : "U02", "itemNO" : 1001, "bid" : 55, "bid_date" : "1999-01-15"} +{"userID" : "U01", "itemNO" : 1002, "bid" : 400, "bid_date" : "1999-02-14"} +{"userID" : "U02", "itemNO" : 1002, "bid" : 600, "bid_date" : "1999-02-16"} +{"userID" : "U03", "itemNO" : 1002, "bid" : 800, "bid_date" : "1999-02-17"} +{"userID" : "U04", "itemNO" : 1002, "bid" : 1000, "bid_date" : "1999-02-25"} +{"userID" : "U02", "itemNO" : 1002, "bid" : 1200, "bid_date" : "1999-03-02"} +{"userID" : "U04", "itemNO" : 1003, "bid" : 15, "bid_date" : "1999-01-22"} +{"userID" : "U05", "itemNO" : 1003, "bid" : 20, "bid_date" : "1999-02-03"} +{"userID" : "U01", "itemNO" : 1004, "bid" : 40, "bid_date" : "1999-03-05"} +{"userID" : "U03", "itemNO" : 1007, "bid" : 175, "bid_date" : "1999-01-25"} +{"userID" : "U05", "itemNO" : 1007, "bid" : 200, "bid_date" : "1999-02-08"} +{"userID" : "U04", "itemNO" : 1007, "bid" : 225, "bid_date" : "1999-02-12"} \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/datasets/items.json b/src/test/resources/test_files/runtime/Updating/datasets/items.json new file mode 100644 index 0000000000..1c17b8a809 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/datasets/items.json @@ -0,0 +1,8 @@ +{"itemNO" : "1001", "description" : "Red Bicycle", "offered_by" : "U01", "start_date" : "1999-01-05", "end_date" : "1999-01-20", "reserve_price" : 40} +{"itemNO" : "1002", "description" : "Motorcycle", "offered_by" : "U02", "start_date" : "1999-02-11", "end_date" : "1999-03-15", "reserve_price" : 500} +{"itemNO" : "1003", "description" : "Old Bicycle", "offered_by" : "U02", "start_date" : "1999-01-10", "end_date" : "1999-02-20", "reserve_price" : 25} +{"itemNO" : "1004", "description" : "Tricycle", "offered_by" : "U01", "start_date" : "1999-02-25", "end_date" : "1999-03-08", "reserve_price" : 15} +{"itemNO" : "1005", "description" : "Tennis Racket", "offered_by" : "U03", "start_date" : "1999-03-19", "end_date" : "1999-04-30", "reserve_price" : 20} +{"itemNO" : "1006", "description" : "Helicopter", "offered_by" : "U03", "start_date" : "1999-05-05", "end_date" : "1999-05-25", "reserve_price" : 50000} +{"itemNO" : "1007", "description" : "Racing Bicycle", "offered_by" : "U04", "start_date" : "1999-01-20", "end_date" : "1999-02-20", "reserve_price" : 200} +{"itemNO" : "1008", "description" : "Broken Bicycle", "offered_by" : "U01", "start_date" : "1999-02-05", "end_date" : "1999-03-06", "reserve_price" : 25} \ No newline at end of file diff --git a/src/test/resources/test_files/runtime/Updating/datasets/users.json b/src/test/resources/test_files/runtime/Updating/datasets/users.json new file mode 100644 index 0000000000..6639704c8a --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/datasets/users.json @@ -0,0 +1,6 @@ +{"userID" : "U01", "name" : "Tom Jones", "rating" : "B"} +{"userID" : "U02", "name" : "Mary Doe", "rating" : "A"} +{"userID" : "U03", "name" : "Dee Linquent", "rating" : "D"} +{"userID" : "U04", "name" : "Roger Smith", "rating" : "C"} +{"userID" : "U05", "name" : "Jack Sprat", "rating" : "B"} +{"userID" : "U06", "name" : "Rip Van Winkle", "rating" : "B"} \ No newline at end of file From 80b13d5a58e1f5a406eade6b4eded25a22906bb1 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Thu, 25 May 2023 03:24:55 +0200 Subject: [PATCH 102/119] Add tests for transform with multiple copy vars --- .../test_files/runtime/Updating/SimpleTransform3.jq | 6 ++++++ .../test_files/runtime/Updating/SimpleTransform4.jq | 6 ++++++ 2 files changed, 12 insertions(+) create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleTransform3.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleTransform4.jq diff --git a/src/test/resources/test_files/runtime/Updating/SimpleTransform3.jq b/src/test/resources/test_files/runtime/Updating/SimpleTransform3.jq new file mode 100644 index 0000000000..aecef7a6c3 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleTransform3.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldRun; Output="([ 2, 3, 4 ], [ 5, 6, 7 ])" :) +copy json $je := [1 to 4], $ej := [5 to 8] +modify (delete json $je[[1]], delete json $ej[[4]]) +return ($je, $ej) + + diff --git a/src/test/resources/test_files/runtime/Updating/SimpleTransform4.jq b/src/test/resources/test_files/runtime/Updating/SimpleTransform4.jq new file mode 100644 index 0000000000..7760cd69b0 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleTransform4.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldRun; Output="([ 1, 2, 3, 4 ], [ 5, 6, 7, 8 ])" :) +copy json $je := [1 to 4], $ej := [5 to 8] +modify () +return ($je, $ej) + + From 9d79899d62f939d8045044b1eaf779795cd1bd58 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Thu, 25 May 2023 03:25:34 +0200 Subject: [PATCH 103/119] Add tests for referencing copy vars outside their scope --- .../test_files/runtime/Updating/SimpleTransformErr4.jq | 8 ++++++++ .../test_files/runtime/Updating/SimpleTransformErr5.jq | 6 ++++++ 2 files changed, 14 insertions(+) create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleTransformErr4.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleTransformErr5.jq diff --git a/src/test/resources/test_files/runtime/Updating/SimpleTransformErr4.jq b/src/test/resources/test_files/runtime/Updating/SimpleTransformErr4.jq new file mode 100644 index 0000000000..094d6170cf --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleTransformErr4.jq @@ -0,0 +1,8 @@ +(:JIQS: ShouldNotCompile; ErrorCode="XPST0008"; ErrorMetadata="LINE:6:COLUMN:7:" :) +let $x := (copy json $je := [1 to 4] + modify () + return $je +) +return $je + +(: copy variable referenced outside of transform :) diff --git a/src/test/resources/test_files/runtime/Updating/SimpleTransformErr5.jq b/src/test/resources/test_files/runtime/Updating/SimpleTransformErr5.jq new file mode 100644 index 0000000000..fc1f5e4422 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleTransformErr5.jq @@ -0,0 +1,6 @@ +(:JIQS: ShouldNotCompile; ErrorCode="XPST0008"; ErrorMetadata="LINE:2:COLUMN:34:" :) +copy json $je := [1 to 4], $ej := $je +modify () +return $ej + +(: copy declaration references value in same copy clause :) From 24406a53825b7d1c49c46e52ffae3a0d3863ab05 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Thu, 25 May 2023 03:28:07 +0200 Subject: [PATCH 104/119] Implement semantics for scoping copy vars outside of modify and return exprs --- .../compiler/ExecutionModeVisitor.java | 9 +++--- .../compiler/StaticContextVisitor.java | 29 +++++++++++++------ .../TransformExpressionIterator.java | 3 ++ 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java b/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java index 44cda153ac..8ed877f1f2 100644 --- a/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java +++ b/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java @@ -437,18 +437,19 @@ public StaticContext visitVariableDeclaration(VariableDeclaration variableDeclar @Override public StaticContext visitTransformExpression(TransformExpression expression, StaticContext argument) { + StaticContext innerContext = expression.getStaticContext(); for (CopyDeclaration copyDecl : expression.getCopyDeclarations()) { - this.visit(copyDecl.getSourceExpression(), null); + this.visit(copyDecl.getSourceExpression(), copyDecl.getSourceExpression().getStaticContext()); // first pass. - argument.setVariableStorageMode( + innerContext.setVariableStorageMode( copyDecl.getVariableName(), expression.getVariableHighestStorageMode(this.visitorConfig) ); } expression.initHighestExecutionMode(this.visitorConfig); - this.visit(expression.getModifyExpression(), argument); - this.visit(expression.getReturnExpression(), argument); + this.visit(expression.getModifyExpression(), innerContext); + this.visit(expression.getReturnExpression(), innerContext); return argument; } diff --git a/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java b/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java index 3d7fcd1921..f2f0e4d138 100644 --- a/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java +++ b/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java @@ -332,22 +332,33 @@ public StaticContext visitVariableDeclaration(VariableDeclaration variableDeclar @Override public StaticContext visitTransformExpression(TransformExpression expression, StaticContext argument) { + StaticContext result = argument; for (CopyDeclaration copyDecl : expression.getCopyDeclarations()) { - this.visit(copyDecl.getSourceExpression(), argument); - // first pass. - argument.addVariable( - copyDecl.getVariableName(), - copyDecl.getSourceSequenceType(), - expression.getMetadata() - ); + result = this.visitCopyDecl(copyDecl, result, argument); } - this.visit(expression.getModifyExpression(), argument); - this.visit(expression.getReturnExpression(), argument); + result = this.visit(expression.getModifyExpression(), result); + result = this.visit(expression.getReturnExpression(), result); + + expression.setStaticContext(result); return argument; } + private StaticContext visitCopyDecl(CopyDeclaration copyDeclaration, StaticContext argument, StaticContext copyContext) { + this.visit(copyDeclaration.getSourceExpression(), copyContext); + + StaticContext result = new StaticContext(argument); + result.addVariable( + copyDeclaration.getVariableName(), + copyDeclaration.getSourceSequenceType(), + copyDeclaration.getSourceExpression().getMetadata() + ); + copyDeclaration.getSourceSequenceType().resolve(copyContext, copyDeclaration.getSourceExpression().getMetadata()); + + return result; + } + @Override public StaticContext visitTypeDeclaration(TypeDeclaration declaration, StaticContext argument) { ItemType type = declaration.getDefinition(); diff --git a/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java index 739f673f43..8f8f232073 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java @@ -54,6 +54,9 @@ protected void openLocal() { @Override protected void closeLocal() { returnIterator.close(); + for (Name copyVar : copyDeclMap.keySet()) { + this.currentDynamicContextForLocalExecution.getVariableValues().removeVariable(copyVar); + } } @Override From d3e965dc00d5f291bbf107fab929011ba376e2b1 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sat, 27 May 2023 22:47:51 +0200 Subject: [PATCH 105/119] Create tests for XUDY0014 --- .../runtime/Updating/SimpleTransformErr6.jq | 8 ++++++++ .../runtime/Updating/SimpleTransformErr7.jq | 13 ++++++++++++ .../runtime/Updating/SimpleTransformErr8.jq | 20 +++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleTransformErr6.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleTransformErr7.jq create mode 100644 src/test/resources/test_files/runtime/Updating/SimpleTransformErr8.jq diff --git a/src/test/resources/test_files/runtime/Updating/SimpleTransformErr6.jq b/src/test/resources/test_files/runtime/Updating/SimpleTransformErr6.jq new file mode 100644 index 0000000000..ca753e463a --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleTransformErr6.jq @@ -0,0 +1,8 @@ +(:JIQS: ShouldCrash; ErrorCode="XUDY0014"; ErrorMetadata="LINE:4:COLUMN:17:" :) +let $x := [1 to 4] +let $y := copy json $je := [1 to 4] + modify delete json $x[[1]] + return $je +return $x + +(: target of modify is not same level copy var :) diff --git a/src/test/resources/test_files/runtime/Updating/SimpleTransformErr7.jq b/src/test/resources/test_files/runtime/Updating/SimpleTransformErr7.jq new file mode 100644 index 0000000000..bf4dcf480b --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleTransformErr7.jq @@ -0,0 +1,13 @@ +(:JIQS: ShouldCrash; ErrorCode="XUDY0014"; ErrorMetadata="LINE:6:COLUMN:15:" :) +copy json $je := [1 to 4] +modify ( + let $x := ( + copy json $ej := [5 to 8] + modify delete json $je[[1]] + return $ej + ) + return delete json $je[[2]] +) +return $je + +(: target of modify is not same level copy var :) diff --git a/src/test/resources/test_files/runtime/Updating/SimpleTransformErr8.jq b/src/test/resources/test_files/runtime/Updating/SimpleTransformErr8.jq new file mode 100644 index 0000000000..4d017fbb73 --- /dev/null +++ b/src/test/resources/test_files/runtime/Updating/SimpleTransformErr8.jq @@ -0,0 +1,20 @@ +(:JIQS: ShouldCrash; ErrorCode="XUDY0014"; ErrorMetadata="LINE:9:COLUMN:27:" :) +copy json $je := [1 to 4] +modify ( + let $x := ( + copy json $ej := [5 to 8] + modify ( + let $x := ( + copy json $ee := [5 to 8] + modify delete json $je[[1]] + return $ee + ) + return delete json $ej[[2]] + ) + return $ej + ) + return delete json $je[[2]] +) +return $je + +(: target of modify is not same level copy var :) From 2d281f54fa568207a1a53034150225c447aa63b7 Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sat, 27 May 2023 22:50:59 +0200 Subject: [PATCH 106/119] Implement semantics for XUDY0014 with currentMutabilityLevel and getter & setters --- src/main/java/org/rumbledb/api/Item.java | 17 +++++++++++++++++ .../compiler/RuntimeIteratorVisitor.java | 1 + .../compiler/StaticContextVisitor.java | 3 +++ .../org/rumbledb/context/DynamicContext.java | 13 +++++++++++++ .../org/rumbledb/context/StaticContext.java | 13 +++++++++++++ .../update/TransformExpression.java | 10 ++++++++++ .../java/org/rumbledb/items/ArrayItem.java | 17 +++++++++++++++++ .../java/org/rumbledb/items/ObjectItem.java | 19 ++++++++++++++++++- .../expression/AppendExpressionIterator.java | 5 ++++- .../expression/DeleteExpressionIterator.java | 6 ++++++ .../expression/InsertExpressionIterator.java | 6 ++++++ .../expression/RenameExpressionIterator.java | 3 +++ .../expression/ReplaceExpressionIterator.java | 6 ++++++ .../TransformExpressionIterator.java | 12 +++++++++--- 14 files changed, 126 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/rumbledb/api/Item.java b/src/main/java/org/rumbledb/api/Item.java index 20581464ad..3790e1d603 100644 --- a/src/main/java/org/rumbledb/api/Item.java +++ b/src/main/java/org/rumbledb/api/Item.java @@ -686,6 +686,23 @@ default boolean isNaN() { throw new UnsupportedOperationException("Operation not defined for type " + this.getDynamicType()); } + /** + * Returns the mutability level of the item. + * + * @return int representing nestedness of the item inside transform expressions. + */ + default int getMutabilityLevel() { + return 0; + } + + /** + * Returns the mutability level of the item. + * + * @return int representing nestedness of the item inside transform expressions. + */ + default void setMutabilityLevel(int mutabilityLevel) { + } + /** * Tests for logical equality. The semantics are that of the eq operator. * diff --git a/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java b/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java index 7b3f95eb90..6b623e0ba2 100644 --- a/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java +++ b/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java @@ -451,6 +451,7 @@ public RuntimeIterator visitTransformExpression(TransformExpression expression, modifyIterator, returnIterator, expression.getHighestExecutionMode(this.visitorConfig), + expression.getMutabilityLevel(), expression.getMetadata() ); runtimeIterator.setStaticContext(expression.getStaticContext()); diff --git a/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java b/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java index f2f0e4d138..7abe3ea775 100644 --- a/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java +++ b/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java @@ -332,6 +332,7 @@ public StaticContext visitVariableDeclaration(VariableDeclaration variableDeclar @Override public StaticContext visitTransformExpression(TransformExpression expression, StaticContext argument) { + argument.setCurrentMutabilityLevel(argument.getCurrentMutabilityLevel() + 1); StaticContext result = argument; for (CopyDeclaration copyDecl : expression.getCopyDeclarations()) { result = this.visitCopyDecl(copyDecl, result, argument); @@ -341,7 +342,9 @@ public StaticContext visitTransformExpression(TransformExpression expression, St result = this.visit(expression.getReturnExpression(), result); expression.setStaticContext(result); + expression.setMutabilityLevel(result.getCurrentMutabilityLevel()); + argument.setCurrentMutabilityLevel(argument.getCurrentMutabilityLevel() - 1); return argument; } diff --git a/src/main/java/org/rumbledb/context/DynamicContext.java b/src/main/java/org/rumbledb/context/DynamicContext.java index e4e998f3ec..444a0a265e 100644 --- a/src/main/java/org/rumbledb/context/DynamicContext.java +++ b/src/main/java/org/rumbledb/context/DynamicContext.java @@ -46,6 +46,7 @@ public class DynamicContext implements Serializable, KryoSerializable { private NamedFunctions namedFunctions; private InScopeSchemaTypes inScopeSchemaTypes; private DateTime currentDateTime; + private int currentMutabilityLevel; /** * The default constructor is for Kryo deserialization purposes. @@ -57,6 +58,7 @@ public DynamicContext() { this.namedFunctions = null; this.inScopeSchemaTypes = null; this.currentDateTime = new DateTime(); + this.currentMutabilityLevel = 0; } /** @@ -71,6 +73,7 @@ public DynamicContext(RumbleRuntimeConfiguration conf) { this.namedFunctions = new NamedFunctions(); this.inScopeSchemaTypes = new InScopeSchemaTypes(); this.currentDateTime = new DateTime(); + this.currentMutabilityLevel = 0; } public DynamicContext(DynamicContext parent) { @@ -82,6 +85,7 @@ public DynamicContext(DynamicContext parent) { this.conf = null; this.namedFunctions = null; this.inScopeSchemaTypes = null; + this.currentMutabilityLevel = parent.getCurrentMutabilityLevel(); } public DynamicContext( @@ -101,6 +105,7 @@ public DynamicContext( dataFrameVariableValues ); this.namedFunctions = null; + this.currentMutabilityLevel = parent.getCurrentMutabilityLevel(); } public RumbleRuntimeConfiguration getRumbleRuntimeConfiguration() { @@ -129,6 +134,14 @@ public void read(Kryo kryo, Input input) { this.variableValues = kryo.readObject(input, VariableValues.class); } + public int getCurrentMutabilityLevel() { + return this.currentMutabilityLevel; + } + + public void setCurrentMutabilityLevel(int currentMutabilityLevel) { + this.currentMutabilityLevel = currentMutabilityLevel; + } + public enum VariableDependency { FULL, COUNT, diff --git a/src/main/java/org/rumbledb/context/StaticContext.java b/src/main/java/org/rumbledb/context/StaticContext.java index e8d6cf0eea..03bedf89c5 100644 --- a/src/main/java/org/rumbledb/context/StaticContext.java +++ b/src/main/java/org/rumbledb/context/StaticContext.java @@ -60,6 +60,8 @@ public class StaticContext implements Serializable, KryoSerializable { private static final Map defaultBindings; + private int currentMutabilityLevel; + static { defaultBindings = new HashMap<>(); defaultBindings.put("local", Name.LOCAL_NS); @@ -83,6 +85,7 @@ public StaticContext() { this.contextItemStaticType = null; this.configuration = null; this.inScopeSchemaTypes = null; + this.currentMutabilityLevel = 0; } public StaticContext(URI staticBaseURI, RumbleRuntimeConfiguration configuration) { @@ -95,6 +98,7 @@ public StaticContext(URI staticBaseURI, RumbleRuntimeConfiguration configuration this.contextItemStaticType = null; this.staticallyKnownFunctionSignatures = new HashMap<>(); this.inScopeSchemaTypes = new InScopeSchemaTypes(); + this.currentMutabilityLevel = 0; } public StaticContext(StaticContext parent) { @@ -105,6 +109,7 @@ public StaticContext(StaticContext parent) { this.staticallyKnownFunctionSignatures = new HashMap<>(); this.configuration = null; this.inScopeSchemaTypes = null; + this.currentMutabilityLevel = parent.currentMutabilityLevel; } public StaticContext getParent() { @@ -419,4 +424,12 @@ public InScopeSchemaTypes getInScopeSchemaTypes() { } throw new OurBadException("In-scope schema types are not set up properly in static context."); } + + public int getCurrentMutabilityLevel() { + return currentMutabilityLevel; + } + + public void setCurrentMutabilityLevel(int currentMutabilityLevel) { + this.currentMutabilityLevel = currentMutabilityLevel; + } } diff --git a/src/main/java/org/rumbledb/expressions/update/TransformExpression.java b/src/main/java/org/rumbledb/expressions/update/TransformExpression.java index b824100946..4aebcfc0b9 100644 --- a/src/main/java/org/rumbledb/expressions/update/TransformExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/TransformExpression.java @@ -15,6 +15,7 @@ public class TransformExpression extends Expression { private List copyDeclarations; private Expression modifyExpression; private Expression returnExpression; + private int mutabilityLevel; protected ExecutionMode variableHighestStorageMode = ExecutionMode.UNSET; @@ -31,6 +32,7 @@ public TransformExpression( this.copyDeclarations = copyDeclarations; this.modifyExpression = modifyExpression; this.returnExpression = returnExpression; + this.mutabilityLevel = 0; } public List getCopyDeclarations() { @@ -99,4 +101,12 @@ public void serializeToJSONiq(StringBuffer sb, int indent) { this.returnExpression.serializeToJSONiq(sb, 0); sb.append("\n"); } + + public int getMutabilityLevel() { + return this.mutabilityLevel; + } + + public void setMutabilityLevel(int mutabilityLevel) { + this.mutabilityLevel = mutabilityLevel; + } } diff --git a/src/main/java/org/rumbledb/items/ArrayItem.java b/src/main/java/org/rumbledb/items/ArrayItem.java index b213dbf35c..ee8d7815c1 100644 --- a/src/main/java/org/rumbledb/items/ArrayItem.java +++ b/src/main/java/org/rumbledb/items/ArrayItem.java @@ -35,14 +35,18 @@ public class ArrayItem implements Item { private static final long serialVersionUID = 1L; private List arrayItems; + private int mutabilityLevel; + public ArrayItem() { super(); this.arrayItems = new ArrayList<>(); + this.mutabilityLevel = 0; } public ArrayItem(List arrayItems) { super(); this.arrayItems = arrayItems; + this.mutabilityLevel = 0; } public boolean equals(Object otherItem) { @@ -137,4 +141,17 @@ public ItemType getDynamicType() { public boolean getEffectiveBooleanValue() { return true; } + + @Override + public int getMutabilityLevel() { + return this.mutabilityLevel; + } + + @Override + public void setMutabilityLevel(int mutabilityLevel) { + this.mutabilityLevel = mutabilityLevel; + for (Item item : arrayItems) { + item.setMutabilityLevel(mutabilityLevel); + } + } } diff --git a/src/main/java/org/rumbledb/items/ObjectItem.java b/src/main/java/org/rumbledb/items/ObjectItem.java index 3155bd9f7e..5705141fcc 100644 --- a/src/main/java/org/rumbledb/items/ObjectItem.java +++ b/src/main/java/org/rumbledb/items/ObjectItem.java @@ -38,10 +38,13 @@ public class ObjectItem implements Item { private List values; private List keys; + private int mutabilityLevel; + public ObjectItem() { super(); this.keys = new ArrayList<>(); this.values = new ArrayList<>(); + this.mutabilityLevel = 0; } public ObjectItem(List keys, List values, ExceptionMetadata itemMetadata) { @@ -49,6 +52,7 @@ public ObjectItem(List keys, List values, ExceptionMetadata itemMe checkForDuplicateKeys(keys, itemMetadata); this.keys = keys; this.values = values; + this.mutabilityLevel = 0; } public boolean equals(Object otherItem) { @@ -111,6 +115,7 @@ public ObjectItem(Map> keyValuePairs) { this.keys = keyList; this.values = valueList; + this.mutabilityLevel = 0; } @Override @@ -195,4 +200,16 @@ public ItemType getDynamicType() { public boolean getEffectiveBooleanValue() { return true; } -} + + @Override + public int getMutabilityLevel() { + return this.mutabilityLevel; + } + @Override + public void setMutabilityLevel(int mutabilityLevel) { + this.mutabilityLevel = mutabilityLevel; + for (Item item : values) { + item.setMutabilityLevel(mutabilityLevel); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java index f40412cd1d..b079f777f2 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java @@ -14,7 +14,7 @@ import java.util.Arrays; import java.util.Collections; -import java.util.List; + public class AppendExpressionIterator extends HybridRuntimeIterator { @@ -76,6 +76,9 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { UpdatePrimitive up; if (target.isArray()) { Item locator = ItemFactory.getInstance().createIntItem(target.getSize() + 1); + if (target.getMutabilityLevel() != context.getCurrentMutabilityLevel()) { + throw new TransformModifiesNonCopiedValueException("Attempt to modify currently immutable target", this.getMetadata()); + } up = factory.createInsertIntoArrayPrimitive(target, locator, Collections.singletonList(content)); } else { throw new InvalidUpdateTargetException("Append expression target must be a single array", this.getMetadata()); diff --git a/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java index c7d05275d1..e93f179cd3 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java @@ -75,11 +75,17 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { if (!lookup.isString()) { throw new CannotCastUpdateSelectorException("Delete expression selection cannot be cast to String type", this.getMetadata()); } + if (main.getMutabilityLevel() != context.getCurrentMutabilityLevel()) { + throw new TransformModifiesNonCopiedValueException("Attempt to modify currently immutable target", this.getMetadata()); + } up = factory.createDeleteFromObjectPrimitive(main, Collections.singletonList(lookup), this.getMetadata()); } else if (main.isArray()) { if (!lookup.isInt()) { throw new CannotCastUpdateSelectorException("Delete expression selection cannot be cast to Int type", this.getMetadata()); } + if (main.getMutabilityLevel() != context.getCurrentMutabilityLevel()) { + throw new TransformModifiesNonCopiedValueException("Attempt to modify currently immutable target", this.getMetadata()); + } up = factory.createDeleteFromArrayPrimitive(main, lookup, this.getMetadata()); } else { throw new InvalidUpdateTargetException("Delete expression target must be a single array or object", this.getMetadata()); diff --git a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java index 9bd9213693..c144172f01 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java @@ -97,6 +97,9 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { if (!content.isObject()) { throw new ObjectInsertContentIsNotObjectSeqException("Insert expression content is not an object", this.getMetadata()); } + if (main.getMutabilityLevel() != context.getCurrentMutabilityLevel()) { + throw new TransformModifiesNonCopiedValueException("Attempt to modify currently immutable target", this.getMetadata()); + } up = factory.createInsertIntoObjectPrimitive(main, content); } else if (main.isArray()) { if (locator == null) { @@ -105,6 +108,9 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { if (!locator.isInt()) { throw new CannotCastUpdateSelectorException("Insert expression selector cannot be cast to Int type", this.getMetadata()); } + if (main.getMutabilityLevel() != context.getCurrentMutabilityLevel()) { + throw new TransformModifiesNonCopiedValueException("Attempt to modify currently immutable target", this.getMetadata()); + } up = factory.createInsertIntoArrayPrimitive(main, locator, Collections.singletonList(content)); } else { throw new InvalidUpdateTargetException("Insert expression target must be a single array or object", this.getMetadata()); diff --git a/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java index f8e9c90a98..146f4a4c14 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java @@ -84,6 +84,9 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { if (!locator.isString()) { throw new CannotCastUpdateSelectorException("Rename expression selection cannot be cast to String type", this.getMetadata()); } + if (target.getMutabilityLevel() != context.getCurrentMutabilityLevel()) { + throw new TransformModifiesNonCopiedValueException("Attempt to modify currently immutable target", this.getMetadata()); + } up = factory.createRenameInObjectPrimitive(target, locator, content, this.getMetadata()); } else { throw new InvalidUpdateTargetException("Rename expression target must be a single object", this.getMetadata()); diff --git a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java index 1e1d36997d..2f48995059 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java @@ -97,11 +97,17 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { if (!locator.isString()) { throw new CannotCastUpdateSelectorException("Replace expression selection cannot be cast to String type", this.getMetadata()); } + if (target.getMutabilityLevel() != context.getCurrentMutabilityLevel()) { + throw new TransformModifiesNonCopiedValueException("Attempt to modify currently immutable target", this.getMetadata()); + } up = factory.createReplaceInObjectPrimitive(target, locator, content, this.getMetadata()); } else if (target.isArray()) { if (!locator.isInt()) { throw new CannotCastUpdateSelectorException("Replace expression selection cannot be cast to Int type", this.getMetadata()); } + if (target.getMutabilityLevel() != context.getCurrentMutabilityLevel()) { + throw new TransformModifiesNonCopiedValueException("Attempt to modify currently immutable target", this.getMetadata()); + } up = factory.createReplaceInArrayPrimitive(target, locator, content, this.getMetadata()); } else { throw new InvalidUpdateTargetException("Replace expression target must be a single array or object", this.getMetadata()); diff --git a/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java index 8f8f232073..973dcd7b5d 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java @@ -24,7 +24,9 @@ public class TransformExpressionIterator extends HybridRuntimeIterator { private RuntimeIterator modifyIterator; private RuntimeIterator returnIterator; - public TransformExpressionIterator(Map copyDeclMap, RuntimeIterator modifyIterator, RuntimeIterator returnIterator, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { + private int mutabilityLevel; + + public TransformExpressionIterator(Map copyDeclMap, RuntimeIterator modifyIterator, RuntimeIterator returnIterator, ExecutionMode executionMode, int mutabilityLevel, ExceptionMetadata iteratorMetadata) { super(null, executionMode, iteratorMetadata); this.children.addAll(copyDeclMap.values()); this.children.add(modifyIterator); @@ -33,7 +35,7 @@ public TransformExpressionIterator(Map copyDeclMap, Runti this.copyDeclMap = copyDeclMap; this.modifyIterator = modifyIterator; this.returnIterator = returnIterator; -// this.updateContext = null; + this.mutabilityLevel = mutabilityLevel; this.isUpdating = false; } @@ -79,6 +81,7 @@ protected Item nextLocal() { @Override public PendingUpdateList getPendingUpdateList(DynamicContext context) { bindCopyDeclarations(context); + context.setCurrentMutabilityLevel(this.mutabilityLevel); return modifyIterator.getPendingUpdateList(context); } @@ -87,8 +90,11 @@ private void bindCopyDeclarations(DynamicContext context) { RuntimeIterator copyIterator = copyDeclMap.get(copyVar); List toCopy = copyIterator.materialize(context); List copy = new ArrayList<>(); + Item temp; for (Item item : toCopy) { - copy.add((Item) SerializationUtils.clone(item)); + temp = (Item) SerializationUtils.clone(item); + temp.setMutabilityLevel(this.mutabilityLevel); + copy.add(temp); } context.getVariableValues().addVariableValue(copyVar, copy); } From 9895c7ca7c94bd00fd2a2937bbb915f0f8ea382a Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sat, 27 May 2023 22:54:22 +0200 Subject: [PATCH 107/119] Fix test to coincide with changes for XUDY0014 --- .../resources/test_files/runtime/Updating/SimpleAppendErr1.jq | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/resources/test_files/runtime/Updating/SimpleAppendErr1.jq b/src/test/resources/test_files/runtime/Updating/SimpleAppendErr1.jq index 091bbd3ec9..2b1956b8d5 100644 --- a/src/test/resources/test_files/runtime/Updating/SimpleAppendErr1.jq +++ b/src/test/resources/test_files/runtime/Updating/SimpleAppendErr1.jq @@ -1,6 +1,6 @@ (:JIQS: ShouldCrash; ErrorCode="JNUP0008"; ErrorMetadata="LINE:3:COLUMN:7:" :) -copy json $je := { "a" : 1, "b" : 2, "c" : 3 } -modify append json 5 into false +copy json $je := false +modify append json 5 into $je return $je (: target expr does not evaluate to array :) \ No newline at end of file From 248ecd648e592e3587fff10063dd3c57fe8e4d5c Mon Sep 17 00:00:00 2001 From: dloughlin Date: Sun, 28 May 2023 16:16:17 +0200 Subject: [PATCH 108/119] Apply spotless --- .../compiler/DynamicContextVisitor.java | 35 +++++------ .../compiler/RuntimeIteratorVisitor.java | 5 +- .../compiler/StaticContextVisitor.java | 15 +++-- .../DuplicateKeyOnUpdateApplyException.java | 8 ++- .../DuplicateObjectInsertSourceException.java | 6 +- ...yRenamesOnSameTargetSelectorException.java | 6 +- ...ReplacesOnSameTargetSelectorException.java | 12 ++-- .../expressions/update/DeleteExpression.java | 1 + .../java/org/rumbledb/items/ObjectItem.java | 3 +- .../control/TypeswitchRuntimeIterator.java | 16 ++--- .../clauses/ReturnClauseSparkIterator.java | 10 ++- .../runtime/update/PendingUpdateList.java | 61 +++++++++++++------ .../expression/AppendExpressionIterator.java | 17 +++++- .../expression/DeleteExpressionIterator.java | 32 ++++++++-- .../expression/InsertExpressionIterator.java | 45 ++++++++++---- .../expression/RenameExpressionIterator.java | 26 +++++--- .../expression/ReplaceExpressionIterator.java | 33 ++++++++-- .../TransformExpressionIterator.java | 12 ++-- .../primitives/DeleteFromArrayPrimitive.java | 6 +- .../primitives/DeleteFromObjectPrimitive.java | 9 +-- .../primitives/InsertIntoArrayPrimitive.java | 1 - .../primitives/RenameInObjectPrimitive.java | 13 +++- .../primitives/ReplaceInArrayPrimitive.java | 13 +++- .../primitives/ReplaceInObjectPrimitive.java | 13 +++- .../update/primitives/UpdatePrimitive.java | 8 ++- .../primitives/UpdatePrimitiveFactory.java | 33 ++++++++-- 26 files changed, 306 insertions(+), 133 deletions(-) diff --git a/src/main/java/org/rumbledb/compiler/DynamicContextVisitor.java b/src/main/java/org/rumbledb/compiler/DynamicContextVisitor.java index 0e724947e0..ccfe657783 100644 --- a/src/main/java/org/rumbledb/compiler/DynamicContextVisitor.java +++ b/src/main/java/org/rumbledb/compiler/DynamicContextVisitor.java @@ -41,15 +41,12 @@ import org.rumbledb.expressions.AbstractNodeVisitor; import org.rumbledb.expressions.Expression; import org.rumbledb.expressions.Node; -import org.rumbledb.expressions.flowr.ReturnClause; import org.rumbledb.expressions.module.FunctionDeclaration; import org.rumbledb.expressions.module.LibraryModule; import org.rumbledb.expressions.module.Prolog; import org.rumbledb.expressions.module.TypeDeclaration; import org.rumbledb.expressions.module.VariableDeclaration; import org.rumbledb.expressions.primary.InlineFunctionExpression; -import org.rumbledb.expressions.update.CopyDeclaration; -import org.rumbledb.expressions.update.TransformExpression; import org.rumbledb.items.ItemFactory; import org.rumbledb.items.parsing.ItemParser; import org.rumbledb.runtime.RuntimeIterator; @@ -116,22 +113,22 @@ public DynamicContext visitFunctionDeclaration(FunctionDeclaration declaration, return defaultAction(expression, argument); } -// @Override -// public DynamicContext visitTransformExpression(TransformExpression expression, DynamicContext argument) { -// -// for (CopyDeclaration copyDecl : expression.getCopyDeclarations()) { -// Expression child = copyDecl.getSourceExpression(); -// this.visit(child, argument); -// RuntimeIterator iterator = VisitorHelpers.generateRuntimeIterator(child, this.configuration); -// iterator.bindToVariableInDynamicContext(argument, copyDecl.getVariableName(), argument); -// } -// -// this.visit(expression.getModifyExpression(), argument); -// -// this.visit(expression.getReturnExpression(), argument); -// -// return argument; -// } + // @Override + // public DynamicContext visitTransformExpression(TransformExpression expression, DynamicContext argument) { + // + // for (CopyDeclaration copyDecl : expression.getCopyDeclarations()) { + // Expression child = copyDecl.getSourceExpression(); + // this.visit(child, argument); + // RuntimeIterator iterator = VisitorHelpers.generateRuntimeIterator(child, this.configuration); + // iterator.bindToVariableInDynamicContext(argument, copyDecl.getVariableName(), argument); + // } + // + // this.visit(expression.getModifyExpression(), argument); + // + // this.visit(expression.getReturnExpression(), argument); + // + // return argument; + // } @Override public DynamicContext visitVariableDeclaration(VariableDeclaration variableDeclaration, DynamicContext argument) { diff --git a/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java b/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java index 6b623e0ba2..6308988ef1 100644 --- a/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java +++ b/src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java @@ -139,7 +139,6 @@ import org.rumbledb.runtime.primary.ObjectConstructorRuntimeIterator; import org.rumbledb.runtime.primary.StringRuntimeIterator; import org.rumbledb.runtime.primary.VariableReferenceIterator; -import org.rumbledb.runtime.update.PendingUpdateList; import org.rumbledb.runtime.update.expression.*; import org.rumbledb.types.BuiltinTypesCatalogue; import org.rumbledb.types.SequenceType; @@ -401,7 +400,9 @@ public RuntimeIterator visitInsertExpression(InsertExpression expression, Runtim RuntimeIterator mainIterator = this.visit(expression.getMainExpression(), argument); RuntimeIterator toInsertIterator = this.visit(expression.getToInsertExpression(), argument); - RuntimeIterator positionIterator = expression.hasPositionExpression() ? this.visit(expression.getPositionExpression(), argument) : null; + RuntimeIterator positionIterator = expression.hasPositionExpression() + ? this.visit(expression.getPositionExpression(), argument) + : null; RuntimeIterator runtimeIterator = new InsertExpressionIterator( mainIterator, diff --git a/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java b/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java index 7abe3ea775..b5aadf72fc 100644 --- a/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java +++ b/src/main/java/org/rumbledb/compiler/StaticContextVisitor.java @@ -348,16 +348,21 @@ public StaticContext visitTransformExpression(TransformExpression expression, St return argument; } - private StaticContext visitCopyDecl(CopyDeclaration copyDeclaration, StaticContext argument, StaticContext copyContext) { + private StaticContext visitCopyDecl( + CopyDeclaration copyDeclaration, + StaticContext argument, + StaticContext copyContext + ) { this.visit(copyDeclaration.getSourceExpression(), copyContext); StaticContext result = new StaticContext(argument); result.addVariable( - copyDeclaration.getVariableName(), - copyDeclaration.getSourceSequenceType(), - copyDeclaration.getSourceExpression().getMetadata() + copyDeclaration.getVariableName(), + copyDeclaration.getSourceSequenceType(), + copyDeclaration.getSourceExpression().getMetadata() ); - copyDeclaration.getSourceSequenceType().resolve(copyContext, copyDeclaration.getSourceExpression().getMetadata()); + copyDeclaration.getSourceSequenceType() + .resolve(copyContext, copyDeclaration.getSourceExpression().getMetadata()); return result; } diff --git a/src/main/java/org/rumbledb/exceptions/DuplicateKeyOnUpdateApplyException.java b/src/main/java/org/rumbledb/exceptions/DuplicateKeyOnUpdateApplyException.java index e29f2cd4ac..89de47398a 100644 --- a/src/main/java/org/rumbledb/exceptions/DuplicateKeyOnUpdateApplyException.java +++ b/src/main/java/org/rumbledb/exceptions/DuplicateKeyOnUpdateApplyException.java @@ -8,9 +8,11 @@ public class DuplicateKeyOnUpdateApplyException extends RumbleException { public DuplicateKeyOnUpdateApplyException(String keyInfo, ExceptionMetadata metadata) { super( - "Dynamic Updating error; Duplicate keys inserted into target object during update application: " + keyInfo + ".", - ErrorCode.DuplicateKeyOnUpdateApplyErrorCode, - metadata + "Dynamic Updating error; Duplicate keys inserted into target object during update application: " + + keyInfo + + ".", + ErrorCode.DuplicateKeyOnUpdateApplyErrorCode, + metadata ); } } diff --git a/src/main/java/org/rumbledb/exceptions/DuplicateObjectInsertSourceException.java b/src/main/java/org/rumbledb/exceptions/DuplicateObjectInsertSourceException.java index 6bfaa262fb..fbaffcd384 100644 --- a/src/main/java/org/rumbledb/exceptions/DuplicateObjectInsertSourceException.java +++ b/src/main/java/org/rumbledb/exceptions/DuplicateObjectInsertSourceException.java @@ -8,9 +8,9 @@ public class DuplicateObjectInsertSourceException extends RumbleException { public DuplicateObjectInsertSourceException(String keyInfo, ExceptionMetadata metadata) { super( - "Dynamic Updating error; Duplicate keys to insert into object: " + keyInfo + ".", - ErrorCode.DuplicateObjectInsertSourceErrorCode, - metadata + "Dynamic Updating error; Duplicate keys to insert into object: " + keyInfo + ".", + ErrorCode.DuplicateObjectInsertSourceErrorCode, + metadata ); } diff --git a/src/main/java/org/rumbledb/exceptions/TooManyRenamesOnSameTargetSelectorException.java b/src/main/java/org/rumbledb/exceptions/TooManyRenamesOnSameTargetSelectorException.java index 65bd8b1f89..727874a373 100644 --- a/src/main/java/org/rumbledb/exceptions/TooManyRenamesOnSameTargetSelectorException.java +++ b/src/main/java/org/rumbledb/exceptions/TooManyRenamesOnSameTargetSelectorException.java @@ -8,9 +8,9 @@ public class TooManyRenamesOnSameTargetSelectorException extends RumbleException public TooManyRenamesOnSameTargetSelectorException(String keyInfo, ExceptionMetadata metadata) { super( - "Dynamic Updating error; Too many renames on same object at key: " + keyInfo + ".", - ErrorCode.TooManyRenamesOnSameTargetSelectorErrorCode, - metadata + "Dynamic Updating error; Too many renames on same object at key: " + keyInfo + ".", + ErrorCode.TooManyRenamesOnSameTargetSelectorErrorCode, + metadata ); } diff --git a/src/main/java/org/rumbledb/exceptions/TooManyReplacesOnSameTargetSelectorException.java b/src/main/java/org/rumbledb/exceptions/TooManyReplacesOnSameTargetSelectorException.java index 7f7808383e..3808044f5f 100644 --- a/src/main/java/org/rumbledb/exceptions/TooManyReplacesOnSameTargetSelectorException.java +++ b/src/main/java/org/rumbledb/exceptions/TooManyReplacesOnSameTargetSelectorException.java @@ -6,11 +6,15 @@ public class TooManyReplacesOnSameTargetSelectorException extends RumbleExceptio private static final long serialVersionUID = 1L; - public TooManyReplacesOnSameTargetSelectorException(String targetInfo, String selectorInfo, ExceptionMetadata metadata) { + public TooManyReplacesOnSameTargetSelectorException( + String targetInfo, + String selectorInfo, + ExceptionMetadata metadata + ) { super( - "Dynamic Updating error; Too many replaces on " + targetInfo + " at: " + selectorInfo + ".", - ErrorCode.TooManyReplacesOnSameTargetSelectorErrorCode, - metadata + "Dynamic Updating error; Too many replaces on " + targetInfo + " at: " + selectorInfo + ".", + ErrorCode.TooManyReplacesOnSameTargetSelectorErrorCode, + metadata ); } } diff --git a/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java b/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java index 2882473bb4..57e5368496 100644 --- a/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/DeleteExpression.java @@ -13,6 +13,7 @@ public class DeleteExpression extends Expression { private Expression mainExpression; private Expression locatorExpression; + public DeleteExpression( Expression mainExpression, Expression locatorExpression, diff --git a/src/main/java/org/rumbledb/items/ObjectItem.java b/src/main/java/org/rumbledb/items/ObjectItem.java index 5705141fcc..c6f535ac53 100644 --- a/src/main/java/org/rumbledb/items/ObjectItem.java +++ b/src/main/java/org/rumbledb/items/ObjectItem.java @@ -205,6 +205,7 @@ public boolean getEffectiveBooleanValue() { public int getMutabilityLevel() { return this.mutabilityLevel; } + @Override public void setMutabilityLevel(int mutabilityLevel) { this.mutabilityLevel = mutabilityLevel; @@ -212,4 +213,4 @@ public void setMutabilityLevel(int mutabilityLevel) { item.setMutabilityLevel(mutabilityLevel); } } -} \ No newline at end of file +} diff --git a/src/main/java/org/rumbledb/runtime/control/TypeswitchRuntimeIterator.java b/src/main/java/org/rumbledb/runtime/control/TypeswitchRuntimeIterator.java index 86c55cff75..1f8b23e60f 100644 --- a/src/main/java/org/rumbledb/runtime/control/TypeswitchRuntimeIterator.java +++ b/src/main/java/org/rumbledb/runtime/control/TypeswitchRuntimeIterator.java @@ -203,10 +203,10 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { if (localMatchingIterator != null) { if (typeSwitchCase.getVariableName() != null) { context.getVariableValues() - .addVariableValue( - typeSwitchCase.getVariableName(), - Collections.singletonList(this.testValue) - ); + .addVariableValue( + typeSwitchCase.getVariableName(), + Collections.singletonList(this.testValue) + ); } return localMatchingIterator.getPendingUpdateList(context); @@ -215,10 +215,10 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { if (this.defaultCase.getVariableName() != null) { context.getVariableValues() - .addVariableValue( - this.defaultCase.getVariableName(), - Collections.singletonList(this.testValue) - ); + .addVariableValue( + this.defaultCase.getVariableName(), + Collections.singletonList(this.testValue) + ); } return this.defaultCase.getReturnIterator().getPendingUpdateList(context); diff --git a/src/main/java/org/rumbledb/runtime/flwor/clauses/ReturnClauseSparkIterator.java b/src/main/java/org/rumbledb/runtime/flwor/clauses/ReturnClauseSparkIterator.java index fe6b670668..5819db7289 100644 --- a/src/main/java/org/rumbledb/runtime/flwor/clauses/ReturnClauseSparkIterator.java +++ b/src/main/java/org/rumbledb/runtime/flwor/clauses/ReturnClauseSparkIterator.java @@ -20,7 +20,6 @@ package org.rumbledb.runtime.flwor.clauses; -import org.apache.hadoop.yarn.webapp.hamlet2.Hamlet; import org.apache.log4j.LogManager; import org.apache.spark.api.java.JavaRDD; import org.apache.spark.sql.Dataset; @@ -399,10 +398,15 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { while (this.child.hasNext()) { FlworTuple tuple = this.child.next(); this.tupleContext.getVariableValues().removeAllVariables(); // clear the previous variables - this.tupleContext.getVariableValues().setBindingsFromTuple(tuple, getMetadata()); // assign new variables + this.tupleContext.getVariableValues().setBindingsFromTuple(tuple, getMetadata()); // assign new + // variables // from new tuple - result = PendingUpdateList.mergeUpdates(result, this.expression.getPendingUpdateList(this.tupleContext), this.getMetadata()); + result = PendingUpdateList.mergeUpdates( + result, + this.expression.getPendingUpdateList(this.tupleContext), + this.getMetadata() + ); } this.child.close(); diff --git a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java index cfec75912a..6e56434714 100644 --- a/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java +++ b/src/main/java/org/rumbledb/runtime/update/PendingUpdateList.java @@ -1,15 +1,11 @@ package org.rumbledb.runtime.update; -import org.apache.hadoop.mapred.lib.DelegatingInputFormat; import org.rumbledb.api.Item; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.exceptions.OurBadException; import org.rumbledb.exceptions.TooManyRenamesOnSameTargetSelectorException; import org.rumbledb.exceptions.TooManyReplacesOnSameTargetSelectorException; -import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.update.primitives.*; -import org.rumbledb.types.ItemType; -import shapeless.ops.zipper; import java.util.*; @@ -125,7 +121,9 @@ public void applyUpdates(ExceptionMetadata metadata) { for (Item target : renameObjMap.keySet()) { tempSelSrcMap = renameObjMap.get(target); for (Item locator : tempSelSrcMap.keySet()) { - objectPUL.add(upFactory.createRenameInObjectPrimitive(target, locator, tempSelSrcMap.get(locator), metadata)); + objectPUL.add( + upFactory.createRenameInObjectPrimitive(target, locator, tempSelSrcMap.get(locator), metadata) + ); } } @@ -144,7 +142,11 @@ public void applyUpdates(ExceptionMetadata metadata) { } else { up = upFactory.createReplaceInArrayPrimitive(target, locator, tempSrc, metadata); } - int index = Collections.binarySearch(tempArrayPULs, up, Comparator.comparing(UpdatePrimitive::getIntSelector)); + int index = Collections.binarySearch( + tempArrayPULs, + up, + Comparator.comparing(UpdatePrimitive::getIntSelector) + ); if (index < 0) { index = -index - 1; } @@ -161,7 +163,11 @@ public void applyUpdates(ExceptionMetadata metadata) { tempSelSrcListMap = insertArrayMap.get(target); for (Item locator : tempSelSrcListMap.keySet()) { up = upFactory.createInsertIntoArrayPrimitive(target, locator, tempSelSrcListMap.get(locator)); - int index = Collections.binarySearch(tempArrayPULs, up, Comparator.comparing(UpdatePrimitive::getIntSelector)); + int index = Collections.binarySearch( + tempArrayPULs, + up, + Comparator.comparing(UpdatePrimitive::getIntSelector) + ); if (index < 0) { index = -index - 1; } @@ -187,7 +193,11 @@ public void applyUpdates(ExceptionMetadata metadata) { } - public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpdateList pul2, ExceptionMetadata metadata) { + public static PendingUpdateList mergeUpdates( + PendingUpdateList pul1, + PendingUpdateList pul2, + ExceptionMetadata metadata + ) { PendingUpdateList res = new PendingUpdateList(); Map tempSelSrcMap; Map> tempSelSrcListMap; @@ -207,7 +217,7 @@ public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpda for (Item selector : tempSelSrcMap.keySet()) { tempSelSrcResMap.put(selector, tempSelSrcMap.get(selector)); } - res.delReplaceObjMap.put(target,tempSelSrcResMap); + res.delReplaceObjMap.put(target, tempSelSrcResMap); } for (Item target : pul2.delReplaceObjMap.keySet()) { @@ -218,13 +228,17 @@ public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpda if (tempSelSrcResMap.containsKey(selector)) { tempSrc = tempSelSrcResMap.get(selector); if (tempSrc != null) { - throw new TooManyReplacesOnSameTargetSelectorException(target.getDynamicType().getName().toString(), selector.getStringValue(), metadata); + throw new TooManyReplacesOnSameTargetSelectorException( + target.getDynamicType().getName().toString(), + selector.getStringValue(), + metadata + ); } continue; } tempSelSrcResMap.put(selector, tempSelSrcMap.get(selector)); } - res.delReplaceObjMap.put(target,tempSelSrcResMap); + res.delReplaceObjMap.put(target, tempSelSrcResMap); } // INSERTS @@ -236,7 +250,7 @@ public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpda if (res.insertObjMap.containsKey(target)) { tempSrc = InsertIntoObjectPrimitive.mergeSources(res.insertObjMap.get(target), tempSrc, metadata); } - res.insertObjMap.put(target,tempSrc); + res.insertObjMap.put(target, tempSrc); } // RENAME @@ -248,7 +262,7 @@ public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpda for (Item selector : tempSelSrcMap.keySet()) { tempSelSrcResMap.put(selector, tempSelSrcMap.get(selector)); } - res.renameObjMap.put(target,tempSelSrcResMap); + res.renameObjMap.put(target, tempSelSrcResMap); } for (Item target : pul2.renameObjMap.keySet()) { @@ -261,7 +275,7 @@ public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpda } tempSelSrcResMap.put(selector, tempSelSrcMap.get(selector)); } - res.renameObjMap.put(target,tempSelSrcResMap); + res.renameObjMap.put(target, tempSelSrcResMap); } ////// ARRAYS @@ -275,7 +289,7 @@ public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpda for (Item selector : tempSelSrcMap.keySet()) { tempSelSrcResMap.put(selector, tempSelSrcMap.get(selector)); } - res.delReplaceArrayMap.put(target,tempSelSrcResMap); + res.delReplaceArrayMap.put(target, tempSelSrcResMap); } for (Item target : pul2.delReplaceArrayMap.keySet()) { @@ -286,13 +300,17 @@ public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpda if (tempSelSrcResMap.containsKey(selector)) { tempSrc = tempSelSrcResMap.get(selector); if (tempSrc != null) { - throw new TooManyReplacesOnSameTargetSelectorException(target.getDynamicType().getName().toString(), Integer.toString(selector.getIntValue()), metadata); + throw new TooManyReplacesOnSameTargetSelectorException( + target.getDynamicType().getName().toString(), + Integer.toString(selector.getIntValue()), + metadata + ); } continue; } tempSelSrcResMap.put(selector, tempSelSrcMap.get(selector)); } - res.delReplaceArrayMap.put(target,tempSelSrcResMap); + res.delReplaceArrayMap.put(target, tempSelSrcResMap); } // INSERTS @@ -304,7 +322,7 @@ public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpda for (Item selector : tempSelSrcListMap.keySet()) { tempSelSrcResListMap.put(selector, tempSelSrcListMap.get(selector)); } - res.insertArrayMap.put(target,tempSelSrcResListMap); + res.insertArrayMap.put(target, tempSelSrcResListMap); } for (Item target : pul2.insertArrayMap.keySet()) { @@ -313,9 +331,12 @@ public static PendingUpdateList mergeUpdates(PendingUpdateList pul1, PendingUpda for (Item selector : tempSelSrcListMap.keySet()) { tempSrcList = tempSelSrcResListMap.getOrDefault(selector, new ArrayList<>()); - tempSelSrcResListMap.put(selector, InsertIntoArrayPrimitive.mergeSources( tempSrcList, tempSelSrcListMap.get(selector))); + tempSelSrcResListMap.put( + selector, + InsertIntoArrayPrimitive.mergeSources(tempSrcList, tempSelSrcListMap.get(selector)) + ); } - res.insertArrayMap.put(target,tempSelSrcResListMap); + res.insertArrayMap.put(target, tempSelSrcResListMap); } return res; diff --git a/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java index b079f777f2..6f49070d0b 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java @@ -21,7 +21,12 @@ public class AppendExpressionIterator extends HybridRuntimeIterator { private RuntimeIterator arrayIterator; private RuntimeIterator toAppendIterator; - public AppendExpressionIterator(RuntimeIterator arrayIterator, RuntimeIterator toAppendIterator, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { + public AppendExpressionIterator( + RuntimeIterator arrayIterator, + RuntimeIterator toAppendIterator, + ExecutionMode executionMode, + ExceptionMetadata iteratorMetadata + ) { super(Arrays.asList(arrayIterator, toAppendIterator), executionMode, iteratorMetadata); this.arrayIterator = arrayIterator; @@ -77,11 +82,17 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { if (target.isArray()) { Item locator = ItemFactory.getInstance().createIntItem(target.getSize() + 1); if (target.getMutabilityLevel() != context.getCurrentMutabilityLevel()) { - throw new TransformModifiesNonCopiedValueException("Attempt to modify currently immutable target", this.getMetadata()); + throw new TransformModifiesNonCopiedValueException( + "Attempt to modify currently immutable target", + this.getMetadata() + ); } up = factory.createInsertIntoArrayPrimitive(target, locator, Collections.singletonList(content)); } else { - throw new InvalidUpdateTargetException("Append expression target must be a single array", this.getMetadata()); + throw new InvalidUpdateTargetException( + "Append expression target must be a single array", + this.getMetadata() + ); } pul.addUpdatePrimitive(up); diff --git a/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java index e93f179cd3..49035acf09 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java @@ -19,7 +19,12 @@ public class DeleteExpressionIterator extends HybridRuntimeIterator { private RuntimeIterator mainIterator; private RuntimeIterator lookupIterator; - public DeleteExpressionIterator(RuntimeIterator mainIterator, RuntimeIterator lookupIterator, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { + public DeleteExpressionIterator( + RuntimeIterator mainIterator, + RuntimeIterator lookupIterator, + ExecutionMode executionMode, + ExceptionMetadata iteratorMetadata + ) { super(Arrays.asList(mainIterator, lookupIterator), executionMode, iteratorMetadata); this.mainIterator = mainIterator; this.lookupIterator = lookupIterator; @@ -73,22 +78,37 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { UpdatePrimitive up; if (main.isObject()) { if (!lookup.isString()) { - throw new CannotCastUpdateSelectorException("Delete expression selection cannot be cast to String type", this.getMetadata()); + throw new CannotCastUpdateSelectorException( + "Delete expression selection cannot be cast to String type", + this.getMetadata() + ); } if (main.getMutabilityLevel() != context.getCurrentMutabilityLevel()) { - throw new TransformModifiesNonCopiedValueException("Attempt to modify currently immutable target", this.getMetadata()); + throw new TransformModifiesNonCopiedValueException( + "Attempt to modify currently immutable target", + this.getMetadata() + ); } up = factory.createDeleteFromObjectPrimitive(main, Collections.singletonList(lookup), this.getMetadata()); } else if (main.isArray()) { if (!lookup.isInt()) { - throw new CannotCastUpdateSelectorException("Delete expression selection cannot be cast to Int type", this.getMetadata()); + throw new CannotCastUpdateSelectorException( + "Delete expression selection cannot be cast to Int type", + this.getMetadata() + ); } if (main.getMutabilityLevel() != context.getCurrentMutabilityLevel()) { - throw new TransformModifiesNonCopiedValueException("Attempt to modify currently immutable target", this.getMetadata()); + throw new TransformModifiesNonCopiedValueException( + "Attempt to modify currently immutable target", + this.getMetadata() + ); } up = factory.createDeleteFromArrayPrimitive(main, lookup, this.getMetadata()); } else { - throw new InvalidUpdateTargetException("Delete expression target must be a single array or object", this.getMetadata()); + throw new InvalidUpdateTargetException( + "Delete expression target must be a single array or object", + this.getMetadata() + ); } pul.addUpdatePrimitive(up); diff --git a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java index c144172f01..443e1a0cc3 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java @@ -12,10 +12,8 @@ import org.rumbledb.runtime.update.primitives.UpdatePrimitive; import org.rumbledb.runtime.update.primitives.UpdatePrimitiveFactory; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.List; public class InsertExpressionIterator extends HybridRuntimeIterator { @@ -23,13 +21,19 @@ public class InsertExpressionIterator extends HybridRuntimeIterator { private RuntimeIterator toInsertIterator; private RuntimeIterator positionIterator; - public InsertExpressionIterator(RuntimeIterator mainIterator, RuntimeIterator toInsertIterator, RuntimeIterator positionIterator, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { + public InsertExpressionIterator( + RuntimeIterator mainIterator, + RuntimeIterator toInsertIterator, + RuntimeIterator positionIterator, + ExecutionMode executionMode, + ExceptionMetadata iteratorMetadata + ) { super( - positionIterator == null - ? Arrays.asList(mainIterator, toInsertIterator) - : Arrays.asList(mainIterator, toInsertIterator, positionIterator), - executionMode, - iteratorMetadata + positionIterator == null + ? Arrays.asList(mainIterator, toInsertIterator) + : Arrays.asList(mainIterator, toInsertIterator, positionIterator), + executionMode, + iteratorMetadata ); this.mainIterator = mainIterator; @@ -95,10 +99,16 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { UpdatePrimitive up; if (main.isObject()) { if (!content.isObject()) { - throw new ObjectInsertContentIsNotObjectSeqException("Insert expression content is not an object", this.getMetadata()); + throw new ObjectInsertContentIsNotObjectSeqException( + "Insert expression content is not an object", + this.getMetadata() + ); } if (main.getMutabilityLevel() != context.getCurrentMutabilityLevel()) { - throw new TransformModifiesNonCopiedValueException("Attempt to modify currently immutable target", this.getMetadata()); + throw new TransformModifiesNonCopiedValueException( + "Attempt to modify currently immutable target", + this.getMetadata() + ); } up = factory.createInsertIntoObjectPrimitive(main, content); } else if (main.isArray()) { @@ -106,14 +116,23 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { throw new CannotCastUpdateSelectorException("Insert expression selector is null", this.getMetadata()); } if (!locator.isInt()) { - throw new CannotCastUpdateSelectorException("Insert expression selector cannot be cast to Int type", this.getMetadata()); + throw new CannotCastUpdateSelectorException( + "Insert expression selector cannot be cast to Int type", + this.getMetadata() + ); } if (main.getMutabilityLevel() != context.getCurrentMutabilityLevel()) { - throw new TransformModifiesNonCopiedValueException("Attempt to modify currently immutable target", this.getMetadata()); + throw new TransformModifiesNonCopiedValueException( + "Attempt to modify currently immutable target", + this.getMetadata() + ); } up = factory.createInsertIntoArrayPrimitive(main, locator, Collections.singletonList(content)); } else { - throw new InvalidUpdateTargetException("Insert expression target must be a single array or object", this.getMetadata()); + throw new InvalidUpdateTargetException( + "Insert expression target must be a single array or object", + this.getMetadata() + ); } pul.addUpdatePrimitive(up); diff --git a/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java index 146f4a4c14..1be250c45b 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java @@ -5,7 +5,6 @@ import org.rumbledb.context.DynamicContext; import org.rumbledb.exceptions.*; import org.rumbledb.expressions.ExecutionMode; -import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.HybridRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.update.PendingUpdateList; @@ -13,8 +12,6 @@ import org.rumbledb.runtime.update.primitives.UpdatePrimitiveFactory; import java.util.Arrays; -import java.util.Collections; -import java.util.List; public class RenameExpressionIterator extends HybridRuntimeIterator { @@ -22,7 +19,13 @@ public class RenameExpressionIterator extends HybridRuntimeIterator { private RuntimeIterator locatorIterator; private RuntimeIterator nameIterator; - public RenameExpressionIterator(RuntimeIterator mainIterator, RuntimeIterator locatorIterator, RuntimeIterator nameIterator, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { + public RenameExpressionIterator( + RuntimeIterator mainIterator, + RuntimeIterator locatorIterator, + RuntimeIterator nameIterator, + ExecutionMode executionMode, + ExceptionMetadata iteratorMetadata + ) { super(Arrays.asList(mainIterator, locatorIterator, nameIterator), executionMode, iteratorMetadata); this.mainIterator = mainIterator; @@ -82,14 +85,23 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { UpdatePrimitive up; if (target.isObject()) { if (!locator.isString()) { - throw new CannotCastUpdateSelectorException("Rename expression selection cannot be cast to String type", this.getMetadata()); + throw new CannotCastUpdateSelectorException( + "Rename expression selection cannot be cast to String type", + this.getMetadata() + ); } if (target.getMutabilityLevel() != context.getCurrentMutabilityLevel()) { - throw new TransformModifiesNonCopiedValueException("Attempt to modify currently immutable target", this.getMetadata()); + throw new TransformModifiesNonCopiedValueException( + "Attempt to modify currently immutable target", + this.getMetadata() + ); } up = factory.createRenameInObjectPrimitive(target, locator, content, this.getMetadata()); } else { - throw new InvalidUpdateTargetException("Rename expression target must be a single object", this.getMetadata()); + throw new InvalidUpdateTargetException( + "Rename expression target must be a single object", + this.getMetadata() + ); } pul.addUpdatePrimitive(up); diff --git a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java index 2f48995059..4d21860db3 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java @@ -23,7 +23,13 @@ public class ReplaceExpressionIterator extends HybridRuntimeIterator { private RuntimeIterator locatorIterator; private RuntimeIterator replacerIterator; - public ReplaceExpressionIterator(RuntimeIterator mainIterator, RuntimeIterator locatorIterator, RuntimeIterator replacerIterator, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) { + public ReplaceExpressionIterator( + RuntimeIterator mainIterator, + RuntimeIterator locatorIterator, + RuntimeIterator replacerIterator, + ExecutionMode executionMode, + ExceptionMetadata iteratorMetadata + ) { super(Arrays.asList(mainIterator, locatorIterator, replacerIterator), executionMode, iteratorMetadata); this.mainIterator = mainIterator; @@ -95,22 +101,37 @@ public PendingUpdateList getPendingUpdateList(DynamicContext context) { UpdatePrimitive up; if (target.isObject()) { if (!locator.isString()) { - throw new CannotCastUpdateSelectorException("Replace expression selection cannot be cast to String type", this.getMetadata()); + throw new CannotCastUpdateSelectorException( + "Replace expression selection cannot be cast to String type", + this.getMetadata() + ); } if (target.getMutabilityLevel() != context.getCurrentMutabilityLevel()) { - throw new TransformModifiesNonCopiedValueException("Attempt to modify currently immutable target", this.getMetadata()); + throw new TransformModifiesNonCopiedValueException( + "Attempt to modify currently immutable target", + this.getMetadata() + ); } up = factory.createReplaceInObjectPrimitive(target, locator, content, this.getMetadata()); } else if (target.isArray()) { if (!locator.isInt()) { - throw new CannotCastUpdateSelectorException("Replace expression selection cannot be cast to Int type", this.getMetadata()); + throw new CannotCastUpdateSelectorException( + "Replace expression selection cannot be cast to Int type", + this.getMetadata() + ); } if (target.getMutabilityLevel() != context.getCurrentMutabilityLevel()) { - throw new TransformModifiesNonCopiedValueException("Attempt to modify currently immutable target", this.getMetadata()); + throw new TransformModifiesNonCopiedValueException( + "Attempt to modify currently immutable target", + this.getMetadata() + ); } up = factory.createReplaceInArrayPrimitive(target, locator, content, this.getMetadata()); } else { - throw new InvalidUpdateTargetException("Replace expression target must be a single array or object", this.getMetadata()); + throw new InvalidUpdateTargetException( + "Replace expression target must be a single array or object", + this.getMetadata() + ); } pul.addUpdatePrimitive(up); diff --git a/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java index 973dcd7b5d..330303cf47 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java @@ -3,13 +3,10 @@ import org.apache.spark.api.java.JavaRDD; import org.apache.commons.lang.SerializationUtils; import org.rumbledb.api.Item; -import org.rumbledb.compiler.VisitorHelpers; import org.rumbledb.context.DynamicContext; import org.rumbledb.context.Name; import org.rumbledb.exceptions.ExceptionMetadata; import org.rumbledb.expressions.ExecutionMode; -import org.rumbledb.expressions.Expression; -import org.rumbledb.expressions.update.CopyDeclaration; import org.rumbledb.runtime.HybridRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.update.PendingUpdateList; @@ -26,7 +23,14 @@ public class TransformExpressionIterator extends HybridRuntimeIterator { private int mutabilityLevel; - public TransformExpressionIterator(Map copyDeclMap, RuntimeIterator modifyIterator, RuntimeIterator returnIterator, ExecutionMode executionMode, int mutabilityLevel, ExceptionMetadata iteratorMetadata) { + public TransformExpressionIterator( + Map copyDeclMap, + RuntimeIterator modifyIterator, + RuntimeIterator returnIterator, + ExecutionMode executionMode, + int mutabilityLevel, + ExceptionMetadata iteratorMetadata + ) { super(null, executionMode, iteratorMetadata); this.children.addAll(copyDeclMap.values()); this.children.add(modifyIterator); diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java index 4d013869b2..8cf51f57bb 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromArrayPrimitive.java @@ -3,7 +3,6 @@ import org.rumbledb.api.Item; import org.rumbledb.exceptions.CannotResolveUpdateSelectorException; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.items.ArrayItem; public class DeleteFromArrayPrimitive implements UpdatePrimitive { @@ -13,7 +12,10 @@ public class DeleteFromArrayPrimitive implements UpdatePrimitive { public DeleteFromArrayPrimitive(Item targetArray, Item positionInt, ExceptionMetadata metadata) { if (positionInt.getIntValue() <= 0 || positionInt.getIntValue() > targetArray.getSize()) { - throw new CannotResolveUpdateSelectorException("Cannot delete item at index out of range of target array", metadata); + throw new CannotResolveUpdateSelectorException( + "Cannot delete item at index out of range of target array", + metadata + ); } this.target = targetArray; this.selector = positionInt; diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java index 79cf30d52c..a55b5b9a3e 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/DeleteFromObjectPrimitive.java @@ -3,8 +3,6 @@ import org.rumbledb.api.Item; import org.rumbledb.exceptions.CannotResolveUpdateSelectorException; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.OurBadException; -import org.rumbledb.items.ObjectItem; import java.util.ArrayList; import java.util.List; @@ -19,11 +17,14 @@ public DeleteFromObjectPrimitive(Item targetObject, List namesToRemove, Ex for (Item item : namesToRemove) { if (targetObject.getItemByKey(item.getStringValue()) == null) { - throw new CannotResolveUpdateSelectorException("Cannot delete key that does not exist in target object", metadata); + throw new CannotResolveUpdateSelectorException( + "Cannot delete key that does not exist in target object", + metadata + ); } } - this.target = targetObject; + this.target = targetObject; this.content = namesToRemove; } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java index 1f595c28a8..a6f2d9b4e8 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/InsertIntoArrayPrimitive.java @@ -1,7 +1,6 @@ package org.rumbledb.runtime.update.primitives; import org.rumbledb.api.Item; -import org.rumbledb.items.ArrayItem; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java index aaff6e3498..01c0d4037b 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/RenameInObjectPrimitive.java @@ -3,7 +3,6 @@ import org.rumbledb.api.Item; import org.rumbledb.exceptions.CannotResolveUpdateSelectorException; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.items.ObjectItem; public class RenameInObjectPrimitive implements UpdatePrimitive { @@ -11,10 +10,18 @@ public class RenameInObjectPrimitive implements UpdatePrimitive { private Item selector; private Item content; - public RenameInObjectPrimitive(Item targetObject, Item targetName, Item replacementName, ExceptionMetadata metadata) { + public RenameInObjectPrimitive( + Item targetObject, + Item targetName, + Item replacementName, + ExceptionMetadata metadata + ) { if (targetObject.getItemByKey(targetName.getStringValue()) == null) { - throw new CannotResolveUpdateSelectorException("Cannot rename key that does not exist in target object", metadata); + throw new CannotResolveUpdateSelectorException( + "Cannot rename key that does not exist in target object", + metadata + ); } diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java index 5522e2b8cb..9be2c98200 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInArrayPrimitive.java @@ -3,7 +3,6 @@ import org.rumbledb.api.Item; import org.rumbledb.exceptions.CannotResolveUpdateSelectorException; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.items.ArrayItem; public class ReplaceInArrayPrimitive implements UpdatePrimitive { @@ -11,9 +10,17 @@ public class ReplaceInArrayPrimitive implements UpdatePrimitive { private Item selector; private Item content; - public ReplaceInArrayPrimitive(Item targetArray, Item positionInt, Item replacementItem, ExceptionMetadata metadata) { + public ReplaceInArrayPrimitive( + Item targetArray, + Item positionInt, + Item replacementItem, + ExceptionMetadata metadata + ) { if (positionInt.getIntValue() <= 0 || positionInt.getIntValue() > targetArray.getSize()) { - throw new CannotResolveUpdateSelectorException("Cannot replace item at index out of range of target array", metadata); + throw new CannotResolveUpdateSelectorException( + "Cannot replace item at index out of range of target array", + metadata + ); } this.target = targetArray; diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java index 77f85e7cce..a4d9e0daf1 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/ReplaceInObjectPrimitive.java @@ -3,7 +3,6 @@ import org.rumbledb.api.Item; import org.rumbledb.exceptions.CannotResolveUpdateSelectorException; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.items.ObjectItem; public class ReplaceInObjectPrimitive implements UpdatePrimitive { @@ -11,10 +10,18 @@ public class ReplaceInObjectPrimitive implements UpdatePrimitive { private Item selector; private Item content; - public ReplaceInObjectPrimitive(Item targetObject, Item targetName, Item replacementItem, ExceptionMetadata metadata) { + public ReplaceInObjectPrimitive( + Item targetObject, + Item targetName, + Item replacementItem, + ExceptionMetadata metadata + ) { if (targetObject.getItemByKey(targetName.getStringValue()) == null) { - throw new CannotResolveUpdateSelectorException("Cannot delete key that does not exist in target object", metadata); + throw new CannotResolveUpdateSelectorException( + "Cannot delete key that does not exist in target object", + metadata + ); } this.target = targetObject; diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java index 006f7d5842..7827587d36 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitive.java @@ -12,9 +12,13 @@ public interface UpdatePrimitive { Item getTarget(); - default Item getSelector() {throw new UnsupportedOperationException("Operation not defined");} + default Item getSelector() { + throw new UnsupportedOperationException("Operation not defined"); + } - default int getIntSelector() {throw new UnsupportedOperationException("Operation not defined");} + default int getIntSelector() { + throw new UnsupportedOperationException("Operation not defined"); + } default Item getContent() { throw new UnsupportedOperationException("Operation not defined"); diff --git a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveFactory.java b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveFactory.java index 33ad107788..2dc938b1c2 100644 --- a/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveFactory.java +++ b/src/main/java/org/rumbledb/runtime/update/primitives/UpdatePrimitiveFactory.java @@ -16,11 +16,19 @@ public static UpdatePrimitiveFactory getInstance() { return instance; } - public UpdatePrimitive createDeleteFromArrayPrimitive(Item targetArray, Item selectorInt, ExceptionMetadata metadata) { + public UpdatePrimitive createDeleteFromArrayPrimitive( + Item targetArray, + Item selectorInt, + ExceptionMetadata metadata + ) { return new DeleteFromArrayPrimitive(targetArray, selectorInt, metadata); } - public UpdatePrimitive createDeleteFromObjectPrimitive(Item targetObject, List selectorStrs, ExceptionMetadata metadata) { + public UpdatePrimitive createDeleteFromObjectPrimitive( + Item targetObject, + List selectorStrs, + ExceptionMetadata metadata + ) { return new DeleteFromObjectPrimitive(targetObject, selectorStrs, metadata); } @@ -32,15 +40,30 @@ public UpdatePrimitive createInsertIntoObjectPrimitive(Item targetObject, Item c return new InsertIntoObjectPrimitive(targetObject, contentsObject); } - public UpdatePrimitive createReplaceInArrayPrimitive(Item targetArray, Item selectorInt, Item content, ExceptionMetadata metadata) { + public UpdatePrimitive createReplaceInArrayPrimitive( + Item targetArray, + Item selectorInt, + Item content, + ExceptionMetadata metadata + ) { return new ReplaceInArrayPrimitive(targetArray, selectorInt, content, metadata); } - public UpdatePrimitive createReplaceInObjectPrimitive(Item targetObject, Item selectorStr, Item content, ExceptionMetadata metadata) { + public UpdatePrimitive createReplaceInObjectPrimitive( + Item targetObject, + Item selectorStr, + Item content, + ExceptionMetadata metadata + ) { return new ReplaceInObjectPrimitive(targetObject, selectorStr, content, metadata); } - public UpdatePrimitive createRenameInObjectPrimitive(Item targetObject, Item selectorStr, Item content, ExceptionMetadata metadata) { + public UpdatePrimitive createRenameInObjectPrimitive( + Item targetObject, + Item selectorStr, + Item content, + ExceptionMetadata metadata + ) { return new RenameInObjectPrimitive(targetObject, selectorStr, content, metadata); } From cf3d8d1aedc7eef85d5d78b587efbeb2cbfc35ca Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Tue, 27 Feb 2024 17:09:38 +0100 Subject: [PATCH 109/119] Spotless. --- .../runtime/update/expression/AppendExpressionIterator.java | 1 - .../runtime/update/expression/DeleteExpressionIterator.java | 1 - .../runtime/update/expression/InsertExpressionIterator.java | 1 - .../runtime/update/expression/RenameExpressionIterator.java | 1 - .../runtime/update/expression/ReplaceExpressionIterator.java | 1 - .../runtime/update/expression/TransformExpressionIterator.java | 2 -- 6 files changed, 7 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java index 2cdbcaa240..8344a62af6 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java @@ -5,7 +5,6 @@ import org.rumbledb.context.DynamicContext; import org.rumbledb.context.RuntimeStaticContext; import org.rumbledb.exceptions.*; -import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.HybridRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; diff --git a/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java index 757674fc72..3f076daa89 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java @@ -5,7 +5,6 @@ import org.rumbledb.context.DynamicContext; import org.rumbledb.context.RuntimeStaticContext; import org.rumbledb.exceptions.*; -import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.runtime.HybridRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.update.PendingUpdateList; diff --git a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java index ab63c702b8..47d2110db9 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java @@ -6,7 +6,6 @@ import org.rumbledb.context.DynamicContext; import org.rumbledb.context.RuntimeStaticContext; import org.rumbledb.exceptions.*; -import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.runtime.HybridRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.update.PendingUpdateList; diff --git a/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java index 6342aae97b..79f907730a 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java @@ -5,7 +5,6 @@ import org.rumbledb.context.DynamicContext; import org.rumbledb.context.RuntimeStaticContext; import org.rumbledb.exceptions.*; -import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.runtime.HybridRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.update.PendingUpdateList; diff --git a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java index 635de1043a..be21cd4fa1 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java @@ -6,7 +6,6 @@ import org.rumbledb.context.DynamicContext; import org.rumbledb.context.RuntimeStaticContext; import org.rumbledb.exceptions.*; -import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.items.ItemFactory; import org.rumbledb.runtime.HybridRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; diff --git a/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java index 593bf10f0b..1b9ce01394 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java @@ -6,8 +6,6 @@ import org.rumbledb.context.DynamicContext; import org.rumbledb.context.Name; import org.rumbledb.context.RuntimeStaticContext; -import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.expressions.ExecutionMode; import org.rumbledb.runtime.HybridRuntimeIterator; import org.rumbledb.runtime.RuntimeIterator; import org.rumbledb.runtime.update.PendingUpdateList; From c6d2e6800b97bc0a1eb2cb785feba098129ab4b7 Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Tue, 27 Feb 2024 17:11:01 +0100 Subject: [PATCH 110/119] Fix javadoc. --- src/main/java/org/rumbledb/api/Item.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/rumbledb/api/Item.java b/src/main/java/org/rumbledb/api/Item.java index 3790e1d603..5a01bc91b8 100644 --- a/src/main/java/org/rumbledb/api/Item.java +++ b/src/main/java/org/rumbledb/api/Item.java @@ -689,7 +689,7 @@ default boolean isNaN() { /** * Returns the mutability level of the item. * - * @return int representing nestedness of the item inside transform expressions. + * @return an int representing nestedness of the item inside transform expressions. */ default int getMutabilityLevel() { return 0; From a1f99c1368a11cc7b29b01fa2fab3f9bd71c469d Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Tue, 27 Feb 2024 17:12:53 +0100 Subject: [PATCH 111/119] Fix javadoc. --- src/main/java/org/rumbledb/api/Item.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/rumbledb/api/Item.java b/src/main/java/org/rumbledb/api/Item.java index 5a01bc91b8..83483587d2 100644 --- a/src/main/java/org/rumbledb/api/Item.java +++ b/src/main/java/org/rumbledb/api/Item.java @@ -698,7 +698,7 @@ default int getMutabilityLevel() { /** * Returns the mutability level of the item. * - * @return int representing nestedness of the item inside transform expressions. + * @return an int representing nestedness of the item inside transform expressions. */ default void setMutabilityLevel(int mutabilityLevel) { } From ff2fe42274a0e1dc3612f5f84d783084046f9f59 Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Tue, 27 Feb 2024 17:13:46 +0100 Subject: [PATCH 112/119] Fix javadoc. --- src/main/java/org/rumbledb/api/Item.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/rumbledb/api/Item.java b/src/main/java/org/rumbledb/api/Item.java index 83483587d2..46f221f921 100644 --- a/src/main/java/org/rumbledb/api/Item.java +++ b/src/main/java/org/rumbledb/api/Item.java @@ -696,9 +696,9 @@ default int getMutabilityLevel() { } /** - * Returns the mutability level of the item. + * Sets the mutability level of the item. * - * @return an int representing nestedness of the item inside transform expressions. + * @param int the new mutability level. */ default void setMutabilityLevel(int mutabilityLevel) { } From 9c8b84c5d69cc9f9c2664039f8c2cd682c7d2e6c Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Tue, 27 Feb 2024 17:16:36 +0100 Subject: [PATCH 113/119] Fix javadoc. --- src/main/java/org/rumbledb/api/Item.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/rumbledb/api/Item.java b/src/main/java/org/rumbledb/api/Item.java index 46f221f921..ae0feeb357 100644 --- a/src/main/java/org/rumbledb/api/Item.java +++ b/src/main/java/org/rumbledb/api/Item.java @@ -698,7 +698,7 @@ default int getMutabilityLevel() { /** * Sets the mutability level of the item. * - * @param int the new mutability level. + * @param mutabilityLevel the new mutability level. */ default void setMutabilityLevel(int mutabilityLevel) { } From 963106dbf4bfd137528e25cdf3bc56ccb3eccc11 Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Tue, 27 Feb 2024 17:25:13 +0100 Subject: [PATCH 114/119] Set copy variable execution mode to local. --- src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java b/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java index 36099b173c..c4146003e5 100644 --- a/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java +++ b/src/main/java/org/rumbledb/compiler/ExecutionModeVisitor.java @@ -621,7 +621,7 @@ public StaticContext visitTransformExpression(TransformExpression expression, St // first pass. innerContext.setVariableStorageMode( copyDecl.getVariableName(), - expression.getVariableHighestStorageMode(this.visitorConfig) + ExecutionMode.LOCAL ); } expression.setHighestExecutionMode(ExecutionMode.LOCAL); From c24e6c402425944bfc9aeed85d8fc6ada7c30bdb Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Tue, 27 Feb 2024 17:28:53 +0100 Subject: [PATCH 115/119] Remove unused method. --- .../expressions/update/TransformExpression.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/main/java/org/rumbledb/expressions/update/TransformExpression.java b/src/main/java/org/rumbledb/expressions/update/TransformExpression.java index e0056c4aa4..bbcbab7cd4 100644 --- a/src/main/java/org/rumbledb/expressions/update/TransformExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/TransformExpression.java @@ -17,8 +17,6 @@ public class TransformExpression extends Expression { private Expression returnExpression; private int mutabilityLevel; - protected ExecutionMode variableHighestStorageMode = ExecutionMode.UNSET; - public TransformExpression( List copyDeclarations, Expression modifyExpression, @@ -54,16 +52,6 @@ public Expression getReturnExpression() { return returnExpression; } - public ExecutionMode getVariableHighestStorageMode(VisitorConfig visitorConfig) { - if ( - !visitorConfig.suppressErrorsForAccessingUnsetExecutionModes() - && this.variableHighestStorageMode == ExecutionMode.UNSET - ) { - throw new OurBadException("A copy variable storage mode is accessed without being set."); - } - return this.variableHighestStorageMode; - } - @Override public List getChildren() { List result = this.copyDeclarations.stream() From fae8f32a90e415bcb60602a0f59fbff9f10fc8b9 Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Tue, 27 Feb 2024 17:31:58 +0100 Subject: [PATCH 116/119] Merge master back. --- .../org/rumbledb/expressions/update/TransformExpression.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/org/rumbledb/expressions/update/TransformExpression.java b/src/main/java/org/rumbledb/expressions/update/TransformExpression.java index bbcbab7cd4..f4773ab769 100644 --- a/src/main/java/org/rumbledb/expressions/update/TransformExpression.java +++ b/src/main/java/org/rumbledb/expressions/update/TransformExpression.java @@ -1,8 +1,6 @@ package org.rumbledb.expressions.update; -import org.rumbledb.compiler.VisitorConfig; import org.rumbledb.exceptions.ExceptionMetadata; -import org.rumbledb.exceptions.OurBadException; import org.rumbledb.exceptions.SemanticException; import org.rumbledb.expressions.*; From 86f51f9233f5ff8682c19073f10b7cb7729329c5 Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Tue, 27 Feb 2024 17:35:55 +0100 Subject: [PATCH 117/119] Fix build. --- .../runtime/update/expression/InsertExpressionIterator.java | 2 +- .../runtime/update/expression/ReplaceExpressionIterator.java | 2 +- .../runtime/update/expression/TransformExpressionIterator.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java index 47d2110db9..28e10eb322 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java @@ -1,6 +1,6 @@ package org.rumbledb.runtime.update.expression; -import org.apache.commons.lang.SerializationUtils; +import org.apache.commons.lang3.SerializationUtils; 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/update/expression/ReplaceExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java index be21cd4fa1..c95df511cd 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java @@ -1,6 +1,6 @@ package org.rumbledb.runtime.update.expression; -import org.apache.commons.lang.SerializationUtils; +import org.apache.commons.lang3.SerializationUtils; 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/update/expression/TransformExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java index 1b9ce01394..27f7b07013 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java @@ -1,7 +1,7 @@ package org.rumbledb.runtime.update.expression; import org.apache.spark.api.java.JavaRDD; -import org.apache.commons.lang.SerializationUtils; +import org.apache.commons.lang3.SerializationUtils; import org.rumbledb.api.Item; import org.rumbledb.context.DynamicContext; import org.rumbledb.context.Name; From 67853a1ab045086309854b12a2ac0554c10c019a Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Tue, 27 Feb 2024 17:37:23 +0100 Subject: [PATCH 118/119] Fix warnings. --- .../runtime/update/expression/AppendExpressionIterator.java | 3 ++- .../runtime/update/expression/DeleteExpressionIterator.java | 3 ++- .../runtime/update/expression/InsertExpressionIterator.java | 3 ++- .../runtime/update/expression/RenameExpressionIterator.java | 3 ++- .../runtime/update/expression/ReplaceExpressionIterator.java | 3 ++- .../runtime/update/expression/TransformExpressionIterator.java | 3 ++- 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java index 8344a62af6..49df8669ce 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java @@ -18,7 +18,8 @@ public class AppendExpressionIterator extends HybridRuntimeIterator { - private RuntimeIterator arrayIterator; + private static final long serialVersionUID = 1L; + private RuntimeIterator arrayIterator; private RuntimeIterator toAppendIterator; public AppendExpressionIterator( diff --git a/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java index 3f076daa89..505dba23b8 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java @@ -16,7 +16,8 @@ public class DeleteExpressionIterator extends HybridRuntimeIterator { - private RuntimeIterator mainIterator; + private static final long serialVersionUID = 1L; + private RuntimeIterator mainIterator; private RuntimeIterator lookupIterator; public DeleteExpressionIterator( diff --git a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java index 28e10eb322..e4301fd92e 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java @@ -17,7 +17,8 @@ public class InsertExpressionIterator extends HybridRuntimeIterator { - private RuntimeIterator mainIterator; + private static final long serialVersionUID = 1L; + private RuntimeIterator mainIterator; private RuntimeIterator toInsertIterator; private RuntimeIterator positionIterator; diff --git a/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java index 79f907730a..5d5b41c1e2 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java @@ -15,7 +15,8 @@ public class RenameExpressionIterator extends HybridRuntimeIterator { - private RuntimeIterator mainIterator; + private static final long serialVersionUID = 1L; + private RuntimeIterator mainIterator; private RuntimeIterator locatorIterator; private RuntimeIterator nameIterator; diff --git a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java index c95df511cd..25edef7a5f 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java @@ -19,7 +19,8 @@ public class ReplaceExpressionIterator extends HybridRuntimeIterator { - private RuntimeIterator mainIterator; + private static final long serialVersionUID = 1L; + private RuntimeIterator mainIterator; private RuntimeIterator locatorIterator; private RuntimeIterator replacerIterator; diff --git a/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java index 27f7b07013..1313b147a4 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java @@ -16,7 +16,8 @@ public class TransformExpressionIterator extends HybridRuntimeIterator { - private Map copyDeclMap; + private static final long serialVersionUID = 1L; + private Map copyDeclMap; private RuntimeIterator modifyIterator; private RuntimeIterator returnIterator; From 97cbc7887869927dfe63100a7a45beb334d06637 Mon Sep 17 00:00:00 2001 From: Ghislain Fourny Date: Tue, 27 Feb 2024 17:39:01 +0100 Subject: [PATCH 119/119] Spotless. --- .../runtime/update/expression/AppendExpressionIterator.java | 2 +- .../runtime/update/expression/DeleteExpressionIterator.java | 2 +- .../runtime/update/expression/InsertExpressionIterator.java | 2 +- .../runtime/update/expression/RenameExpressionIterator.java | 2 +- .../runtime/update/expression/ReplaceExpressionIterator.java | 2 +- .../runtime/update/expression/TransformExpressionIterator.java | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java index 49df8669ce..054fe6f2b0 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/AppendExpressionIterator.java @@ -19,7 +19,7 @@ public class AppendExpressionIterator extends HybridRuntimeIterator { private static final long serialVersionUID = 1L; - private RuntimeIterator arrayIterator; + private RuntimeIterator arrayIterator; private RuntimeIterator toAppendIterator; public AppendExpressionIterator( diff --git a/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java index 505dba23b8..c9a4dc6aae 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/DeleteExpressionIterator.java @@ -17,7 +17,7 @@ public class DeleteExpressionIterator extends HybridRuntimeIterator { private static final long serialVersionUID = 1L; - private RuntimeIterator mainIterator; + private RuntimeIterator mainIterator; private RuntimeIterator lookupIterator; public DeleteExpressionIterator( diff --git a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java index e4301fd92e..297156cdd6 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/InsertExpressionIterator.java @@ -18,7 +18,7 @@ public class InsertExpressionIterator extends HybridRuntimeIterator { private static final long serialVersionUID = 1L; - private RuntimeIterator mainIterator; + private RuntimeIterator mainIterator; private RuntimeIterator toInsertIterator; private RuntimeIterator positionIterator; diff --git a/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java index 5d5b41c1e2..57fbf49e50 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/RenameExpressionIterator.java @@ -16,7 +16,7 @@ public class RenameExpressionIterator extends HybridRuntimeIterator { private static final long serialVersionUID = 1L; - private RuntimeIterator mainIterator; + private RuntimeIterator mainIterator; private RuntimeIterator locatorIterator; private RuntimeIterator nameIterator; diff --git a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java index 25edef7a5f..25ce38dea5 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/ReplaceExpressionIterator.java @@ -20,7 +20,7 @@ public class ReplaceExpressionIterator extends HybridRuntimeIterator { private static final long serialVersionUID = 1L; - private RuntimeIterator mainIterator; + private RuntimeIterator mainIterator; private RuntimeIterator locatorIterator; private RuntimeIterator replacerIterator; diff --git a/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java b/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java index 1313b147a4..fb1a24a0f4 100644 --- a/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java +++ b/src/main/java/org/rumbledb/runtime/update/expression/TransformExpressionIterator.java @@ -17,7 +17,7 @@ public class TransformExpressionIterator extends HybridRuntimeIterator { private static final long serialVersionUID = 1L; - private Map copyDeclMap; + private Map copyDeclMap; private RuntimeIterator modifyIterator; private RuntimeIterator returnIterator;