Skip to content

Commit

Permalink
Implement semantics for XUDY0014 with currentMutabilityLevel and gett…
Browse files Browse the repository at this point in the history
…er & setters
  • Loading branch information
dloughlin committed May 27, 2023
1 parent d3e965d commit 2d281f5
Show file tree
Hide file tree
Showing 14 changed files with 126 additions and 5 deletions.
17 changes: 17 additions & 0 deletions src/main/java/org/rumbledb/api/Item.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,7 @@ public RuntimeIterator visitTransformExpression(TransformExpression expression,
modifyIterator,
returnIterator,
expression.getHighestExecutionMode(this.visitorConfig),
expression.getMutabilityLevel(),
expression.getMetadata()
);
runtimeIterator.setStaticContext(expression.getStaticContext());
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/org/rumbledb/compiler/StaticContextVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
}

Expand Down
13 changes: 13 additions & 0 deletions src/main/java/org/rumbledb/context/DynamicContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -57,6 +58,7 @@ public DynamicContext() {
this.namedFunctions = null;
this.inScopeSchemaTypes = null;
this.currentDateTime = new DateTime();
this.currentMutabilityLevel = 0;
}

/**
Expand All @@ -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) {
Expand All @@ -82,6 +85,7 @@ public DynamicContext(DynamicContext parent) {
this.conf = null;
this.namedFunctions = null;
this.inScopeSchemaTypes = null;
this.currentMutabilityLevel = parent.getCurrentMutabilityLevel();
}

public DynamicContext(
Expand All @@ -101,6 +105,7 @@ public DynamicContext(
dataFrameVariableValues
);
this.namedFunctions = null;
this.currentMutabilityLevel = parent.getCurrentMutabilityLevel();
}

public RumbleRuntimeConfiguration getRumbleRuntimeConfiguration() {
Expand Down Expand Up @@ -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,
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/org/rumbledb/context/StaticContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ public class StaticContext implements Serializable, KryoSerializable {

private static final Map<String, String> defaultBindings;

private int currentMutabilityLevel;

static {
defaultBindings = new HashMap<>();
defaultBindings.put("local", Name.LOCAL_NS);
Expand All @@ -83,6 +85,7 @@ public StaticContext() {
this.contextItemStaticType = null;
this.configuration = null;
this.inScopeSchemaTypes = null;
this.currentMutabilityLevel = 0;
}

public StaticContext(URI staticBaseURI, RumbleRuntimeConfiguration configuration) {
Expand All @@ -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) {
Expand All @@ -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() {
Expand Down Expand Up @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class TransformExpression extends Expression {
private List<CopyDeclaration> copyDeclarations;
private Expression modifyExpression;
private Expression returnExpression;
private int mutabilityLevel;

protected ExecutionMode variableHighestStorageMode = ExecutionMode.UNSET;

Expand All @@ -31,6 +32,7 @@ public TransformExpression(
this.copyDeclarations = copyDeclarations;
this.modifyExpression = modifyExpression;
this.returnExpression = returnExpression;
this.mutabilityLevel = 0;
}

public List<CopyDeclaration> getCopyDeclarations() {
Expand Down Expand Up @@ -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;
}
}
17 changes: 17 additions & 0 deletions src/main/java/org/rumbledb/items/ArrayItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,18 @@ public class ArrayItem implements Item {
private static final long serialVersionUID = 1L;
private List<Item> arrayItems;

private int mutabilityLevel;

public ArrayItem() {
super();
this.arrayItems = new ArrayList<>();
this.mutabilityLevel = 0;
}

public ArrayItem(List<Item> arrayItems) {
super();
this.arrayItems = arrayItems;
this.mutabilityLevel = 0;
}

public boolean equals(Object otherItem) {
Expand Down Expand Up @@ -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);
}
}
}
19 changes: 18 additions & 1 deletion src/main/java/org/rumbledb/items/ObjectItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,21 @@ public class ObjectItem implements Item {
private List<Item> values;
private List<String> keys;

private int mutabilityLevel;

public ObjectItem() {
super();
this.keys = new ArrayList<>();
this.values = new ArrayList<>();
this.mutabilityLevel = 0;
}

public ObjectItem(List<String> keys, List<Item> values, ExceptionMetadata itemMetadata) {
super();
checkForDuplicateKeys(keys, itemMetadata);
this.keys = keys;
this.values = values;
this.mutabilityLevel = 0;
}

public boolean equals(Object otherItem) {
Expand Down Expand Up @@ -111,6 +115,7 @@ public ObjectItem(Map<String, List<Item>> keyValuePairs) {

this.keys = keyList;
this.values = valueList;
this.mutabilityLevel = 0;
}

@Override
Expand Down Expand Up @@ -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);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

import java.util.Arrays;
import java.util.Collections;
import java.util.List;


public class AppendExpressionIterator extends HybridRuntimeIterator {

Expand Down Expand Up @@ -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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ public class TransformExpressionIterator extends HybridRuntimeIterator {
private RuntimeIterator modifyIterator;
private RuntimeIterator returnIterator;

public TransformExpressionIterator(Map<Name, RuntimeIterator> copyDeclMap, RuntimeIterator modifyIterator, RuntimeIterator returnIterator, ExecutionMode executionMode, ExceptionMetadata iteratorMetadata) {
private int mutabilityLevel;

public TransformExpressionIterator(Map<Name, RuntimeIterator> copyDeclMap, RuntimeIterator modifyIterator, RuntimeIterator returnIterator, ExecutionMode executionMode, int mutabilityLevel, ExceptionMetadata iteratorMetadata) {
super(null, executionMode, iteratorMetadata);
this.children.addAll(copyDeclMap.values());
this.children.add(modifyIterator);
Expand All @@ -33,7 +35,7 @@ public TransformExpressionIterator(Map<Name, RuntimeIterator> copyDeclMap, Runti
this.copyDeclMap = copyDeclMap;
this.modifyIterator = modifyIterator;
this.returnIterator = returnIterator;
// this.updateContext = null;
this.mutabilityLevel = mutabilityLevel;
this.isUpdating = false;
}

Expand Down Expand Up @@ -79,6 +81,7 @@ protected Item nextLocal() {
@Override
public PendingUpdateList getPendingUpdateList(DynamicContext context) {
bindCopyDeclarations(context);
context.setCurrentMutabilityLevel(this.mutabilityLevel);
return modifyIterator.getPendingUpdateList(context);
}

Expand All @@ -87,8 +90,11 @@ private void bindCopyDeclarations(DynamicContext context) {
RuntimeIterator copyIterator = copyDeclMap.get(copyVar);
List<Item> toCopy = copyIterator.materialize(context);
List<Item> 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);
}
Expand Down

0 comments on commit 2d281f5

Please sign in to comment.