Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ jobs:
uses: actions/checkout@v4
with:
repository: regtab/jregtab
ref: v0.5.0
ref: v0.7.1
token: ${{ secrets.JREGTAB_TOKEN }}
path: jregtab
- uses: actions/setup-java@v4
Expand Down
9 changes: 8 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pyregtab"
version = "0.5.1"
version = "0.7.1"
edition = "2021"
description = "Native core of pyRegTab: RTL compiler, ATP matcher and table interpreter"
license = "MIT"
Expand All @@ -20,6 +20,7 @@ python = ["dep:pyo3"]
pyo3 = { version = "0.23", features = ["abi3-py310"], optional = true }
regex = "1"
indexmap = "2"
rustc-hash = "2"

[profile.release]
lto = true
57 changes: 46 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,26 @@ and interprets the match into a relational **recordset**:
TableSyntax → RtlCompiler/TablePattern → AtpMatcher → TableInterpreter → Recordset
```

**pyRegTab 0.5.1 ≙ jRegTab 0.5.1** (same API, same semantics, same test
**pyRegTab 0.7.1 ≙ jRegTab 0.7.1** (same API, same semantics, same test
corpus), including the
embedded RTL DSL `pyregtab.dsl` — a port of jRegTab's `ru.icc.regtab.dsl`
(added upstream in jRegTab 0.3.0). Python-side extras on top of the Java API:
`AtpMatcher.match_many` (parallel batch matching), `Recordset.to_pandas()`,
`Recordset.to_csv()`, `RtlCompileError.line`/`.col` attributes, and
`CellDerivedItem.span` (the item's byte range within the raw cell text).
`Recordset.to_csv()`, `RtlCompileError.line`/`.col` attributes,
`CellDerivedItem.span` (the item's byte range within the raw cell text), and
the CLI runner `python -m pyregtab.runner` (see below).

Since 0.5.1 the language and the interpreter follow jRegTab 0.6.0–0.7.1:
`JOIN(K)` is the **record product** (a cross product for `K = ∅`, an equi-join
on the key `K` otherwise), the former folding operation is spelled
`CONCAT(K)` — a pattern written for 0.5.x must replace `JOIN(K)` by
`CONCAT(K)`; the key `K` may name attributes (`CONCAT(0, 1, 'A', 'B')`,
`JOIN('Year')`); skipped `CONCAT`/`JOIN` actions (a key mismatch, a shared
attribute, a forgotten `REC`) are reported through
`TableInterpreter.diagnostics()`; zero-width subrows match the empty
sequence and `{0}`/`{1}` are accepted; cell-derived providers use a spatial
index, so interpretation is linear in the number of cells (a 1.19 M-cell
table interprets in seconds).

## Installation

Expand Down Expand Up @@ -143,7 +156,7 @@ Rust (`pyregtab._core`, built with [PyO3](https://pyo3.rs) and

## Testing

`pytest tests` runs (1 925 tests):
`pytest tests` runs (1 981 tests):

- the full benchmark suite — tasks 001–150 (Foofah, RegTab, Baikal),
every fixture variant, **both** via RTL patterns and via ATP patterns
Expand All @@ -159,13 +172,20 @@ Rust (`pyregtab._core`, built with [PyO3](https://pyo3.rs) and
- RTL↔ATP round-trip for tasks 001–050;
- API unit tests (syntax layer, extractors, EXT bindings, custom
predicates, transformations, interpreter options, GIL-released batch
matching from a thread pool and via `AtpMatcher.match_many`).

`cargo test` additionally runs the conformance corpus and an end-to-end
smoke test against the native core alone. Differential testing against the
Java reference (`tools/differential.py` + `tools/RecordsetDumpMain.java`)
compares recordsets cell-by-cell on all 750 task variants — zero
mismatches against jRegTab v0.5.0.
matching from a thread pool and via `AtpMatcher.match_many`);
- `CONCAT`/`JOIN` semantics, named keys, diagnostics, strict preconditions,
zero-width subrows and `{0}`/`{1}` (`tests/test_join_concat.py`, a port of
jRegTab's `TableInterpreterMultiRecordTest`).

`cargo test` additionally runs the conformance corpus, an end-to-end smoke
test against the native core alone, the working-state unit tests for
`CONCAT`/`JOIN` (ports of `WorkingStateConcatTest`/`WorkingStateJoinTest`), the
zero-width matcher cases, and a randomized equivalence test of the indexed
provider against the reference definition Υ^{J,k}_{τ,κ} (full scan + sort).
Differential testing against the Java reference (`tools/differential.py` +
`tools/RecordsetDumpMain.java`) compares recordsets cell-by-cell on all 750
task variants; the 244 ATBench solutions of regtab-eval-on-atbench are
byte-identical between the jRegTab 0.7.1 runner and `python -m pyregtab.runner`.

## IDE support

Expand All @@ -180,6 +200,21 @@ IntelliJ/PyCharm and other TextMate editors is under [`ide/`](ide/README.md).
RTL is also validated at compile time: `RtlCompiler.compile(...)` raises
`RtlCompileError` with a `line:col` position on an invalid pattern.

## Command-line runner

`python -m pyregtab.runner <solution.rtl>` (or `python -m pyregtab <solution.rtl>`)
reads `./input.csv`, applies the pattern (`RtlCompiler.compile` →
`AtpMatcher.match` → `TableInterpreter` with `RECORD_FIRST` →
`pattern.transform`) and writes `./output.csv` — the schema as the header row,
every field double-quoted, a missing value as the empty string, UTF-8, LF. It
is the drop-in counterpart of the `regtab-runner` jar used by
[regtab-eval-on-atbench](https://github.com/regtab/regtab-eval-on-atbench):
same I/O contract, same exit codes (0 — success, 1 — the pattern did not
match, 2 — invalid usage), same CSV parsing (RFC 4180 with multi-line quoted
cells, ragged rows padded); on the 244 ATBench solutions of that project the
two runners produce byte-identical `output.csv`. `--input`/`--output` override
the file names, `--strict` turns interpreter diagnostics into errors.

## Development

```
Expand Down
23 changes: 23 additions & 0 deletions conformance/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,29 @@ compound specification).
> Changed in jRegTab 0.5.0. Earlier versions trimmed each substring and silently
> dropped empty ones; patterns relying on that must add `=TRIM` to the delimited atom.

