Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
81a1b14
fix dynamic context in let clause - making sure it's cloned and not r…
ohamz Nov 17, 2025
028b92f
first batch of tests - same snapshot mutiple updates
ohamz Nov 17, 2025
1f116eb
fix delta inserts when key is new - merge schemas enabled
ohamz Nov 17, 2025
7eb717e
fixed error when deleting from df that contains 1 element
ohamz Nov 17, 2025
7cd8dc4
Merge remote-tracking branch 'origin/master' into master-omar
ohamz Nov 17, 2025
0f65041
adapt tests for inserts
ohamz Dec 3, 2025
acd6bb3
create Collection class - to better handle collection modes and paths
ohamz Dec 3, 2025
7d57e05
make inserts compatible with schema merging in delta files - fix inse…
ohamz Dec 3, 2025
3c4b306
added Collection to insert calls directly - code cleanup - extend Ite…
ohamz Dec 10, 2025
e829296
make Collection class serializable
ohamz Dec 10, 2025
7d3ee69
bug fix: adapt groupby clause to include rdd and dataframe keys
ohamz Dec 10, 2025
fe93f6d
bug fix: typo error
ohamz Dec 10, 2025
c2d896e
bug fix: wrongly return ObjectItemType (when atomic)
ohamz Dec 10, 2025
43bab35
ObjectItemType fully fixed and test added
ohamz Dec 10, 2025
8dbead6
adapt RDD/DF tests for group by clause
ohamz Dec 15, 2025
759ea85
cleaner code for atomic type case
ohamz Dec 15, 2025
ad05c4a
spotless.
ohamz Dec 15, 2025
24396b1
start integrating apache iceberg
ohamz Dec 15, 2025
89284d2
fix build by updating java version
ohamz Dec 15, 2025
8677877
Implement iceberg correctly - adapt grammar and primitives (create/de…
ohamz Dec 15, 2025
2b470fd
Fix edits - adapt inserting to Collection (and not raw sql)
ohamz Dec 18, 2025
d412451
cleanup code
ohamz Dec 20, 2025
9de40ed
Merge branch 'master' into omar1
ghislainfourny Jan 7, 2026
f2209ad
complete let clause fixes added
ohamz Jan 12, 2026
5245b7a
spotless let fix
ohamz Jan 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
image: maven:3.9.9-eclipse-temurin-11
image: maven:3.9.9-eclipse-temurin-17

stages:
- build
Expand Down
24 changes: 23 additions & 1 deletion src/main/java/org/rumbledb/api/Item.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@
import org.rumbledb.context.Name;
import org.rumbledb.items.structured.JSoundDataFrame;
import org.rumbledb.items.xml.XMLDocumentPosition;
import org.rumbledb.runtime.RuntimeIterator;
import org.rumbledb.runtime.flwor.NativeClauseContext;
import org.rumbledb.runtime.RuntimeIterator;
import org.rumbledb.runtime.update.primitives.Collection;
import org.rumbledb.serialization.Serializer;
import org.rumbledb.types.FunctionSignature;
import org.rumbledb.types.ItemType;


import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
Expand Down Expand Up @@ -1106,4 +1108,24 @@ default XMLDocumentPosition getXmlDocumentPosition() {
default int setXmlDocumentPosition(String path, int current) {
throw new UnsupportedOperationException("Operation not defined for type " + this.getDynamicType());
}

/**
* Returns the collection to which the item belongs, if any.
* Only defined for top-level items.
*
* @return the collection.
*/
default Collection getCollection() {
throw new UnsupportedOperationException("Operation not defined for type " + this.getDynamicType());
}

/**
* Sets the collection to which the item belongs.
* Only defined for top-level items.
*
* @param collection the collection.
*/
default void setCollection(Collection collection) {
throw new UnsupportedOperationException("Operation not defined for type " + this.getDynamicType());
}
}
21 changes: 11 additions & 10 deletions src/main/java/org/rumbledb/compiler/RuntimeIteratorVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@
import org.rumbledb.runtime.update.expression.InsertIndexIntoCollectionIterator;
import org.rumbledb.runtime.update.expression.InsertSearchIntoCollectionIterator;
import org.rumbledb.runtime.update.expression.TruncateCollectionIterator;
import org.rumbledb.runtime.update.primitives.Mode;
import org.rumbledb.runtime.xml.SlashExprIterator;
import org.rumbledb.runtime.xml.StepExprIterator;
import org.rumbledb.runtime.xml.TextNodeConstructorRuntimeIterator;
Expand Down Expand Up @@ -544,12 +545,12 @@ public RuntimeIterator visitCreateCollectionExpression(
) {
RuntimeIterator contentIterator = this.visit(expression.getContentExpression(), argument);
RuntimeIterator targetIterator = this.visit(expression.getCollection(), argument);
boolean isTable = expression.isTable();
Mode mode = expression.getMode();

RuntimeIterator runtimeIterator = new CreateCollectionIterator(
targetIterator,
contentIterator,
isTable,
mode,
expression.getStaticContextForRuntime(this.config, this.visitorConfig)
);
runtimeIterator.setStaticContext(expression.getStaticContext());
Expand All @@ -563,7 +564,7 @@ public RuntimeIterator visitDeleteIndexFromCollectionExpression(
RuntimeIterator argument
) {
RuntimeIterator targetIterator = this.visit(expression.getCollection(), argument);
boolean isTable = expression.isTable();
Mode mode = expression.getMode();
boolean isFirst = expression.isFirst();

RuntimeIterator runtimeIterator = null;
Expand All @@ -573,14 +574,14 @@ public RuntimeIterator visitDeleteIndexFromCollectionExpression(
targetIterator,
numDelete,
isFirst,
isTable,
mode,
expression.getStaticContextForRuntime(this.config, this.visitorConfig)
);
} else {
runtimeIterator = new DeleteIndexFromCollectionIterator(
targetIterator,
isFirst,
isTable,
mode,
expression.getStaticContextForRuntime(this.config, this.visitorConfig)
);
}
Expand Down Expand Up @@ -627,7 +628,7 @@ public RuntimeIterator visitInsertIndexIntoCollectionExpression(
) {
RuntimeIterator contentIterator = this.visit(expression.getContentExpression(), argument);
RuntimeIterator targetIterator = this.visit(expression.getCollection(), argument);
boolean isTable = expression.isTable();
Mode mode = expression.getMode();
boolean isFirst = expression.isFirst();
boolean isLast = expression.isLast();

Expand All @@ -638,7 +639,7 @@ public RuntimeIterator visitInsertIndexIntoCollectionExpression(
targetIterator,
contentIterator,
pos,
isTable,
mode,
isFirst,
isLast,
expression.getStaticContextForRuntime(this.config, this.visitorConfig)
Expand All @@ -647,7 +648,7 @@ public RuntimeIterator visitInsertIndexIntoCollectionExpression(
runtimeIterator = new InsertIndexIntoCollectionIterator(
targetIterator,
contentIterator,
isTable,
mode,
isFirst,
isLast,
expression.getStaticContextForRuntime(this.config, this.visitorConfig)
Expand Down Expand Up @@ -682,10 +683,10 @@ public RuntimeIterator visitTruncateCollectionExpression(
RuntimeIterator argument
) {
RuntimeIterator targetIterator = this.visit(expression.getCollectionName(), argument);
boolean isTable = expression.isTable();
Mode mode = expression.getMode();
RuntimeIterator runtimeIterator = new TruncateCollectionIterator(
targetIterator,
isTable,
mode,
expression.getStaticContextForRuntime(this.config, this.visitorConfig)
);
runtimeIterator.setStaticContext(expression.getStaticContext());
Expand Down
17 changes: 9 additions & 8 deletions src/main/java/org/rumbledb/compiler/TranslationVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@
import org.rumbledb.parser.jsoniq.JsoniqParser.SetterContext;
import org.rumbledb.parser.jsoniq.JsoniqParser.UriLiteralContext;
import org.rumbledb.runtime.functions.input.FileSystemUtil;
import org.rumbledb.runtime.update.primitives.Mode;
import org.rumbledb.types.BuiltinTypesCatalogue;
import org.rumbledb.types.FunctionSignature;
import org.rumbledb.types.ItemType;
Expand Down Expand Up @@ -1407,19 +1408,19 @@ public Node visitAppendExpr(JsoniqParser.AppendExprContext ctx) {
public Node visitCreateCollectionExpr(JsoniqParser.CreateCollectionExprContext ctx) {
Expression collection = (Expression) this.visitExprSimple(ctx.collection_name);
Expression contentExpression = (Expression) this.visitExprSingle(ctx.content);
boolean isTable = (ctx.table != null);
Mode mode = Mode.fromString(ctx.collectionMode.getText());
return new CreateCollectionExpression(
collection,
contentExpression,
isTable,
mode,
createMetadataFromContext(ctx)
);
}

@Override
public Node visitDeleteIndexExpr(JsoniqParser.DeleteIndexExprContext ctx) {
Expression collection = (Expression) this.visitExprSimple(ctx.collection_name);
boolean isTable = (ctx.table != null);
Mode mode = Mode.fromString(ctx.collectionMode.getText());
boolean isFirst = (ctx.first != null);

Expression numDelete = null;
Expand All @@ -1431,7 +1432,7 @@ public Node visitDeleteIndexExpr(JsoniqParser.DeleteIndexExprContext ctx) {
collection,
numDelete,
isFirst,
isTable,
mode,
createMetadataFromContext(ctx)
);
}
Expand Down Expand Up @@ -1461,15 +1462,15 @@ public Node visitInsertIndexExpr(JsoniqParser.InsertIndexExprContext ctx) {
Expression collection = (Expression) this.visitExprSimple(ctx.collection_name);
Expression contentExpression = (Expression) this.visitExprSingle(ctx.content);
Expression pos = ctx.pos != null ? (Expression) this.visitExprSingle(ctx.pos) : null;
boolean isTable = (ctx.table != null);
Mode mode = Mode.fromString(ctx.collectionMode.getText());
boolean isLast = (ctx.last != null);
boolean isFirst = (ctx.first != null);

return new InsertIndexIntoCollectionExpression(
collection,
contentExpression,
pos,
isTable,
mode,
isFirst,
isLast,
createMetadataFromContext(ctx)
Expand All @@ -1492,10 +1493,10 @@ public Node visitInsertSearchExpr(JsoniqParser.InsertSearchExprContext ctx) {
@Override
public Node visitTruncateCollectionExpr(JsoniqParser.TruncateCollectionExprContext ctx) {
Expression collectionName = (Expression) this.visitExprSimple(ctx.collection_name);
boolean isTable = (ctx.table != null);
Mode mode = Mode.fromString(ctx.collectionMode.getText());
return new TruncateCollectionExpression(
collectionName,
isTable,
mode,
createMetadataFromContext(ctx)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,17 @@ private static BuiltinFunction createBuiltinFunction(
BuiltinFunction.BuiltinFunctionExecutionMode.DATAFRAME
);

/**
* function that parses an iceberg table
*/
static final BuiltinFunction iceberg_table = createBuiltinFunction(
new Name(Name.JN_NS, "jn", "iceberg-table"),
"string",
"item*",
IcebergTableFunctionIterator.class,
BuiltinFunction.BuiltinFunctionExecutionMode.DATAFRAME
);

/**
* function that parses a csv file
*/
Expand Down Expand Up @@ -3099,6 +3110,7 @@ private static BuiltinFunction createBuiltinFunction(
builtinFunctions.put(mongodb_collection3.getIdentifier(), mongodb_collection3);
builtinFunctions.put(delta_file.getIdentifier(), delta_file);
builtinFunctions.put(delta_table.getIdentifier(), delta_table);
builtinFunctions.put(iceberg_table.getIdentifier(), iceberg_table);
builtinFunctions.put(csv_file1.getIdentifier(), csv_file1);
builtinFunctions.put(csv_file2.getIdentifier(), csv_file2);
builtinFunctions.put(root_file1.getIdentifier(), root_file1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,20 @@
import org.rumbledb.expressions.AbstractNodeVisitor;
import org.rumbledb.expressions.Expression;
import org.rumbledb.expressions.Node;
import org.rumbledb.runtime.update.primitives.Mode;

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

public class CreateCollectionExpression extends Expression {
private Expression collection;
private Expression contentExpression;
private boolean isTable;
private Mode mode;

public CreateCollectionExpression(
Expression collection,
Expression contentExpression,
boolean isTable,
Mode mode,
ExceptionMetadata metadata
) {
// TODO: The current implementations only accounts for two callening modes- table, and delta-file
Expand All @@ -31,7 +32,7 @@ public CreateCollectionExpression(
}
this.collection = collection;
this.contentExpression = contentExpression;
this.isTable = isTable;
this.mode = mode;
}

public Expression getCollection() {
Expand All @@ -42,8 +43,8 @@ public Expression getContentExpression() {
return this.contentExpression;
}

public boolean isTable() {
return this.isTable;
public Mode getMode() {
return this.mode;
}

@Override
Expand All @@ -60,7 +61,13 @@ public <T> T accept(AbstractNodeVisitor<T> visitor, T argument) {
public void serializeToJSONiq(StringBuffer sb, int indent) {
indentIt(sb, indent);
sb.append("create collection ");
sb.append(this.isTable ? "table" : "delta-file");
if (this.mode == Mode.HIVE) {
sb.append("table");
} else if (this.mode == Mode.DELTA) {
sb.append("delta-file");
} else if (this.mode == Mode.ICEBERG) {
sb.append("iceberg-table");
}
sb.append("(");
this.collection.serializeToJSONiq(sb, 0);
sb.append(")");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.rumbledb.expressions.AbstractNodeVisitor;
import org.rumbledb.expressions.Expression;
import org.rumbledb.expressions.Node;
import org.rumbledb.runtime.update.primitives.Mode;

import java.util.Arrays;
import java.util.List;
Expand All @@ -13,13 +14,13 @@ public class DeleteIndexFromCollectionExpression extends Expression {
private Expression collection;
private Expression numDelete;
private boolean isFirst;
private boolean isTable;
private Mode mode;

public DeleteIndexFromCollectionExpression(
Expression collection,
Expression numDelete,
boolean isFirst,
boolean isTable,
Mode mode,
ExceptionMetadata metadata
) {
// TODO: The current implementations only accounts for two callening modes- table, and delta-file
Expand All @@ -31,7 +32,7 @@ public DeleteIndexFromCollectionExpression(
this.collection = collection;
this.numDelete = numDelete;
this.isFirst = isFirst;
this.isTable = isTable;
this.mode = mode;
}

public Expression getCollection() {
Expand All @@ -42,8 +43,8 @@ public Expression getNumDelete() {
return this.numDelete;
}

public boolean isTable() {
return this.isTable;
public Mode getMode() {
return this.mode;
}

public boolean isFirst() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.rumbledb.expressions.AbstractNodeVisitor;
import org.rumbledb.expressions.Expression;
import org.rumbledb.expressions.Node;
import org.rumbledb.runtime.update.primitives.Mode;

import java.util.Arrays;
import java.util.List;
Expand All @@ -13,15 +14,15 @@ public class InsertIndexIntoCollectionExpression extends Expression {
private final Expression collection;
private final Expression contentExpression;
private final Expression pos;
private final boolean isTable;
private final Mode mode;
private final boolean isFirst;
private final boolean isLast;

public InsertIndexIntoCollectionExpression(
Expression collection,
Expression contentExpression,
Expression pos,
boolean isTable,
Mode mode,
boolean isFirst,
boolean isLast,
ExceptionMetadata metadata
Expand All @@ -36,7 +37,7 @@ public InsertIndexIntoCollectionExpression(

this.collection = collection;
this.contentExpression = contentExpression;
this.isTable = isTable;
this.mode = mode;
this.pos = pos;
this.isFirst = isFirst;
this.isLast = isLast;
Expand All @@ -54,8 +55,8 @@ public Expression getPosition() {
return this.pos;
}

public boolean isTable() {
return this.isTable;
public Mode getMode() {
return this.mode;
}

public boolean isLast() {
Expand Down Expand Up @@ -92,7 +93,13 @@ public void serializeToJSONiq(StringBuffer sb, int indent) {
this.pos.serializeToJSONiq(sb, 1);
}
sb.append(" into collection ");
sb.append(this.isTable ? "table" : "delta-file");
if (this.mode == Mode.HIVE) {
sb.append("table");
} else if (this.mode == Mode.DELTA) {
sb.append("delta-file");
} else if (this.mode == Mode.ICEBERG) {
sb.append("iceberg-table");
}
sb.append("(");
this.collection.serializeToJSONiq(sb, 0);
sb.append(")");
Expand Down
Loading
Loading