@malloydata/malloy-filter 0.0.237-dev250222034547 → 0.0.237-dev250223010918

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import {SpecialToken, Tokenizer, TokenizerParams} from './tokenizer';
1
+ import * as fs from 'fs';
2
2
  import {BooleanParser} from './boolean_parser';
3
3
  import {StringParser} from './string_parser';
4
4
  import {NumberParser} from './number_parser';
@@ -7,15 +7,11 @@ import {BooleanSerializer} from './boolean_serializer';
7
7
  import {StringSerializer} from './string_serializer';
8
8
  import {NumberSerializer} from './number_serializer';
9
9
  import {DateSerializer} from './date_serializer';
10
- import {BooleanClause, NumberClause, StringClause} from './clause_types';
11
- import {DateClause} from './date_types';
12
-
13
- type Clause = BooleanClause | DateClause | NumberClause | StringClause;
14
10
 
15
11
  const numberExamples = [
16
12
  '5',
17
13
  '!=5',
18
- '1, 3, null , 7',
14
+ '1, 3, 5, null',
19
15
  '<1, >=100 ',
20
16
  '>=1',
21
17
  ' <= 10 ',
@@ -70,9 +66,10 @@ const stringExamples = [
70
66
  const booleanExamples = [
71
67
  'true',
72
68
  'FALSE',
69
+ '=false',
73
70
  'null',
74
71
  '-NULL',
75
- ' True , faLSE,NULl,-null',
72
+ ' True , faLSE,=false,NULl,-null',
76
73
  "-'null'",
77
74
  '10',
78
75
  'nnull',
@@ -84,7 +81,6 @@ const dateExamples = [
84
81
  '3 days',
85
82
  '3 days ago',
86
83
  '3 months ago for 2 days',
87
- 'after 2025 seconds',
88
84
  '2025 weeks ago',
89
85
  'before 3 days ago',
90
86
  'before 2025-08-30 08:30:20',
@@ -104,341 +100,248 @@ const dateExamples = [
104
100
  'next week',
105
101
  'now',
106
102
  'now to next month',
103
+ 'null',
104
+ '-null,',
107
105
  ' yyesterday ', // Typo
108
106
  'before', // Bad syntax
109
107
  'for', // Bad syntax
110
108
  '7', // Bad syntax
111
109
  'from now', // Bad syntax
112
110
  '2025-12-25 12:32:', // Bad syntax
111
+ 'after 2025 seconds', // Bad syntax
113
112
  '',
114
113
  ];
115
114
 
116
115
  /* eslint-disable @typescript-eslint/no-unused-vars */
117
116
  /* eslint-disable no-console */
117
+ /* eslint-disable @typescript-eslint/no-explicit-any */
118
118
 
119
- function testTokenizerSingle(str: string, params: TokenizerParams): void {
120
- const tokenizer = new Tokenizer(str, params);
121
- console.log(str, ' -> ', tokenizer.parse(), '\n');
122
- }
123
-
124
- function testTokenizerString() {
125
- // Test string parser tokenizer. Do not split on whitespace
126
- const specialSubstrings: SpecialToken[] = [{type: ',', value: ','}];
127
- const specialWords: SpecialToken[] = [];
128
- const params: TokenizerParams = {
129
- trimWordWhitespace: true,
130
- combineAdjacentWords: true,
131
- specialSubstrings,
132
- specialWords,
133
- };
134
- const examples = [
135
- 'CAT, DOG,mouse ',
136
- '-CAT,-DOG , -mouse',
137
- ' CAT,-"DOG",m o u s e',
138
- '-CAT,-DOG,mouse, bird, zebra, -horse, -goat',
139
- 'Missing ,NULL',
140
- 'CAT%,D%OG',
141
- 'CAT%,-CATALOG',
142
- '_CAT,D_G',
143
- 'CAT,-NULL',
144
- 'CAT,-"NULL"',
145
- 'EMPTY',
146
- '-EMPTY',
147
- 'CAT,-EMPTY',
148
- '"CAT,DOG"',
149
- 'CAT\\,DOG',
150
- 'CAT,DOG,-, - ',
151
- '--CAT,DOG,\\',
152
- 'CA--,D-G', // _ = 'CA--' OR _ = 'D-G'
153
- ' hello world, foo="bar baz" , qux=quux',
154
- 'one ,Null , Empty,E M P T Y Y,EEmpty, emptIEs',
155
- '',
156
- ];
157
- for (const example of examples) {
158
- testTokenizerSingle(example, params);
159
- }
160
- }
161
-
162
- function testTokenizerNumber() {
163
- // Test number parser tokenizer, split on whitespace
164
- const specialSubstrings: SpecialToken[] = [
165
- {type: ',', value: ','},
166
- {type: '[', value: '['},
167
- {type: ']', value: ']'},
168
- {type: '(', value: '('},
169
- {type: ')', value: ')'},
170
- {type: '<=', value: '<='},
171
- {type: '>=', value: '>='},
172
- {type: '!=', value: '!='},
173
- {type: '=', value: '='},
174
- {type: '>', value: '>'},
175
- {type: '<', value: '<'},
176
- ];
177
- const specialWords: SpecialToken[] = [
178
- {type: 'TO', value: 'to', ignoreCase: true},
179
- {type: '-NULL', value: '-null', ignoreCase: true},
180
- {type: 'NULL', value: 'null', ignoreCase: true},
181
- ];
182
- const params: TokenizerParams = {
183
- trimWordWhitespace: true,
184
- combineAdjacentWords: false,
185
- splitOnWhitespace: true,
186
- specialSubstrings,
187
- specialWords,
188
- };
189
- const examples = [
190
- '5',
191
- '!=5',
192
- '1, 3, null , 7',
193
- '<1, >=100 ',
194
- '-5.5 to 10',
195
- '>=1',
196
- ' <= 10 ',
197
- 'NULL',
198
- ' -NULL',
199
- '(1, 7)',
200
- '[-5, 90]',
201
- ' ( 12, 20 ] ',
202
- '[.12e-20, 20.0e3)',
203
- '[0,9],[20,29]',
204
- '[0,10], 20, NULL, ( 72, 82 ] ',
205
- ', notanumber,, -"-null", apple pear orange, nulle, nnull',
206
- ];
207
- for (const example of examples) {
208
- testTokenizerSingle(example, params);
209
- }
210
- }
119
+ class GenerateSamples {
120
+ public samplesFile: fs.WriteStream = fs.createWriteStream('dist/SAMPLES.md');
121
+ public serializedFile: fs.WriteStream = fs.createWriteStream(
122
+ 'dist/SERIALIZE_SAMPLES.md'
123
+ );
124
+ constructor() {}
211
125
 
212
- function testNumberParserSingle(
213
- str: string,
214
- outputFormatter?: (clauses: Clause[]) => string
215
- ): void {
216
- console.log('Input: ', str);
217
- const parser = new NumberParser(str);
218
- const response = parser.parse();
219
- // console.log('Tokens: ', parser.getTokens());
220
- if (response.clauses && response.clauses.length > 0) {
221
- if (outputFormatter) {
222
- console.log('Output: ', outputFormatter(response.clauses));
223
- } else {
224
- console.log('Output: ', ...response.clauses);
126
+ private static removeQuotes(word: string) {
127
+ if (word.startsWith('"')) {
128
+ word = word.substring(1);
225
129
  }
226
- }
227
- if (response.errors && response.errors.length > 0) {
228
- console.log('Errors: ', ...response.errors);
229
- }
230
- console.log('');
231
- }
232
-
233
- function testNumberParser() {
234
- for (const example of numberExamples) {
235
- testNumberParserSingle(example);
236
- }
237
- }
238
-
239
- function testStringParserSingle(
240
- str: string,
241
- outputFormatter?: (clauses: Clause[]) => string
242
- ): void {
243
- console.log('Input: ', str);
244
- const parser = new StringParser(str);
245
- const response = parser.parse();
246
- // console.log('Tokens: ', parser.getTokens());
247
- if (response.clauses && response.clauses.length > 0) {
248
- if (outputFormatter) {
249
- console.log('Output: ', outputFormatter(response.clauses));
250
- } else {
251
- console.log('Output: ', ...response.clauses);
130
+ if (word.endsWith('"')) {
131
+ word = word.substring(0, word.length - 1);
252
132
  }
133
+ return word;
253
134
  }
254
- if (response.errors && response.errors.length > 0) {
255
- console.log('Errors: ', ...response.errors);
256
- }
257
- console.log('');
258
- }
259
135
 
260
- function testStringParser() {
261
- for (const example of stringExamples) {
262
- const parser = new StringParser(example);
263
- testStringParserSingle(example);
136
+ private static writeJson(
137
+ fp: fs.WriteStream,
138
+ title: string,
139
+ ...args: any[]
140
+ ): void {
141
+ const result: string[] = args.map(str => JSON.stringify(str));
142
+ const result2: string[] = result.map(str =>
143
+ GenerateSamples.removeQuotes(str)
144
+ );
145
+ fp.write(title + ' ' + result2.join(' ') + '\n');
146
+ console.log(title, ...args);
264
147
  }
265
- }
266
148
 
267
- function testBooleanParserSingle(
268
- str: string,
269
- outputFormatter?: (clauses: Clause[]) => string
270
- ): void {
271
- console.log('Input: ', str);
272
- const parser = new BooleanParser(str);
273
- const response = parser.parse();
274
- // console.log('Tokens: ', parser.getTokens());
275
- if (response.clauses && response.clauses.length > 0) {
276
- if (outputFormatter) {
277
- console.log('Output: ', outputFormatter(response.clauses));
278
- } else {
279
- console.log('Output: ', ...response.clauses);
280
- }
281
- }
282
- if (response.errors && response.errors.length > 0) {
283
- console.log('Errors: ', ...response.errors);
149
+ public static writeRaw(fp: fs.WriteStream, ...args: any[]): void {
150
+ fp.write(args.join(' ') + '\n');
151
+ console.log(...args);
284
152
  }
285
- console.log('');
286
- }
287
153
 
288
- function testBooleanParser() {
289
- for (const example of booleanExamples) {
290
- const parser = new BooleanParser(example);
291
- testBooleanParserSingle(example);
154
+ public booleanSample(str: string, fp: fs.WriteStream): void {
155
+ GenerateSamples.writeRaw(fp, 'Input: ', str);
156
+ const parser = new BooleanParser(str);
157
+ const response = parser.parse();
158
+ // GenerateSamples.writeJson(fp, 'Tokens: ', parser.getTokens());
159
+ if (response.clauses && response.clauses.length > 0) {
160
+ GenerateSamples.writeJson(fp, 'Output: ', ...response.clauses);
161
+ }
162
+ if (response.errors && response.errors.length > 0) {
163
+ GenerateSamples.writeJson(fp, 'Errors: ', ...response.errors);
164
+ }
165
+ GenerateSamples.writeRaw(fp, '');
292
166
  }
293
- }
294
167
 
295
- function jsonFormatter(clauses: Clause[]): string {
296
- let str = '';
297
- for (const clause of clauses) {
298
- str += JSON.stringify(clause, null, ' ');
168
+ public dateSample(str: string, fp: fs.WriteStream): void {
169
+ GenerateSamples.writeRaw(fp, 'Input: ', str);
170
+ const parser = new DateParser(str);
171
+ const response = parser.parse();
172
+ // GenerateSamples.writeJson(fp, 'Tokens: ', parser.getTokens());
173
+ if (response.clauses && response.clauses.length > 0) {
174
+ GenerateSamples.writeJson(fp, 'Output: ', ...response.clauses);
175
+ }
176
+ if (response.errors && response.errors.length > 0) {
177
+ GenerateSamples.writeJson(fp, 'Errors: ', ...response.errors);
178
+ }
179
+ GenerateSamples.writeRaw(fp, '');
299
180
  }
300
- return str;
301
- }
302
181
 
303
- function testDateParserSingle(
304
- str: string,
305
- outputFormatter?: (clauses: Clause[]) => string
306
- ): void {
307
- console.log('Input: ', str);
308
- const parser = new DateParser(str);
309
- const response = parser.parse();
310
- // console.log('Tokens: ', parser.getTokens());
311
- if (response.clauses && response.clauses.length > 0) {
312
- if (outputFormatter) {
313
- console.log('Output: ', outputFormatter(response.clauses));
314
- } else {
315
- console.log('Output: ', ...response.clauses);
182
+ public numberSample(str: string, fp: fs.WriteStream): void {
183
+ GenerateSamples.writeRaw(fp, 'Input: ', str);
184
+ const parser = new NumberParser(str);
185
+ const response = parser.parse();
186
+ // GenerateSamples.writeJson(fp, 'Tokens: ', parser.getTokens());
187
+ if (response.clauses && response.clauses.length > 0) {
188
+ GenerateSamples.writeJson(fp, 'Output: ', ...response.clauses);
316
189
  }
190
+ if (response.errors && response.errors.length > 0) {
191
+ GenerateSamples.writeJson(fp, 'Errors: ', ...response.errors);
192
+ }
193
+ GenerateSamples.writeRaw(fp, '');
317
194
  }
318
- if (response.errors && response.errors.length > 0) {
319
- console.log('Errors: ', ...response.errors);
320
- }
321
- console.log('');
322
- }
323
195
 
324
- function testDateParser() {
325
- for (const example of dateExamples) {
326
- const parser = new DateParser(example);
327
- testDateParserSingle(example);
196
+ public stringSample(str: string, fp: fs.WriteStream): void {
197
+ GenerateSamples.writeRaw(fp, 'Input: ', str);
198
+ const parser = new StringParser(str);
199
+ const response = parser.parse();
200
+ // GenerateSamples.writeJson(fp, 'Tokens: ', parser.getTokens());
201
+ if (response.clauses && response.clauses.length > 0) {
202
+ GenerateSamples.writeJson(fp, 'Output: ', ...response.clauses);
203
+ }
204
+ if (response.quotes) {
205
+ GenerateSamples.writeJson(fp, 'Quotes: ', ...response.quotes);
206
+ }
207
+ if (response.errors && response.errors.length > 0) {
208
+ GenerateSamples.writeJson(fp, 'Errors: ', ...response.errors);
209
+ }
210
+ GenerateSamples.writeRaw(fp, '');
328
211
  }
329
- }
330
212
 
331
- function testNumberRoundtrip(str: string): void {
332
- console.log('Input: ' + str);
333
- const response = new NumberParser(str).parse();
334
- // console.log('Clause: ', ...response.clauses, '\n');
335
- if (response.clauses && response.clauses.length > 0) {
336
- const result = new NumberSerializer(response.clauses || []).serialize();
337
- console.log('Output: ' + result);
338
- }
339
- if (response.errors && response.errors.length > 0) {
340
- console.log('Errors: ', ...response.errors);
213
+ public booleanSerialized(str: string, fp: fs.WriteStream): void {
214
+ GenerateSamples.writeRaw(fp, 'Input: ' + str);
215
+ const response = new BooleanParser(str).parse();
216
+ // this.writeJson('Clause: ', ...response.clauses, '\n');
217
+ if (response.clauses && response.clauses.length > 0) {
218
+ const result = new BooleanSerializer(response.clauses || []).serialize();
219
+ GenerateSamples.writeRaw(fp, 'Output: ' + result);
220
+ }
221
+ if (response.errors && response.errors.length > 0) {
222
+ GenerateSamples.writeJson(fp, 'Errors: ', ...response.errors);
223
+ }
224
+ GenerateSamples.writeRaw(fp, '');
341
225
  }
342
- console.log('');
343
- }
344
226
 
345
- function testNumberSerializer(): void {
346
- for (const example of numberExamples) {
347
- testNumberRoundtrip(example);
227
+ public dateSerialized(str: string, fp: fs.WriteStream): void {
228
+ GenerateSamples.writeRaw(fp, 'Input: ' + str);
229
+ const response = new DateParser(str).parse();
230
+ // this.writeJson('Clause: ', ...response.clauses, '\n');
231
+ if (response.clauses && response.clauses.length > 0) {
232
+ const result = new DateSerializer(response.clauses || []).serialize();
233
+ GenerateSamples.writeRaw(fp, 'Output: ' + result);
234
+ }
235
+ if (response.errors && response.errors.length > 0) {
236
+ GenerateSamples.writeJson(fp, 'Errors: ', ...response.errors);
237
+ }
238
+ GenerateSamples.writeRaw(fp, '');
348
239
  }
349
- }
350
240
 
351
- function testStringRoundtrip(str: string): void {
352
- console.log('Input: ' + str);
353
- const response = new StringParser(str).parse();
354
- // console.log('Clause: ', ...response.clauses, '\n');
355
- if (response.clauses && response.clauses.length > 0) {
356
- const result = new StringSerializer(response.clauses || []).serialize();
357
- console.log('Output: ' + result);
358
- }
359
- if (response.errors && response.errors.length > 0) {
360
- console.log('Errors: ', ...response.errors);
241
+ public numberSerialized(str: string, fp: fs.WriteStream): void {
242
+ GenerateSamples.writeRaw(fp, 'Input: ' + str);
243
+ const response = new NumberParser(str).parse();
244
+ // this.writeJson('Clause: ', ...response.clauses, '\n');
245
+ if (response.clauses && response.clauses.length > 0) {
246
+ const result = new NumberSerializer(response.clauses || []).serialize();
247
+ GenerateSamples.writeRaw(fp, 'Output: ' + result);
248
+ }
249
+ if (response.errors && response.errors.length > 0) {
250
+ GenerateSamples.writeJson(fp, 'Errors: ', ...response.errors);
251
+ }
252
+ GenerateSamples.writeRaw(fp, '');
361
253
  }
362
- console.log('');
363
- }
364
254
 
365
- function testStringSerializer(): void {
366
- for (const example of stringExamples) {
367
- testStringRoundtrip(example);
255
+ public stringSerialized(str: string, fp: fs.WriteStream): void {
256
+ GenerateSamples.writeRaw(fp, 'Input: ' + str);
257
+ const response = new StringParser(str).parse();
258
+ // this.writeJson('Clause: ', ...response.clauses, '\n');
259
+ if (response.clauses && response.clauses.length > 0) {
260
+ const result = new StringSerializer(response.clauses || []).serialize();
261
+ GenerateSamples.writeRaw(fp, 'Output: ' + result);
262
+ }
263
+ if (response.errors && response.errors.length > 0) {
264
+ GenerateSamples.writeJson(fp, 'Errors: ', ...response.errors);
265
+ }
266
+ GenerateSamples.writeRaw(fp, '');
368
267
  }
369
- }
370
268
 
371
- function testBooleanRoundtrip(str: string): void {
372
- console.log('Input: ' + str);
373
- const response = new BooleanParser(str).parse();
374
- // console.log('Clause: ', ...response.clauses, '\n');
375
- if (response.clauses && response.clauses.length > 0) {
376
- const result = new BooleanSerializer(response.clauses || []).serialize();
377
- console.log('Output: ' + result);
378
- }
379
- if (response.errors && response.errors.length > 0) {
380
- console.log('Errors: ', ...response.errors);
269
+ public loop(
270
+ title: string,
271
+ examples: string[],
272
+ func: (str: string, fp: fs.WriteStream) => void,
273
+ fp: fs.WriteStream
274
+ ): void {
275
+ GenerateSamples.writeRaw(
276
+ fp,
277
+ '-------------------------------------------------------------------------'
278
+ );
279
+ GenerateSamples.writeRaw(fp, '## ' + title + '\n');
280
+ GenerateSamples.writeRaw(fp, '```code');
281
+ for (const example of examples) {
282
+ func(example, fp);
283
+ }
284
+ GenerateSamples.writeRaw(fp, '```\n');
381
285
  }
382
- console.log('');
383
286
  }
384
287
 
385
- function testBooleanSerializer(): void {
386
- const examples = [[{operator: 'TRUE'}]];
387
- for (const example of booleanExamples) {
388
- testBooleanRoundtrip(example);
389
- }
390
- }
288
+ // Comment or uncomment the following function calls to disable/enable examples.
289
+ function generateSamples() {
290
+ try {
291
+ const gen = new GenerateSamples();
292
+ GenerateSamples.writeRaw(
293
+ gen.samplesFile,
294
+ `
295
+ # Parsers
391
296
 
392
- function testDateRoundtrip(str: string): void {
393
- console.log('Input: ' + str);
394
- const response = new DateParser(str).parse();
395
- // console.log('Clause: ', ...response.clauses, '\n');
396
- if (response.clauses && response.clauses.length > 0) {
397
- const result = new DateSerializer(response.clauses || []).serialize();
398
- console.log('Output: ' + result);
399
- }
400
- if (response.errors && response.errors.length > 0) {
401
- console.log('Errors: ', ...response.errors);
402
- }
403
- console.log('');
404
- }
297
+ Each filter type is handled by a different parser (strings, numbers, dates and times, etc).
298
+ Sample outputs from each parser follow...
299
+ `
300
+ );
405
301
 
406
- function testDateSerializer(): void {
407
- for (const example of dateExamples) {
408
- testDateRoundtrip(example);
409
- }
410
- }
302
+ GenerateSamples.writeRaw(
303
+ gen.serializedFile,
304
+ `
305
+ # Serializers
411
306
 
412
- function printHeader(title: string): void {
413
- console.log(
414
- '\n-------------------------------------------------------------------------'
415
- );
416
- console.log('## ', title, '\n');
417
- }
307
+ Each parser has a complementary serializer that converts the structured clause list back
308
+ to string format. Below are round-trip samples: \`string\` to \`Clause[]\` back to \`string\`.
309
+ Round-trip Examples:
418
310
 
419
- // Comment or uncomment the following function calls to disable/enable examples.
420
- function generateSamples() {
421
- try {
422
- //printHeader('Tokenizer');
423
- //testTokenizerString();
424
- //testTokenizerNumber();
425
- //testTokenizerMatchTypes();
426
- printHeader('Numbers');
427
- testNumberParser();
428
- printHeader('Strings');
429
- testStringParser();
430
- printHeader('Booleans');
431
- testBooleanParser();
432
- printHeader('Dates and Times');
433
- testDateParser();
434
- printHeader('Number Serializer');
435
- testNumberSerializer();
436
- printHeader('String Serializer');
437
- testStringSerializer();
438
- printHeader('Boolean Serializer');
439
- testBooleanSerializer();
440
- printHeader('Date and Time Serializer');
441
- testDateSerializer();
311
+ \`\`\`code
312
+ Input > parse > Clause[] > serialize > Output
313
+ string string
314
+ \`\`\`
315
+ `
316
+ );
317
+ gen.loop('Numbers', numberExamples, gen.numberSample, gen.samplesFile);
318
+ gen.loop('Strings', stringExamples, gen.stringSample, gen.samplesFile);
319
+ gen.loop('Booleans', booleanExamples, gen.booleanSample, gen.samplesFile);
320
+ gen.loop('Dates and Times', dateExamples, gen.dateSample, gen.samplesFile);
321
+ gen.loop(
322
+ 'Number Serializer',
323
+ numberExamples,
324
+ gen.numberSerialized,
325
+ gen.serializedFile
326
+ );
327
+ gen.loop(
328
+ 'String Serializer',
329
+ stringExamples,
330
+ gen.stringSerialized,
331
+ gen.serializedFile
332
+ );
333
+ gen.loop(
334
+ 'Boolean Serializer',
335
+ booleanExamples,
336
+ gen.booleanSerialized,
337
+ gen.serializedFile
338
+ );
339
+ gen.loop(
340
+ 'Date Serializer',
341
+ dateExamples,
342
+ gen.dateSerialized,
343
+ gen.serializedFile
344
+ );
442
345
  } catch (ex: Error | unknown) {
443
346
  if (ex instanceof Error) console.error('Thrown Error: ', ex.message);
444
347
  else {
@@ -98,7 +98,9 @@ export class NumberParser extends BaseParser {
98
98
  outputs.push(clause);
99
99
  } else if (
100
100
  previous !== undefined &&
101
- previous.operator === clause.operator
101
+ previous.operator === clause.operator &&
102
+ 'values' in previous &&
103
+ 'values' in clause
102
104
  ) {
103
105
  previous.values.push(...clause.values);
104
106
  } else {
@@ -204,59 +206,6 @@ export class NumberParser extends BaseParser {
204
206
  return clauses;
205
207
  }
206
208
 
207
- private static getNegatedType(tokenType: NumberOperator): NumberOperator {
208
- switch (tokenType) {
209
- case '<=':
210
- return '>';
211
- case '>=':
212
- return '<';
213
- case '<':
214
- return '>';
215
- case '>':
216
- return '<';
217
- case '=':
218
- return '!=';
219
- case '!=':
220
- return '=';
221
- }
222
- }
223
-
224
- private static getNumberOperator(
225
- tokenType: string
226
- ): NumberOperator | undefined {
227
- switch (tokenType) {
228
- case '<=':
229
- return '<=';
230
- case '>=':
231
- return '>=';
232
- case '<':
233
- return '<';
234
- case '>':
235
- return '>';
236
- case '=':
237
- return '=';
238
- case '!=':
239
- return '!=';
240
- }
241
- return undefined;
242
- }
243
-
244
- private static getNumberRnageOperator(
245
- tokenType: string
246
- ): NumberRangeOperator | undefined {
247
- switch (tokenType) {
248
- case '<=':
249
- return '<=';
250
- case '>=':
251
- return '>=';
252
- case '<':
253
- return '<';
254
- case '>':
255
- return '>';
256
- }
257
- return undefined;
258
- }
259
-
260
209
  private checkNumericExpression(
261
210
  tokenType: NumberOperator,
262
211
  clauses: NumberClause[]
@@ -297,10 +246,12 @@ export class NumberParser extends BaseParser {
297
246
  }
298
247
 
299
248
  private checkNull(clauses: NumberClause[]): boolean {
300
- if (this.getNext().type === 'NULL' || this.getNext().type === 'NOTNULL') {
301
- const tokenType = this.getNext().type === 'NULL' ? '=' : '!=';
302
- const clause: NumberCondition = {operator: tokenType, values: [null]};
303
- clauses.push(clause);
249
+ const type = this.getNext().type;
250
+ if (type === 'NULL') {
251
+ clauses.push({operator: 'NULL'});
252
+ return true;
253
+ } else if (type === 'NOTNULL') {
254
+ clauses.push({operator: 'NOTNULL'});
304
255
  return true;
305
256
  }
306
257
  return false;