## Zero-width subrows and `{n}` with n < 2

An explicit subrow (or subtable) whose children are all optional may consume no cells at
all, e.g. `{ [BLANK]* }` in a row without blank cells. It then matches the *empty sequence*,
as `*` does in regular expressions:

- the empty match is tried at the end of the row as well, so a trailing `{ [BLANK]* }`
does not make the row fail;
- a repeated empty match (`{ [BLANK]* }+`, `{ [BLANK]* }*`, `{ [BLANK]* }{3}`) counts as a
single empty iteration — implementations must not loop;
- an empty subrow covers no cells and must not appear in the interpretable table.

The quantifier `{n}` accepts any `n ≥ 0`: `{1}` is equivalent to no quantifier, `{0}` to
zero occurrences (an empty match). Only a negative `n` is a compile error. Positive case
`quantifier_small_n` pins the canonical form; the executable checks are
`semantic/subrow_zero_width_mid`, `semantic/subrow_zero_width_tail`,
`semantic/subrow_zero_width_repeated` (`+`), `semantic/subrow_zero_width_repeated_star` (`*`),
`semantic/quantifier_exactly_one`, `semantic/quantifier_exactly_zero` and the negative case
`quantifier_exactly_negative`.

> Changed in jRegTab after 0.7.0. Earlier versions raised an error for a zero-width subrow in the
> middle of a row, silently failed on one at the end of a row, and rejected `{0}` / `{1}`.

