embulk-filter-row 0.3.2 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +10 -6
- data/build.gradle +1 -1
- data/src/main/java/org/embulk/filter/row/where/Parser.java +144 -90
- data/src/main/java/org/embulk/filter/row/where/ParserExp.java +112 -8
- data/src/main/java/org/embulk/filter/row/where/ParserLiteral.java +46 -22
- data/src/main/java/org/embulk/filter/row/where/Yylex.java +115 -111
- data/src/main/java/org/embulk/filter/row/where/_lexer.l +3 -2
- data/src/main/java/org/embulk/filter/row/where/_parser.y +47 -38
- data/src/test/java/org/embulk/filter/row/where/TestParser.java +107 -5
- metadata +3 -3
@@ -46,14 +46,15 @@ Newline = \n|\r|\r\n
|
|
46
46
|
"START_WITH" { return Parser.START_WITH; }
|
47
47
|
"END_WITH" { return Parser.END_WITH; }
|
48
48
|
"INCLUDE" { return Parser.INCLUDE; }
|
49
|
+
"REGEXP" { return Parser.REGEXP; }
|
49
50
|
"IS" { return Parser.IS; }
|
50
51
|
"NOT" { return Parser.NOT; }
|
51
52
|
"NULL" { return Parser.NULL; }
|
52
53
|
"TIMESTAMP" { return Parser.TIMESTAMP; }
|
53
54
|
|
54
55
|
/* boolean literal */
|
55
|
-
"true" | "TRUE" { yyparser.yylval = new ParserVal(new BooleanLiteral(
|
56
|
-
"false" | "FALSE" { yyparser.yylval = new ParserVal(new BooleanLiteral(
|
56
|
+
"true" | "TRUE" { yyparser.yylval = new ParserVal(new BooleanLiteral(yytext())); return Parser.BOOLEAN; }
|
57
|
+
"false" | "FALSE" { yyparser.yylval = new ParserVal(new BooleanLiteral(yytext())); return Parser.BOOLEAN; }
|
57
58
|
|
58
59
|
/* number literal */
|
59
60
|
{Number} { yyparser.yylval = new ParserVal(new NumberLiteral(yytext())); return Parser.NUMBER; }
|
@@ -43,44 +43,53 @@ input: /* empty string */
|
|
43
43
|
timestamp: TIMESTAMP STRING { $$ = new ParserVal(new TimestampLiteral($2)); }
|
44
44
|
| TIMESTAMP NUMBER { $$ = new ParserVal(new TimestampLiteral($2)); }
|
45
45
|
|
46
|
-
exp: IDENTIFIER EQ BOOLEAN { $$ = new ParserVal(
|
47
|
-
| IDENTIFIER NEQ BOOLEAN { $$ = new ParserVal(
|
48
|
-
| BOOLEAN EQ IDENTIFIER { $$ = new ParserVal(
|
49
|
-
| BOOLEAN NEQ IDENTIFIER { $$ = new ParserVal(
|
50
|
-
| IDENTIFIER EQ NUMBER { $$ = new ParserVal(
|
51
|
-
| IDENTIFIER NEQ NUMBER { $$ = new ParserVal(
|
52
|
-
| IDENTIFIER GT NUMBER { $$ = new ParserVal(
|
53
|
-
| IDENTIFIER GE NUMBER { $$ = new ParserVal(
|
54
|
-
| IDENTIFIER LT NUMBER { $$ = new ParserVal(
|
55
|
-
| IDENTIFIER LE NUMBER { $$ = new ParserVal(
|
56
|
-
| NUMBER EQ IDENTIFIER { $$ = new ParserVal(
|
57
|
-
| NUMBER NEQ IDENTIFIER { $$ = new ParserVal(
|
58
|
-
| NUMBER GT IDENTIFIER { $$ = new ParserVal(
|
59
|
-
| NUMBER GE IDENTIFIER { $$ = new ParserVal(
|
60
|
-
| NUMBER LT IDENTIFIER { $$ = new ParserVal(
|
61
|
-
| NUMBER LE IDENTIFIER { $$ = new ParserVal(
|
62
|
-
| IDENTIFIER EQ
|
63
|
-
| IDENTIFIER NEQ
|
64
|
-
| IDENTIFIER
|
65
|
-
| IDENTIFIER
|
66
|
-
| IDENTIFIER
|
67
|
-
|
|
68
|
-
| STRING
|
69
|
-
| STRING
|
70
|
-
| STRING
|
71
|
-
| STRING
|
72
|
-
| IDENTIFIER
|
73
|
-
| IDENTIFIER
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
| IDENTIFIER
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
| timestamp
|
82
|
-
|
|
83
|
-
|
|
46
|
+
exp: IDENTIFIER EQ BOOLEAN { $$ = new ParserVal(BinaryOpExp.create($1, $3, EQ)); }
|
47
|
+
| IDENTIFIER NEQ BOOLEAN { $$ = new ParserVal(BinaryOpExp.create($1, $3, NEQ)); }
|
48
|
+
| BOOLEAN EQ IDENTIFIER { $$ = new ParserVal(BinaryOpExp.create($1, $3, EQ)); }
|
49
|
+
| BOOLEAN NEQ IDENTIFIER { $$ = new ParserVal(BinaryOpExp.create($1, $3, NEQ)); }
|
50
|
+
| IDENTIFIER EQ NUMBER { $$ = new ParserVal(BinaryOpExp.create($1, $3, EQ)); }
|
51
|
+
| IDENTIFIER NEQ NUMBER { $$ = new ParserVal(BinaryOpExp.create($1, $3, NEQ)); }
|
52
|
+
| IDENTIFIER GT NUMBER { $$ = new ParserVal(BinaryOpExp.create($1, $3, GT)); }
|
53
|
+
| IDENTIFIER GE NUMBER { $$ = new ParserVal(BinaryOpExp.create($1, $3, GE)); }
|
54
|
+
| IDENTIFIER LT NUMBER { $$ = new ParserVal(BinaryOpExp.create($1, $3, LT)); }
|
55
|
+
| IDENTIFIER LE NUMBER { $$ = new ParserVal(BinaryOpExp.create($1, $3, LE)); }
|
56
|
+
| NUMBER EQ IDENTIFIER { $$ = new ParserVal(BinaryOpExp.create($1, $3, EQ)); }
|
57
|
+
| NUMBER NEQ IDENTIFIER { $$ = new ParserVal(BinaryOpExp.create($1, $3, NEQ)); }
|
58
|
+
| NUMBER GT IDENTIFIER { $$ = new ParserVal(BinaryOpExp.create($1, $3, GT)); }
|
59
|
+
| NUMBER GE IDENTIFIER { $$ = new ParserVal(BinaryOpExp.create($1, $3, GE)); }
|
60
|
+
| NUMBER LT IDENTIFIER { $$ = new ParserVal(BinaryOpExp.create($1, $3, LT)); }
|
61
|
+
| NUMBER LE IDENTIFIER { $$ = new ParserVal(BinaryOpExp.create($1, $3, LE)); }
|
62
|
+
| IDENTIFIER EQ STRING { $$ = new ParserVal(BinaryOpExp.create($1, $3, EQ)); }
|
63
|
+
| IDENTIFIER NEQ STRING { $$ = new ParserVal(BinaryOpExp.create($1, $3, NEQ)); }
|
64
|
+
| IDENTIFIER GT STRING { $$ = new ParserVal(BinaryOpExp.create($1, $3, GT)); }
|
65
|
+
| IDENTIFIER GE STRING { $$ = new ParserVal(BinaryOpExp.create($1, $3, GE)); }
|
66
|
+
| IDENTIFIER LT STRING { $$ = new ParserVal(BinaryOpExp.create($1, $3, LT)); }
|
67
|
+
| IDENTIFIER LE STRING { $$ = new ParserVal(BinaryOpExp.create($1, $3, LE)); }
|
68
|
+
| IDENTIFIER START_WITH STRING { $$ = new ParserVal(BinaryOpExp.create($1, $3, START_WITH)); }
|
69
|
+
| IDENTIFIER END_WITH STRING { $$ = new ParserVal(BinaryOpExp.create($1, $3, END_WITH)); }
|
70
|
+
| IDENTIFIER INCLUDE STRING { $$ = new ParserVal(BinaryOpExp.create($1, $3, INCLUDE)); }
|
71
|
+
| STRING EQ IDENTIFIER { $$ = new ParserVal(BinaryOpExp.create($1, $3, EQ)); }
|
72
|
+
| STRING NEQ IDENTIFIER { $$ = new ParserVal(BinaryOpExp.create($1, $3, NEQ)); }
|
73
|
+
| STRING GT IDENTIFIER { $$ = new ParserVal(BinaryOpExp.create($1, $3, GT)); }
|
74
|
+
| STRING GE IDENTIFIER { $$ = new ParserVal(BinaryOpExp.create($1, $3, GE)); }
|
75
|
+
| STRING LT IDENTIFIER { $$ = new ParserVal(BinaryOpExp.create($1, $3, LT)); }
|
76
|
+
| STRING LE IDENTIFIER { $$ = new ParserVal(BinaryOpExp.create($1, $3, LE)); }
|
77
|
+
| STRING START_WITH IDENTIFIER { $$ = new ParserVal(BinaryOpExp.create($1, $3, START_WITH)); }
|
78
|
+
| STRING END_WITH IDENTIFIER { $$ = new ParserVal(BinaryOpExp.create($1, $3, END_WITH)); }
|
79
|
+
| STRING INCLUDE IDENTIFIER { $$ = new ParserVal(BinaryOpExp.create($1, $3, INCLUDE)); }
|
80
|
+
| IDENTIFIER EQ timestamp { $$ = new ParserVal(BinaryOpExp.create($1, $3, EQ)); }
|
81
|
+
| IDENTIFIER NEQ timestamp { $$ = new ParserVal(BinaryOpExp.create($1, $3, NEQ)); }
|
82
|
+
| IDENTIFIER GT timestamp { $$ = new ParserVal(BinaryOpExp.create($1, $3, GT)); }
|
83
|
+
| IDENTIFIER GE timestamp { $$ = new ParserVal(BinaryOpExp.create($1, $3, GE)); }
|
84
|
+
| IDENTIFIER LT timestamp { $$ = new ParserVal(BinaryOpExp.create($1, $3, LT)); }
|
85
|
+
| IDENTIFIER LE timestamp { $$ = new ParserVal(BinaryOpExp.create($1, $3, LE)); }
|
86
|
+
| timestamp EQ IDENTIFIER { $$ = new ParserVal(BinaryOpExp.create($1, $3, EQ)); }
|
87
|
+
| timestamp NEQ IDENTIFIER { $$ = new ParserVal(BinaryOpExp.create($1, $3, NEQ)); }
|
88
|
+
| timestamp GT IDENTIFIER { $$ = new ParserVal(BinaryOpExp.create($1, $3, GT)); }
|
89
|
+
| timestamp GE IDENTIFIER { $$ = new ParserVal(BinaryOpExp.create($1, $3, GE)); }
|
90
|
+
| timestamp LT IDENTIFIER { $$ = new ParserVal(BinaryOpExp.create($1, $3, LT)); }
|
91
|
+
| timestamp LE IDENTIFIER { $$ = new ParserVal(BinaryOpExp.create($1, $3, LE)); }
|
92
|
+
| IDENTIFIER REGEXP STRING { $$ = new ParserVal(new RegexpOpExp($1, $3, REGEXP)); }
|
84
93
|
| IDENTIFIER IS NULL { $$ = new ParserVal(new NullOpExp($1, EQ)); }
|
85
94
|
| IDENTIFIER IS NOT NULL { $$ = new ParserVal(new NullOpExp($1, NEQ)); }
|
86
95
|
| exp OR exp { $$ = new ParserVal(new LogicalOpExp($1, $3, OR)); }
|
@@ -1,6 +1,7 @@
|
|
1
1
|
package org.embulk.filter.row.where;
|
2
2
|
|
3
3
|
import org.embulk.EmbulkTestRuntime;
|
4
|
+
import org.embulk.config.Config;
|
4
5
|
import org.embulk.config.ConfigException;
|
5
6
|
import org.embulk.spi.Page;
|
6
7
|
import org.embulk.spi.PageReader;
|
@@ -96,7 +97,7 @@ public class TestParser
|
|
96
97
|
assertTrue(exp.eval(reader));
|
97
98
|
|
98
99
|
try {
|
99
|
-
|
100
|
+
parser.parse("\"unknown\" IS NULL");
|
100
101
|
assertTrue(false);
|
101
102
|
}
|
102
103
|
catch (SchemaConfigException e) {
|
@@ -123,7 +124,14 @@ public class TestParser
|
|
123
124
|
assertTrue(exp.eval(reader));
|
124
125
|
|
125
126
|
try {
|
126
|
-
|
127
|
+
parser.parse("timestamp = true");
|
128
|
+
assertTrue(false);
|
129
|
+
}
|
130
|
+
catch (ConfigException e) {
|
131
|
+
}
|
132
|
+
|
133
|
+
try {
|
134
|
+
parser.parse("boolean > true");
|
127
135
|
assertTrue(false);
|
128
136
|
}
|
129
137
|
catch (ConfigException e) {
|
@@ -170,7 +178,14 @@ public class TestParser
|
|
170
178
|
assertTrue(exp.eval(reader));
|
171
179
|
|
172
180
|
try {
|
173
|
-
|
181
|
+
parser.parse("boolean = 1.5");
|
182
|
+
assertTrue(false);
|
183
|
+
}
|
184
|
+
catch (ConfigException e) {
|
185
|
+
}
|
186
|
+
|
187
|
+
try {
|
188
|
+
parser.parse("double START_WITH 1.5");
|
174
189
|
assertTrue(false);
|
175
190
|
}
|
176
191
|
catch (ConfigException e) {
|
@@ -198,6 +213,26 @@ public class TestParser
|
|
198
213
|
exp = parser.parse("string <> 'string'");
|
199
214
|
assertFalse(exp.eval(reader));
|
200
215
|
|
216
|
+
exp = parser.parse("string > 's'");
|
217
|
+
assertTrue(exp.eval(reader));
|
218
|
+
exp = parser.parse("string > 't'");
|
219
|
+
assertFalse(exp.eval(reader));
|
220
|
+
|
221
|
+
exp = parser.parse("string >= 's'");
|
222
|
+
assertTrue(exp.eval(reader));
|
223
|
+
exp = parser.parse("string >= 't'");
|
224
|
+
assertFalse(exp.eval(reader));
|
225
|
+
|
226
|
+
exp = parser.parse("string < 't'");
|
227
|
+
assertTrue(exp.eval(reader));
|
228
|
+
exp = parser.parse("string < 's'");
|
229
|
+
assertFalse(exp.eval(reader));
|
230
|
+
|
231
|
+
exp = parser.parse("string <= 't'");
|
232
|
+
assertTrue(exp.eval(reader));
|
233
|
+
exp = parser.parse("string <= 's'");
|
234
|
+
assertFalse(exp.eval(reader));
|
235
|
+
|
201
236
|
exp = parser.parse("string START_WITH 's'");
|
202
237
|
assertTrue(exp.eval(reader));
|
203
238
|
exp = parser.parse("string START_WITH 'f'");
|
@@ -217,7 +252,14 @@ public class TestParser
|
|
217
252
|
assertTrue(exp.eval(reader));
|
218
253
|
|
219
254
|
try {
|
220
|
-
|
255
|
+
parser.parse("boolean = 'string'");
|
256
|
+
assertTrue(false);
|
257
|
+
}
|
258
|
+
catch (ConfigException e) {
|
259
|
+
}
|
260
|
+
|
261
|
+
try {
|
262
|
+
parser.parse("string AND 'string'");
|
221
263
|
assertTrue(false);
|
222
264
|
}
|
223
265
|
catch (ConfigException e) {
|
@@ -262,6 +304,19 @@ public class TestParser
|
|
262
304
|
|
263
305
|
exp = parser.parse("TIMESTAMP 1.5 = timestamp");
|
264
306
|
assertTrue(exp.eval(reader));
|
307
|
+
|
308
|
+
// auto guess of TIMESTAMP
|
309
|
+
exp = parser.parse("timestamp = 1.5");
|
310
|
+
assertTrue(exp.eval(reader));
|
311
|
+
exp = parser.parse("1.5 = timestamp");
|
312
|
+
assertTrue(exp.eval(reader));
|
313
|
+
|
314
|
+
try {
|
315
|
+
parser.parse("timestamp START_WITH 1.5");
|
316
|
+
assertTrue(false);
|
317
|
+
}
|
318
|
+
catch (ConfigException e) {
|
319
|
+
}
|
265
320
|
}
|
266
321
|
|
267
322
|
@Test
|
@@ -316,12 +371,59 @@ public class TestParser
|
|
316
371
|
exp = parser.parse("timestamp = TIMESTAMP '1970-01-01'");
|
317
372
|
assertFalse(exp.eval(reader));
|
318
373
|
|
374
|
+
// auto guess of TIMESTAMP
|
375
|
+
exp = parser.parse("timestamp = '1970-01-01 09:00:01.5 +0900'");
|
376
|
+
assertTrue(exp.eval(reader));
|
377
|
+
exp = parser.parse("'1970-01-01 09:00:01.5 +0900' = timestamp");
|
378
|
+
assertTrue(exp.eval(reader));
|
379
|
+
|
319
380
|
try {
|
320
|
-
parser.parse("timestamp =
|
381
|
+
parser.parse("timestamp = '1970:01:01'");
|
321
382
|
assertTrue(false);
|
322
383
|
}
|
323
384
|
catch (TimestampParseException ex) {
|
324
385
|
}
|
386
|
+
|
387
|
+
try {
|
388
|
+
parser.parse("timestamp START_WITH '1970-01-01 09:00:01.5 +0900'");
|
389
|
+
assertTrue(false);
|
390
|
+
}
|
391
|
+
catch (ConfigException e) {
|
392
|
+
}
|
393
|
+
}
|
394
|
+
|
395
|
+
@Test
|
396
|
+
public void testRegexpOpExp()
|
397
|
+
{
|
398
|
+
Parser parser = new Parser(schema);
|
399
|
+
ParserExp exp;
|
400
|
+
|
401
|
+
exp = parser.parse("string REGEXP '^st'");
|
402
|
+
assertTrue(exp.eval(reader));
|
403
|
+
exp = parser.parse("string REGEXP 'st$'");
|
404
|
+
assertFalse(exp.eval(reader));
|
405
|
+
|
406
|
+
try {
|
407
|
+
// right-side identifier is not allowed
|
408
|
+
parser.parse("'string' REGEXP string");
|
409
|
+
assertTrue(false);
|
410
|
+
}
|
411
|
+
catch (ConfigException e) {
|
412
|
+
}
|
413
|
+
|
414
|
+
try {
|
415
|
+
parser.parse("string REGEXP 1.5");
|
416
|
+
assertTrue(false);
|
417
|
+
}
|
418
|
+
catch (ConfigException e) {
|
419
|
+
}
|
420
|
+
|
421
|
+
try {
|
422
|
+
parser.parse("boolean REGEXP '^st'");
|
423
|
+
assertTrue(false);
|
424
|
+
}
|
425
|
+
catch (ConfigException e) {
|
426
|
+
}
|
325
427
|
}
|
326
428
|
|
327
429
|
@Test
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: embulk-filter-row
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Naotoshi Seo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-08-
|
11
|
+
date: 2016-08-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -94,7 +94,7 @@ files:
|
|
94
94
|
- src/test/java/org/embulk/filter/row/condition/TestTimestampCondition.java
|
95
95
|
- src/test/java/org/embulk/filter/row/where/TestParser.java
|
96
96
|
- src/test/java/org/embulk/filter/row/where/TestYylex.java
|
97
|
-
- classpath/embulk-filter-row-0.3.
|
97
|
+
- classpath/embulk-filter-row-0.3.3.jar
|
98
98
|
homepage: https://github.com/sonots/embulk-filter-row
|
99
99
|
licenses:
|
100
100
|
- MIT
|