Skip to content

Commit 7b39d4c

Browse files
authored
feat(tests): add enum argument support to FuncTestCase grammar (#1010)
In the FuncTestCase grammar enum arguments were not handled as enum arguments but as string literals (only example so far the datetime `extract` function). - This PR changes the grammar to explicitly support enum arguments with a new `enum` data type in the grammar. - The Python code is regenerated from the grammar. - The `extract` test cases are updated to use the new syntax. Signed-off-by: Niels Pardon <par@zurich.ibm.com>
1 parent 2f836cb commit 7b39d4c

11 files changed

Lines changed: 1698 additions & 1565 deletions

grammar/FuncTestCaseLexer.g4

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ StringLiteral
113113
: '\'' ('\\' . | '\'\'' | ~['\\])* '\''
114114
;
115115

116+
EnumType: 'enum' ;
117+
116118
ColumnName
117119
: 'COL' Int
118120
;

grammar/FuncTestCaseParser.g4

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ result
4949

5050
argument
5151
: nullArg
52+
| enumArg
5253
| intArg
5354
| floatArg
5455
| booleanArg
@@ -216,6 +217,10 @@ lambdaArg
216217
: literalLambda DoubleColon funcType
217218
;
218219

220+
enumArg
221+
: Identifier DoubleColon EnumType
222+
;
223+
219224
literalList
220225
: OBracket (listElement (Comma listElement)*)? CBracket
221226
;

tests/README.md

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,10 @@ test_case := <function>(<arguments>) ([<options>])? = <result> (#<description>
104104
description := string
105105
function := string
106106
arguments := <argument>, <argument>, ... <argument>
107-
argument := <literal>
107+
argument := <literal> | <enum_value>
108108
literal := <literal_value>::<datatype>
109-
result := <substrait_error> | <literal>
109+
enum_value := <identifier>::enum
110+
result := <substrait_error> | <literal> | <enum_value>
110111
options := <option>, <option>, ... <option>
111112
option := <option_name>:<option_value>
112113
literal_value := string | integer | decimal | float | boolean | date | time | timestamp | timestamp_tz | interval year | interval days | null
@@ -148,6 +149,9 @@ Integers are represented as sequences of digits. Negative numbers are preceded b
148149
#### Boolean
149150
- Valid values: true, false
150151

152+
#### Enum
153+
- **enum**: An enumeration value represented as an identifier. Enum values are defined in extension files and are used as named constants. Example: `DISTRIBUTION_TYPE::enum` where `DISTRIBUTION_TYPE` is the enum value.
154+
151155
#### Date and Time
152156
All date and time literals use ISO 8601 format:
153157

@@ -264,3 +268,19 @@ In this example:
264268
- We are testing `functions_list.yaml` (specifically the `transform` function)
265269
- We need `functions_arithmetic.yaml` as a dependency because the lambda expressions use `multiply` and `add` from that extension
266270
- Test coverage counts towards `functions_list.yaml`, not `functions_arithmetic.yaml`
271+
272+
### Example of a test file with enum arguments
273+
274+
```code
275+
### SUBSTRAIT_SCALAR_TEST: v1.0
276+
### SUBSTRAIT_INCLUDE: '/extensions/functions_datetime.yaml'
277+
278+
# timestamps: examples using the timestamp and timestamptz types
279+
extract(YEAR::enum, '2016-12-31T13:30:15'::ts) = 2016::i64
280+
extract(ISO_YEAR::enum, '2016-01-01T13:30:15'::ts) = 2015::i64
281+
extract(QUARTER::enum, '2016-12-31T13:30:15'::ts) = 4::i64
282+
```
283+
284+
In this example:
285+
- Enum values like `YEAR`, `ISO_YEAR` and `QUARTER` are used as arguments with type `enum`
286+
- Enum types are defined in the extension file and represent named constants for function options

tests/cases/datetime/extract.test

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,30 @@
22
### SUBSTRAIT_INCLUDE: '/extensions/functions_datetime.yaml'
33

44
# timestamps: examples using the timestamp and timestamptz types
5-
extract('YEAR'::str, '2016-12-31T13:30:15'::ts) = 2016::i64
6-
extract('ISOYEAR'::str, '2016-01-01T13:30:15'::ts) = 2015::i64
7-
extract('QUARTER'::str, '2016-12-31T13:30:15'::ts) = 4::i64
8-
extract('MONTH'::str, '2016-12-31T13:30:15'::ts) = 12::i64
9-
extract('WEEK'::str, '2016-12-31T13:30:15'::ts) = 52::i64
10-
extract('DAY'::str, '2016-12-31T13:30:15'::ts) = 31::i64
11-
extract('ISODOW'::str, '2016-12-25T13:30:15'::ts) = 7::i64
12-
extract('DOW'::str, '2016-12-25T13:30:15'::ts) = 0::i64
13-
extract('DOY'::str, '2016-12-25T13:30:15'::ts) = 360::i64
14-
extract('HOUR'::str, '2016-12-31T13:30:15'::ts) = 13::i64
15-
extract('MINUTE'::str, '2016-12-31T13:30:15'::ts) = 30::i64
16-
extract('SECOND'::str, '2016-12-31T13:30:15'::ts) = 15::i64
17-
extract('MILLISECONDS'::str, '2016-12-31T13:30:15'::ts) = 15000::i64
18-
extract('MICROSECONDS'::str, '2016-12-31T13:30:15.220000'::ts) = 15220000::i64
19-
extract('EPOCH'::str, '2016-12-31T13:30:15'::ts) = 1483191015::i64
5+
extract(YEAR::enum, '2016-12-31T13:30:15'::ts) = 2016::i64
6+
extract(ISO_YEAR::enum, '2016-01-01T13:30:15'::ts) = 2015::i64
7+
extract(QUARTER::enum, '2016-12-31T13:30:15'::ts) = 4::i64
8+
extract(MONTH::enum, '2016-12-31T13:30:15'::ts) = 12::i64
9+
extract(ISO_WEEK::enum, '2016-12-31T13:30:15'::ts) = 52::i64
10+
extract(DAY::enum, '2016-12-31T13:30:15'::ts) = 31::i64
11+
extract(SUNDAY_DAY_OF_WEEK::enum, '2016-12-25T13:30:15'::ts) = 7::i64
12+
extract(MONDAY_DAY_OF_WEEK::enum, '2016-12-25T13:30:15'::ts) = 0::i64
13+
extract(DAY_OF_YEAR::enum, '2016-12-25T13:30:15'::ts) = 360::i64
14+
extract(HOUR::enum, '2016-12-31T13:30:15'::ts) = 13::i64
15+
extract(MINUTE::enum, '2016-12-31T13:30:15'::ts) = 30::i64
16+
extract(SECOND::enum, '2016-12-31T13:30:15'::ts) = 15::i64
17+
extract(MILLISECOND::enum, '2016-12-31T13:30:15'::ts) = 15000::i64
18+
extract(MICROSECOND::enum, '2016-12-31T13:30:15.220000'::ts) = 15220000::i64
19+
extract(UNIX_TIME::enum, '2016-12-31T13:30:15'::ts) = 1483191015::i64
2020

2121
# date: examples using the date type
22-
extract('YEAR'::str, '2020-12-31'::date) = 2020::i64
23-
extract('MONTH'::str, '2020-12-31'::date) = 12::i64
24-
extract('DAY'::str, '2020-12-31'::date) = 31::i64
22+
extract(YEAR::enum, '2020-12-31'::date) = 2020::i64
23+
extract(MONTH::enum, '2020-12-31'::date) = 12::i64
24+
extract(DAY::enum, '2020-12-31'::date) = 31::i64
2525

2626
# time: examples using the time type
27-
extract('HOUR'::str, '01:02:03'::time) = 1::i64
28-
extract('MINUTE'::str, '01:02:03'::time) = 2::i64
29-
extract('SECOND'::str, '01:02:03'::time) = 3::i64
30-
extract('MILLISECOND'::str, '01:02:03.155'::time) = 3155::i64
31-
extract('MICROSECOND'::str, '01:02:03.45'::time) = 3450000::i64
27+
extract(HOUR::enum, '01:02:03'::time) = 1::i64
28+
extract(MINUTE::enum, '01:02:03'::time) = 2::i64
29+
extract(SECOND::enum, '01:02:03'::time) = 3::i64
30+
extract(MILLISECOND::enum, '01:02:03.155'::time) = 3155::i64
31+
extract(MICROSECOND::enum, '01:02:03.45'::time) = 3450000::i64

0 commit comments

Comments
 (0)