In jRegTab items 1–4 of the contract are executed by
`ru.icc.regtab.conformance.RtlConformanceTest` and item 5 by
`ru.icc.regtab.conformance.RtlSemanticConformanceTest`;
Expand Down
4 changes: 2 additions & 2 deletions conformance/UPSTREAM
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
commit: c12633763b309fd00f65d8b236a4ab91795303b4
tag: v0.5.1
commit: f0093339139f828353db31ad822dd73f68c72eab
tag: v0.7.1
path: conformance/
8 changes: 7 additions & 1 deletion conformance/VERSION
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
generated: 2026-08-26
generated: 2026-08-29
sources: RtlTask001..150 + curated extras
note: key K of CONCAT(K)/JOIN(K) may name attributes (CONCAT(0, 1, 'A', 'B'), JOIN('k')), resolved per record;
canonical form sorts positions, then names, single-quoted; curated extra named_key and
semantic cases concat_named_key, join_named_key, negative concat_empty_key_name added;
zero-width subrows match the empty sequence (never repeated) and {n} accepts n in {0, 1}:
curated extra quantifier_small_n, semantic cases subrow_zero_width_{mid,tail,repeated,repeated_star},
quantifier_exactly_{one,zero}, negative quantifier_exactly_negative added
1 change: 1 addition & 0 deletions conformance/negative/concat_empty_key_name.rtl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[ [VAL : RT->REC, BW*->CONCAT('')] ]
1 change: 1 addition & 0 deletions conformance/negative/quantifier_exactly_negative.rtl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[ [VAL]{-1} ]
1 change: 1 addition & 0 deletions conformance/positive/named_key.expected.rtl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[ [] [] [ ATTR ]+ ] [ [ VAL : RT*->REC, (BW & STR)*->CONCAT(0, 1, 'A', 'B') ] [ VAL ] [ VAL ] [ VAL : COL->AVP ]{2} ]+ [ [ VAL : COL->AVP, RT->REC, C2*->JOIN('k') ] [ VAL : COL->AVP ] [ VAL : COL->AVP, RT->REC ] [ VAL : COL->AVP ] ]+
3 changes: 3 additions & 0 deletions conformance/positive/named_key.rtl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[ [] [] [ATTR]+ ]
[ [VAL: RT*->REC, (BW&STR)*->CONCAT("B", 'A', 1, 0)] [VAL] [VAL] [VAL: COL->AVP]{2} ]+
[ [VAL: COL->AVP, RT->REC, C2*->JOIN('k')] [VAL: COL->AVP] [VAL: COL->AVP, RT->REC] [VAL: COL->AVP] ]+
1 change: 1 addition & 0 deletions conformance/positive/quantifier_small_n.expected.rtl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[ [ VAL ]{1} [ VAL ]{0} { [ BLANK ]* }{1} ]
1 change: 1 addition & 0 deletions conformance/positive/quantifier_small_n.rtl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[ [VAL]{1} [VAL]{0} { [BLANK]* }{1} ]
2 changes: 1 addition & 1 deletion conformance/positive/task_016.expected.rtl
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[ [ VAL : RT->REC, (BW & STR)*->JOIN(0) ] [ VAL ] ]+
[ [ VAL : RT->REC, (BW & STR)*->CONCAT(0) ] [ VAL ] ]+
2 changes: 1 addition & 1 deletion conformance/positive/task_016.rtl
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[ [VAL : RT->REC, BW&STR*->JOIN(0)] [VAL] ]+
[ [VAL : RT->REC, BW&STR*->CONCAT(0)] [VAL] ]+
2 changes: 1 addition & 1 deletion conformance/positive/task_023.expected.rtl
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{ [ [ VAL : ''->AVP, SR*->REC, (BW & STR)*->JOIN(0) ] [ ATTR : RT->SUFFIX ] [ AUX ] [ VAL : SR->AVP ] ]{3} }+
{ [ [ VAL : ''->AVP, SR*->REC, (BW & STR)*->CONCAT(0) ] [ ATTR : RT->SUFFIX ] [ AUX ] [ VAL : SR->AVP ] ]{3} }+
2 changes: 1 addition & 1 deletion conformance/positive/task_023.rtl
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{ [ [VAL : ''->AVP, SR*->REC, BW&STR*->JOIN(0)] [ATTR : RT->SUFFIX] [AUX] [VAL : SR->AVP] ]{3} }+
{ [ [VAL : ''->AVP, SR*->REC, BW&STR*->CONCAT(0)] [ATTR : RT->SUFFIX] [AUX] [VAL : SR->AVP] ]{3} }+
2 changes: 1 addition & 1 deletion conformance/positive/task_025.expected.rtl
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<SPLIT("/")> [ [ VAL : RT->SUFFIX("/"), (RT & C+2..)*->REC('/'), (BW & STR)*->JOIN(0) ] [ VAL ]+ ]+
<SPLIT("/")> [ [ VAL : RT->SUFFIX("/"), (RT & C+2..)*->REC('/'), (BW & STR)*->CONCAT(0) ] [ VAL ]+ ]+
2 changes: 1 addition & 1 deletion conformance/positive/task_025.rtl
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[ [VAL : RT->SUFFIX('/'), RT&C+2..*->REC('/'), BW&STR*->JOIN(0)] [VAL]+ ]+
[ [VAL : RT->SUFFIX('/'), RT&C+2..*->REC('/'), BW&STR*->CONCAT(0)] [VAL]+ ]+
2 changes: 1 addition & 1 deletion conformance/positive/task_033.expected.rtl
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[ [ VAL : SR*->REC, (BW & STR)*->JOIN(0) ] [ VAL ]+ ]+
[ [ VAL : SR*->REC, (BW & STR)*->CONCAT(0) ] [ VAL ]+ ]+
2 changes: 1 addition & 1 deletion conformance/positive/task_033.rtl
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[ [VAL : SR*->REC, BW&STR*->JOIN(0)] [VAL]+ ]+
[ [VAL : SR*->REC, BW&STR*->CONCAT(0)] [VAL]+ ]+
2 changes: 1 addition & 1 deletion conformance/positive/task_046.expected.rtl
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{ [ [ !BLANK? VAL : ''->AVP, SR*->REC, (BW & STR)*->JOIN(0) ] [ !BLANK? ATTR ] [ !BLANK? VAL : SR->AVP ] ]+ }+
{ [ [ !BLANK? VAL : ''->AVP, SR*->REC, (BW & STR)*->CONCAT(0) ] [ !BLANK? ATTR ] [ !BLANK? VAL : SR->AVP ] ]+ }+
2 changes: 1 addition & 1 deletion conformance/positive/task_046.rtl
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{ [ [!BLANK? VAL : ''->AVP, SR*->REC, BW&STR*->JOIN(0)] [!BLANK? ATTR] [!BLANK? VAL : SR->AVP] ]+ }+
{ [ [!BLANK? VAL : ''->AVP, SR*->REC, BW&STR*->CONCAT(0)] [!BLANK? ATTR] [!BLANK? VAL : SR->AVP] ]+ }+
2 changes: 1 addition & 1 deletion conformance/positive/task_047.expected.rtl
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{ [ [ !BLANK? VAL : SR*->REC, (BW & STR)*->JOIN(0) ] [ !BLANK? VAL ] ]+ }+
{ [ [ !BLANK? VAL : SR*->REC, (BW & STR)*->CONCAT(0) ] [ !BLANK? VAL ] ]+ }+
2 changes: 1 addition & 1 deletion conformance/positive/task_047.rtl
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{ [ [!BLANK? VAL : SR*->REC, BW&STR*->JOIN(0)] [!BLANK? VAL] ]+ }+
{ [ [!BLANK? VAL : SR*->REC, BW&STR*->CONCAT(0)] [!BLANK? VAL] ]+ }+
2 changes: 1 addition & 1 deletion conformance/positive/task_050.expected.rtl
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[ [ !BLANK? VAL : ''->AVP, SR*->REC, (BW & STR)*->JOIN(0) ] [ !BLANK? ATTR ] [ !BLANK? VAL : SR->AVP ] ]+
[ [ !BLANK? VAL : ''->AVP, SR*->REC, (BW & STR)*->CONCAT(0) ] [ !BLANK? ATTR ] [ !BLANK? VAL : SR->AVP ] ]+
2 changes: 1 addition & 1 deletion conformance/positive/task_050.rtl
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[ [!BLANK? VAL : ''->AVP, SR*->REC, BW&STR*->JOIN(0)] [!BLANK? ATTR] [!BLANK? VAL : SR->AVP] ]+
[ [!BLANK? VAL : ''->AVP, SR*->REC, BW&STR*->CONCAT(0)] [!BLANK? ATTR] [!BLANK? VAL : SR->AVP] ]+
2 changes: 1 addition & 1 deletion conformance/positive/task_053.expected.rtl
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[ [] [ AUX ]+ ] [ [ VAL : ROW*->REC, (BW & STR)->JOIN(0), 'ID'->AVP ] { [ ATTR : AV->PREFIX("_") ] [ VAL : SR->AVP ] }+ ]+
[ [] [ AUX ]+ ] [ [ VAL : ROW*->REC, (BW & STR)->CONCAT(0), 'ID'->AVP ] { [ ATTR : AV->PREFIX("_") ] [ VAL : SR->AVP ] }+ ]+
2 changes: 1 addition & 1 deletion conformance/positive/task_053.rtl
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[ [] [AUX]+ ]
[ [VAL : ROW*->REC, BW&STR->JOIN(0), 'ID'->AVP]
[ [VAL : ROW*->REC, BW&STR->CONCAT(0), 'ID'->AVP]
{[ATTR : AV->PREFIX('_')] [VAL : SR->AVP]}+]+
2 changes: 1 addition & 1 deletion conformance/positive/task_069.expected.rtl
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[ { [ ATTR : SR->AVP, BW*->REC ] [ VAL #'1' : SR->AVP, BW*->REC, (ROW & #'1')*->JOIN ] [ VAL #'2' : SR->AVP, BW*->REC, (ROW & #'2')*->JOIN ] }* ] [ { [ ATTR : SR->AVP ] [ VAL : SR->AVP ]{2} }* ]*
[ { [ ATTR : SR->AVP, BW*->REC ] [ VAL #'1' : SR->AVP, BW*->REC, (ROW & #'1')*->CONCAT ] [ VAL #'2' : SR->AVP, BW*->REC, (ROW & #'2')*->CONCAT ] }* ] [ { [ ATTR : SR->AVP ] [ VAL : SR->AVP ]{2} }* ]*
2 changes: 1 addition & 1 deletion conformance/positive/task_069.rtl
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
SR->AVP
[ BW*->REC { [ATTR] [VAL#'1': ROW&#'1'*->JOIN][VAL#'2': ROW&#'2'*->JOIN] }* ]
[ BW*->REC { [ATTR] [VAL#'1': ROW&#'1'*->CONCAT][VAL#'2': ROW&#'2'*->CONCAT] }* ]
[ { [ATTR] [VAL]{2} }* ]*
2 changes: 1 addition & 1 deletion conformance/positive/task_094.expected.rtl
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{ [ { [ !BLANK? VAL : COL*->REC, (ROW & C+1.. & STR)*->JOIN(0) ]+ [ BLANK ]? }+ ] } { [ { [ !BLANK? VAL ]+ [ BLANK ]? }+ ]+ [ [ BLANK ]+ ]? }+
{ [ { [ !BLANK? VAL : COL*->REC, (ROW & C+1.. & STR)*->CONCAT(0) ]+ [ BLANK ]? }+ ] } { [ { [ !BLANK? VAL ]+ [ BLANK ]? }+ ]+ [ [ BLANK ]+ ]? }+
2 changes: 1 addition & 1 deletion conformance/positive/task_094.rtl
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[ { [!BLANK? VAL: COL*->REC, ROW&C+1..&STR*->JOIN(0)]+ [BLANK]? }+ ]
[ { [!BLANK? VAL: COL*->REC, ROW&C+1..&STR*->CONCAT(0)]+ [BLANK]? }+ ]
{ [ { [!BLANK? VAL]+ [BLANK]? }+ ]+
[ [BLANK]+ ]? }+
2 changes: 1 addition & 1 deletion conformance/positive/task_097.expected.rtl
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[ [ VAL : RT*->REC, (BW & STR)*->JOIN(0, 1) ] [ VAL ]+ ]+
[ [ VAL : RT*->REC, (BW & STR)*->CONCAT(0, 1) ] [ VAL ]+ ]+
2 changes: 1 addition & 1 deletion conformance/positive/task_097.rtl
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[ [VAL: RT*->REC, (BW&STR)*->JOIN(0,1)] [VAL]+ ]+
[ [VAL: RT*->REC, (BW&STR)*->CONCAT(0,1)] [VAL]+ ]+
2 changes: 1 addition & 1 deletion conformance/positive/task_098.expected.rtl
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[ [] [] [ ATTR ]+ ] [ [ VAL : RT*->REC, (BW & STR)*->JOIN(0, 1) ] [ VAL ] [ VAL : COL->AVP ]{2} [ VAL ]+ ]+
[ [] [] [ ATTR ]+ ] [ [ VAL : RT*->REC, (BW & STR)*->CONCAT(0, 1, 2, 3) ] [ VAL ] [ VAL : COL->AVP ]{2} [ VAL ]+ ]+
2 changes: 1 addition & 1 deletion conformance/positive/task_098.rtl
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[ [] [] [ATTR]+ ]
[ [VAL: RT*->REC, (BW&STR)*->JOIN(0,1)] [VAL] [VAL: COL->AVP]{2} [VAL]+ ]+
[ [VAL: RT*->REC, (BW&STR)*->CONCAT(0,1,2,3)] [VAL] [VAL: COL->AVP]{2} [VAL]+ ]+
3 changes: 3 additions & 0 deletions conformance/semantic/concat_by_key/expected.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"book","5","6","7"
"cat","2","3","8"
"dog","2","3","4"
9 changes: 9 additions & 0 deletions conformance/semantic/concat_by_key/input.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"book","5"
"book","6"
"book","7"
"cat","2"
"cat","3"
"cat","8"
"dog","2"
"dog","3"
"dog","4"
1 change: 1 addition & 0 deletions conformance/semantic/concat_by_key/options.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "expectedHasHeader": false }
1 change: 1 addition & 0 deletions conformance/semantic/concat_by_key/pattern.rtl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[ [VAL : RT->REC, BW&STR*->CONCAT(0)] [VAL] ]+
2 changes: 2 additions & 0 deletions conformance/semantic/concat_named_key/expected.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
"k1","k11","c1","a1","b1","c2"
"k2","k22","c3","a2","b2","c4"
5 changes: 5 additions & 0 deletions conformance/semantic/concat_named_key/input.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"","","C","A","B"
"k1","k11","c1","a1","b1"
"k1","k11","c2","a1","b1"
"k2","k22","c3","a2","b2"
"k2","k22","c4","a2","b2"
1 change: 1 addition & 0 deletions conformance/semantic/concat_named_key/options.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "expectedHasHeader": false }
2 changes: 2 additions & 0 deletions conformance/semantic/concat_named_key/pattern.rtl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[ [] [] [ATTR]+ ]
[ [VAL: RT*->REC, (BW&STR)*->CONCAT(0, 1, 'A', 'B')] [VAL] [VAL] [VAL: COL->AVP]{2} ]+
3 changes: 3 additions & 0 deletions conformance/semantic/join_equi_key/expected.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"k","v","u"
"X","5","kg"
"Y","8","pc"
3 changes: 3 additions & 0 deletions conformance/semantic/join_equi_key/input.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"k","v","k","u"
"X","5","X","kg"
"Y","8","Y","pc"
1 change: 1 addition & 0 deletions conformance/semantic/join_equi_key/options.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "expectedHasHeader": true }
2 changes: 2 additions & 0 deletions conformance/semantic/join_equi_key/pattern.rtl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[ [ATTR]+ ]
[ [VAL: COL->AVP, RT->REC, C2*->JOIN(0)] [VAL: COL->AVP] [VAL: COL->AVP, RT->REC] [VAL: COL->AVP] ]+
3 changes: 3 additions & 0 deletions conformance/semantic/join_named_key/expected.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"k","v","u"
"X","5","kg"
"Y","8","pc"
3 changes: 3 additions & 0 deletions conformance/semantic/join_named_key/input.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"k","v","k","u"
"X","5","X","kg"
"Y","8","Y","pc"
1 change: 1 addition & 0 deletions conformance/semantic/join_named_key/options.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "expectedHasHeader": true }
2 changes: 2 additions & 0 deletions conformance/semantic/join_named_key/pattern.rtl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[ [ATTR]+ ]
[ [VAL: COL->AVP, RT->REC, C2*->JOIN('k')] [VAL: COL->AVP] [VAL: COL->AVP, RT->REC] [VAL: COL->AVP] ]+
7 changes: 7 additions & 0 deletions conformance/semantic/join_product/expected.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"id","value","var"
"a","1","x"
"a","2","y"
"b","1","x"
"b","2","y"
"c","3","x"
"c","4","y"
3 changes: 3 additions & 0 deletions conformance/semantic/join_product/input.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"id","x","y"
"a;b","1","2"
"c","3","4"
1 change: 1 addition & 0 deletions conformance/semantic/join_product/options.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "expectedHasHeader": true }
2 changes: 2 additions & 0 deletions conformance/semantic/join_product/pattern.rtl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[ [ATTR] [VAL: 'var'->AVP]+ ]
[ [(VAL: COL->AVP, ()->REC, RT*->JOIN){';'}] [VAL: 'value'->AVP, COL->REC]+ ]+
2 changes: 2 additions & 0 deletions conformance/semantic/quantifier_exactly_one/expected.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
x,1
y,2
3 changes: 3 additions & 0 deletions conformance/semantic/quantifier_exactly_one/input.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
A,B
x,1
y,2
2 changes: 2 additions & 0 deletions conformance/semantic/quantifier_exactly_one/pattern.rtl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[ [ATTR]+ ]
[ [VAL: COL->AVP, ROW*->REC] { [BLANK]* }{1} [VAL: COL->AVP] ]+
2 changes: 2 additions & 0 deletions conformance/semantic/quantifier_exactly_zero/expected.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
x,1
y,2
3 changes: 3 additions & 0 deletions conformance/semantic/quantifier_exactly_zero/input.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
A,B
x,1
y,2
2 changes: 2 additions & 0 deletions conformance/semantic/quantifier_exactly_zero/pattern.rtl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[ [ATTR]+ ]
[ [VAL: COL->AVP, ROW*->REC] { [BLANK]* }{0} [VAL: COL->AVP] ]+
2 changes: 2 additions & 0 deletions conformance/semantic/subrow_zero_width_mid/expected.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
x,1
y,2
3 changes: 3 additions & 0 deletions conformance/semantic/subrow_zero_width_mid/input.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
A,B
x,1
y,2
2 changes: 2 additions & 0 deletions conformance/semantic/subrow_zero_width_mid/pattern.rtl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[ [ATTR]+ ]
[ [VAL: COL->AVP, ROW*->REC] { [BLANK]* } [VAL: COL->AVP] ]+
2 changes: 2 additions & 0 deletions conformance/semantic/subrow_zero_width_repeated/expected.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
x,1
y,2
3 changes: 3 additions & 0 deletions conformance/semantic/subrow_zero_width_repeated/input.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
A,B
x,1
y,2
2 changes: 2 additions & 0 deletions conformance/semantic/subrow_zero_width_repeated/pattern.rtl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[ [ATTR]+ ]
[ [VAL: COL->AVP, ROW*->REC] { [BLANK]* }+ [VAL: COL->AVP] { [BLANK]* }+ ]+
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
x,1
y,2
Loading
Loading