Skip to content

Commit b37287b

Browse files
committed
allow the assignment operator to insert null
1 parent 94753c9 commit b37287b

File tree

7 files changed

+32
-10
lines changed

7 files changed

+32
-10
lines changed

tessellate-main/src/main/antora/modules/reference/pages/transforms.adoc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ Apply function:: Apply intrinsic functions against one or more fields.
3434
There are three transform operators:
3535

3636
`pass:[=>]`:: Assign a literal value to a new field.
37-
Format::: `literal pass:[=>] new_field|type`
37+
Format:::
38+
- `literal pass:[=>] new_field|type`
39+
- `pass:[=>] new_field|type` # insert `null` into the field
3840
`+>`:: Retain the input field, and assign the result value to a new field.
3941
Format::: `field +> new_field|type`
4042
`pass:[->]`:: Discard the input fields, and assign the result value to a new field.

tessellate-main/src/main/java/io/clusterless/tessellate/parser/StatementParser.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,18 @@ private static Parser<Void> op(String op) {
149149
);
150150

151151
public static Parser<Assignment> LITERAL_ASSIGNMENT =
152-
Parsers.sequence(
153-
LITERAL_VALUE,
154-
ASSIGNMENT.followedBy(Scanners.many(IS_WHITESPACE)),
155-
FieldParser.fullFieldDeclaration.followedBy(EOF),
156-
Assignment::new
152+
Parsers.or(
153+
Parsers.sequence(
154+
LITERAL_VALUE,
155+
ASSIGNMENT.followedBy(Scanners.many(IS_WHITESPACE)),
156+
FieldParser.fullFieldDeclaration.followedBy(EOF),
157+
Assignment::new
158+
),
159+
Parsers.sequence(
160+
ASSIGNMENT.followedBy(Scanners.many(IS_WHITESPACE)),
161+
FieldParser.fullFieldDeclaration.followedBy(EOF),
162+
Assignment::new
163+
)
157164
);
158165

159166
private static final Parser<JoinType> JOIN_NAME = Parsers.sequence(

tessellate-main/src/main/java/io/clusterless/tessellate/parser/ast/Assignment.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ public Assignment(String literal, Op op, Field result) {
2222
this.result = result;
2323
}
2424

25+
public Assignment(Op op, Field result) {
26+
this.literal = null;
27+
this.op = op;
28+
this.result = result;
29+
}
30+
2531
public String literal() {
2632
return literal;
2733
}

tessellate-main/src/test/java/io/clusterless/tessellate/parser/StatementParserTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ void parse() {
5151
assertInstanceOf(Intrinsic.class, assertInstanceOf(Operation.class, StatementParser.parse("^toJson{} -> json")).exp());
5252

5353
assertNotNull(StatementParser.parse("five => intoField|type"));
54+
assertNotNull(StatementParser.parse("=> emptyValue"));
5455
}
5556

5657
@Test

tessellate-main/src/test/java/io/clusterless/tessellate/pipeline/PipelineParseTest.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import io.clusterless.tessellate.model.PipelineDef;
2020
import io.clusterless.tessellate.model.SourcePartition;
2121
import io.clusterless.tessellate.model.Transform;
22+
import io.clusterless.tessellate.parser.ast.Assignment;
2223
import io.clusterless.tessellate.parser.ast.Op;
2324
import io.clusterless.tessellate.type.WrappedCoercibleType;
2425
import io.clusterless.tessellate.util.json.JSONUtil;
@@ -28,6 +29,7 @@
2829
import java.util.TimeZone;
2930

3031
import static org.junit.jupiter.api.Assertions.assertEquals;
32+
import static org.junit.jupiter.api.Assertions.assertNull;
3133

3234
@TestWithResources
3335
public class PipelineParseTest {
@@ -51,12 +53,14 @@ void name(@GivenTextResource("config/pipeline.json") String pipelineJson) throws
5153

5254
Transform transform = pipeline.transform();
5355

54-
assertEquals(6, transform.statements().size());
56+
assertEquals(7, transform.statements().size());
5557
assertEquals(new Op(), transform.statements().get(0).op());
5658
assertEquals(new Op("->"), transform.statements().get(1).op());
5759
assertEquals(new Op("+>"), transform.statements().get(2).op());
5860
assertEquals(new Op("->"), transform.statements().get(3).op());
5961
assertEquals(new Op("=>"), transform.statements().get(4).op());
6062
assertEquals(new Op("=>"), transform.statements().get(5).op());
63+
assertEquals(new Op("=>"), transform.statements().get(6).op());
64+
assertNull(((Assignment) transform.statements().get(6)).literal());
6165
}
6266
}

tessellate-main/src/test/java/io/clusterless/tessellate/pipeline/PipelineTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,8 @@ void awsS3AccessLogWithTransforms(@PathForResource("/data/aws-s3-access-log.txt"
319319
"httpStatus->httpStatusString|String",// rename: "httpStatus|Integer"
320320
"httpStatusString|Integer",// coerce: "httpStatusString|String"
321321
"requestID->",// discard: "httpStatusString|String"
322-
"200=>code|Integer" // insert
322+
"200=>code|Integer", // insert
323+
"=> _empty|Integer" // insert
323324
))
324325
.withSink(Sink.builder()
325326
.withOutput(output)
@@ -346,7 +347,7 @@ void awsS3AccessLogWithTransforms(@PathForResource("/data/aws-s3-access-log.txt"
346347
CascadingTesting.validateEntries(
347348
pipeline.flow().openSink(),
348349
l -> assertEquals(4, l, "wrong length"), // headers are declared so aren't counted
349-
l -> assertEquals(merged.source().schema().declared().size() + 1 + 1, l, "wrong size"),
350+
l -> assertEquals(merged.source().schema().declared().size() + 1 + 1 + 1, l, "wrong size"),
350351
l -> {
351352
}
352353
);

tessellate-main/src/test/resources/config/pipeline.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"three+>@three|DateTime|yyyyMMdd",
2525
"four->",
2626
"five=>_five",
27-
"1689820455=>six|DateTime|yyyyMMdd"
27+
"1689820455=>six|DateTime|yyyyMMdd",
28+
"=> _null"
2829
]
2930
}

0 commit comments

Comments
 (0)