sparkql 1.1.17 → 1.2.0

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.
@@ -16,72 +16,86 @@ module Sparkql
16
16
  ##### State transition tables begin ###
17
17
 
18
18
  racc_action_table = [
19
- 35, 14, 15, 43, 44, 34, 45, 46, 47, 14,
20
- 22, 31, 32, 33, 36, 37, 38, 39, 40, 35,
21
- 17, 16, 23, 49, 34, 50, 10, 11, 14, -28,
22
- 31, 32, 33, 36, 37, 38, 39, 40, 35, 56,
23
- 60, 17, 16, 34, 61, 10, 11, 14, 59, 31,
24
- 32, 33, 36, 37, 38, 39, 40, 35, 18, 19,
25
- 35, 64, 34, nil, nil, 34, nil, nil, 31, 32,
26
- 33, 31, 32, 33, 35, 14, nil, 43, 44, 34,
27
- 45, 46, 47, 14, nil, 31, 32, 33, 8, nil,
28
- 9, nil, 10, 11, 14, 8, nil, 9, nil, 10,
29
- 11, 14, 9, nil, 10, 11, 14, 9, nil, 10,
30
- 11, 14, 9, nil, 10, 11, 14 ]
19
+ 36, 14, 72, 44, 45, 35, 46, 47, 48, 14,
20
+ 58, 32, 33, 34, 37, 38, 39, 40, 41, 36,
21
+ 22, 62, 18, 19, 35, 63, 10, 11, 14, 23,
22
+ 32, 33, 34, 37, 38, 39, 40, 41, 36, 17,
23
+ 16, 61, 50, 35, 51, 10, 11, 14, 15, 32,
24
+ 33, 34, 37, 38, 39, 40, 41, 36, 17, 16,
25
+ 75, 57, 35, 66, 76, -35, 14, nil, 32, 33,
26
+ 34, 37, 38, 39, 40, 41, 36, 14, nil, 44,
27
+ 45, 35, 46, 47, 48, 14, nil, 32, 33, 34,
28
+ 37, 38, 39, 40, 41, 36, nil, nil, 36, nil,
29
+ 35, nil, nil, 35, 14, nil, 32, 33, 34, 32,
30
+ 33, 34, 36, nil, 8, nil, 9, 35, 10, 11,
31
+ 14, nil, nil, 32, 33, 34, 8, nil, 9, nil,
32
+ 10, 11, 14, 9, nil, 10, 11, 14, 9, nil,
33
+ 10, 11, 14, 9, nil, 10, 11, 14 ]
31
34
 
32
35
  racc_action_check = [
33
- 18, 19, 1, 19, 19, 18, 19, 19, 19, 18,
34
- 13, 18, 18, 18, 18, 18, 18, 18, 18, 22,
35
- 21, 21, 15, 21, 22, 22, 22, 22, 22, 28,
36
- 22, 22, 22, 22, 22, 22, 22, 22, 61, 29,
37
- 51, 2, 2, 61, 51, 61, 61, 61, 42, 61,
38
- 61, 61, 61, 61, 61, 61, 61, 34, 6, 6,
39
- 35, 57, 34, nil, nil, 35, nil, nil, 34, 34,
40
- 34, 35, 35, 35, 56, 59, nil, 59, 59, 56,
41
- 59, 59, 59, 56, nil, 56, 56, 56, 0, nil,
42
- 0, nil, 0, 0, 0, 9, nil, 9, nil, 9,
43
- 9, 9, 8, nil, 8, 8, 8, 16, nil, 16,
44
- 16, 16, 17, nil, 17, 17, 17 ]
36
+ 76, 61, 59, 61, 61, 76, 61, 61, 61, 76,
37
+ 30, 76, 76, 76, 76, 76, 76, 76, 76, 63,
38
+ 13, 52, 6, 6, 63, 52, 63, 63, 63, 15,
39
+ 63, 63, 63, 63, 63, 63, 63, 63, 22, 21,
40
+ 21, 43, 21, 22, 22, 22, 22, 22, 1, 22,
41
+ 22, 22, 22, 22, 22, 22, 22, 58, 2, 2,
42
+ 67, 29, 58, 58, 67, 28, 58, nil, 58, 58,
43
+ 58, 58, 58, 58, 58, 58, 18, 19, nil, 19,
44
+ 19, 18, 19, 19, 19, 18, nil, 18, 18, 18,
45
+ 18, 18, 18, 18, 18, 57, nil, nil, 36, nil,
46
+ 57, nil, nil, 36, 57, nil, 57, 57, 57, 36,
47
+ 36, 36, 35, nil, 9, nil, 9, 35, 9, 9,
48
+ 9, nil, nil, 35, 35, 35, 0, nil, 0, nil,
49
+ 0, 0, 0, 17, nil, 17, 17, 17, 16, nil,
50
+ 16, 16, 16, 8, nil, 8, 8, 8 ]
45
51
 
46
52
  racc_action_pointer = [
47
- 83, 2, 36, nil, nil, nil, 55, nil, 95, 90,
48
- nil, nil, nil, 3, nil, 22, 100, 105, -2, -10,
49
- nil, 15, 17, nil, nil, nil, nil, nil, 17, 27,
50
- nil, nil, nil, nil, 55, 58, nil, nil, nil, nil,
51
- nil, nil, 36, nil, nil, nil, nil, nil, nil, nil,
52
- nil, 32, nil, nil, nil, nil, 72, 53, nil, 64,
53
- nil, 36, nil, nil, nil, nil, nil ]
53
+ 121, 48, 53, nil, nil, nil, 19, nil, 136, 109,
54
+ nil, nil, nil, 13, nil, 29, 131, 126, 74, 66,
55
+ nil, 34, 36, nil, nil, nil, nil, nil, 53, 49,
56
+ 3, nil, nil, nil, nil, 110, 96, nil, nil, nil,
57
+ nil, nil, nil, 29, nil, nil, nil, nil, nil, nil,
58
+ nil, nil, 13, nil, nil, nil, nil, 93, 55, -6,
59
+ nil, -10, nil, 17, nil, nil, nil, 52, nil, nil,
60
+ nil, nil, nil, nil, nil, nil, -2, nil ]
54
61
 
55
62
  racc_action_default = [
56
- -2, -48, -1, -3, -4, -5, -48, -8, -48, -48,
57
- -13, -14, -15, -48, -21, -48, -48, -48, -48, -48,
58
- -9, -48, -48, 67, -10, -11, -6, -16, -17, -18,
59
- -27, -32, -33, -34, -48, -48, -37, -38, -39, -40,
60
- -41, -7, -48, -42, -43, -44, -45, -46, -47, -12,
61
- -19, -48, -22, -24, -25, -26, -48, -48, -36, -48,
62
- -20, -48, -29, -30, -35, -31, -23 ]
63
+ -2, -55, -1, -3, -4, -5, -55, -8, -55, -55,
64
+ -13, -14, -15, -55, -23, -55, -55, -55, -55, -55,
65
+ -9, -55, -55, 78, -10, -11, -6, -16, -17, -18,
66
+ -55, -34, -39, -40, -41, -55, -55, -44, -45, -46,
67
+ -47, -48, -7, -55, -49, -50, -51, -52, -53, -54,
68
+ -12, -19, -55, -24, -26, -27, -28, -55, -55, -55,
69
+ -43, -55, -20, -55, -36, -37, -21, -55, -29, -31,
70
+ -32, -33, -42, -38, -25, -22, -55, -30 ]
63
71
 
64
72
  racc_goto_table = [
65
- 28, 48, 42, 2, 55, 52, 20, 30, 1, 26,
66
- 41, 27, 21, 29, 24, 25, 51, nil, nil, nil,
67
- nil, nil, nil, 57, 58, nil, nil, nil, nil, nil,
68
- nil, nil, nil, nil, nil, nil, nil, nil, 63, nil,
69
- nil, 48, 65, 55, 66, 62 ]
73
+ 30, 27, 43, 31, 68, 56, 53, 49, 2, 28,
74
+ 20, 52, 67, 29, 42, 26, 1, 21, 24, 25,
75
+ 59, 60, 77, nil, nil, nil, nil, nil, nil, nil,
76
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
77
+ 30, 69, 64, 70, 73, 65, 56, 74, nil, 49,
78
+ nil, nil, nil, nil, nil, nil, nil, nil, 30, 69,
79
+ nil, 70 ]
70
80
 
71
81
  racc_goto_check = [
72
- 10, 10, 17, 2, 6, 15, 3, 16, 1, 7,
73
- 8, 11, 2, 12, 3, 3, 14, nil, nil, nil,
74
- nil, nil, nil, 16, 16, nil, nil, nil, nil, nil,
75
- nil, nil, nil, nil, nil, nil, nil, nil, 10, nil,
76
- nil, 10, 17, 6, 15, 16 ]
82
+ 14, 11, 20, 18, 19, 6, 17, 10, 2, 12,
83
+ 3, 15, 16, 13, 8, 7, 1, 2, 3, 3,
84
+ 18, 18, 19, nil, nil, nil, nil, nil, nil, nil,
85
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
86
+ 14, 11, 18, 18, 20, 10, 6, 17, nil, 10,
87
+ nil, nil, nil, nil, nil, nil, nil, nil, 14, 11,
88
+ nil, 18 ]
77
89
 
78
90
  racc_goto_pointer = [
79
- nil, 8, 3, -2, nil, nil, -18, -9, -9, nil,
80
- -18, -7, -5, nil, -6, -17, -11, -17 ]
91
+ nil, 16, 8, 2, nil, nil, -17, -3, -5, nil,
92
+ -12, -17, -9, -5, -18, -11, -46, -16, -15, -54,
93
+ -17 ]
81
94
 
82
95
  racc_goto_default = [
83
96
  nil, nil, nil, 3, 4, 5, 6, nil, nil, 7,
84
- 12, 53, nil, 13, nil, nil, 54, nil ]
97
+ 12, 54, 71, nil, 13, nil, nil, nil, 55, nil,
98
+ nil ]
85
99
 
86
100
  racc_reduce_table = [
87
101
  0, 0, :racc_error,
@@ -105,37 +119,44 @@ racc_reduce_table = [
105
119
  1, 28, :_reduce_18,
106
120
  3, 31, :_reduce_19,
107
121
  4, 31, :_reduce_20,
108
- 1, 34, :_reduce_none,
122
+ 3, 33, :_reduce_21,
123
+ 4, 33, :_reduce_22,
109
124
  1, 35, :_reduce_none,
110
- 3, 35, :_reduce_23,
111
- 1, 36, :_reduce_none,
112
125
  1, 36, :_reduce_none,
113
- 1, 36, :_reduce_26,
114
- 1, 33, :_reduce_none,
115
- 1, 33, :_reduce_none,
116
- 3, 33, :_reduce_29,
117
- 3, 33, :_reduce_30,
118
- 3, 29, :_reduce_31,
119
- 1, 37, :_reduce_none,
120
- 1, 37, :_reduce_none,
126
+ 3, 36, :_reduce_25,
127
+ 1, 38, :_reduce_none,
128
+ 1, 38, :_reduce_none,
129
+ 1, 38, :_reduce_28,
121
130
  1, 37, :_reduce_none,
122
- 3, 37, :_reduce_35,
123
- 2, 37, :_reduce_36,
131
+ 3, 37, :_reduce_30,
132
+ 1, 40, :_reduce_none,
133
+ 1, 40, :_reduce_none,
134
+ 1, 40, :_reduce_none,
135
+ 1, 34, :_reduce_none,
136
+ 1, 34, :_reduce_none,
137
+ 3, 34, :_reduce_36,
138
+ 3, 34, :_reduce_37,
139
+ 3, 29, :_reduce_38,
140
+ 1, 39, :_reduce_none,
141
+ 1, 39, :_reduce_none,
142
+ 1, 39, :_reduce_none,
143
+ 3, 39, :_reduce_42,
144
+ 2, 39, :_reduce_43,
124
145
  1, 32, :_reduce_none,
125
146
  1, 32, :_reduce_none,
126
147
  1, 32, :_reduce_none,
127
148
  1, 32, :_reduce_none,
128
149
  1, 32, :_reduce_none,
129
- 1, 38, :_reduce_none,
130
- 1, 38, :_reduce_none,
131
- 1, 38, :_reduce_none,
132
- 1, 38, :_reduce_none,
133
- 1, 38, :_reduce_none,
134
- 1, 38, :_reduce_none ]
150
+ 1, 41, :_reduce_none,
151
+ 1, 41, :_reduce_none,
152
+ 1, 41, :_reduce_none,
153
+ 1, 41, :_reduce_none,
154
+ 1, 41, :_reduce_none,
155
+ 1, 41, :_reduce_none ]
135
156
 
136
- racc_reduce_n = 48
157
+ racc_reduce_n = 55
137
158
 
138
- racc_shift_n = 67
159
+ racc_shift_n = 78
139
160
 
140
161
  racc_token_table = {
141
162
  false => 0,
@@ -214,11 +235,14 @@ Racc_token_to_s_table = [
214
235
  "group",
215
236
  "function",
216
237
  "literal",
238
+ "literal_function",
217
239
  "literal_list",
218
240
  "function_name",
219
241
  "function_args",
242
+ "literal_function_args",
220
243
  "function_arg",
221
244
  "literals",
245
+ "literal_function_arg",
222
246
  "rangeable" ]
223
247
 
224
248
  Racc_debug_parser = false
@@ -297,42 +321,42 @@ def _reduce_20(val, _values, result)
297
321
  result
298
322
  end
299
323
 
300
- # reduce 21 omitted
301
-
302
- # reduce 22 omitted
324
+ def _reduce_21(val, _values, result)
325
+ result = tokenize_function(val[0], [])
326
+ result
327
+ end
303
328
 
304
- def _reduce_23(val, _values, result)
305
- result = tokenize_function_args(val[0], val[2])
329
+ def _reduce_22(val, _values, result)
330
+ result = tokenize_function(val[0], val[2])
306
331
  result
307
332
  end
308
333
 
309
- # reduce 24 omitted
334
+ # reduce 23 omitted
310
335
 
311
- # reduce 25 omitted
336
+ # reduce 24 omitted
312
337
 
313
- def _reduce_26(val, _values, result)
314
- result = tokenize_field_arg(val[0])
338
+ def _reduce_25(val, _values, result)
339
+ result = tokenize_function_args(val[0], val[2])
315
340
  result
316
341
  end
317
342
 
318
- # reduce 27 omitted
343
+ # reduce 26 omitted
319
344
 
320
- # reduce 28 omitted
345
+ # reduce 27 omitted
321
346
 
322
- def _reduce_29(val, _values, result)
323
- result = tokenize_multiple(val[0], val[2])
347
+ def _reduce_28(val, _values, result)
348
+ result = tokenize_field_arg(val[0])
324
349
  result
325
350
  end
326
351
 
352
+ # reduce 29 omitted
353
+
327
354
  def _reduce_30(val, _values, result)
328
- result = tokenize_multiple(val[0], val[2])
355
+ result = tokenize_function_args(val[0], val[2])
329
356
  result
330
357
  end
331
358
 
332
- def _reduce_31(val, _values, result)
333
- result = tokenize_multiple(val[0], val[2])
334
- result
335
- end
359
+ # reduce 31 omitted
336
360
 
337
361
  # reduce 32 omitted
338
362
 
@@ -340,19 +364,22 @@ end
340
364
 
341
365
  # reduce 34 omitted
342
366
 
343
- def _reduce_35(val, _values, result)
344
- result = val[1]
345
- result
346
- end
367
+ # reduce 35 omitted
347
368
 
348
369
  def _reduce_36(val, _values, result)
349
- result = tokenize_literal_negation(val[1])
370
+ result = tokenize_multiple(val[0], val[2])
350
371
  result
351
372
  end
352
373
 
353
- # reduce 37 omitted
374
+ def _reduce_37(val, _values, result)
375
+ result = tokenize_multiple(val[0], val[2])
376
+ result
377
+ end
354
378
 
355
- # reduce 38 omitted
379
+ def _reduce_38(val, _values, result)
380
+ result = tokenize_multiple(val[0], val[2])
381
+ result
382
+ end
356
383
 
357
384
  # reduce 39 omitted
358
385
 
@@ -360,9 +387,15 @@ end
360
387
 
361
388
  # reduce 41 omitted
362
389
 
363
- # reduce 42 omitted
390
+ def _reduce_42(val, _values, result)
391
+ result = val[1]
392
+ result
393
+ end
364
394
 
365
- # reduce 43 omitted
395
+ def _reduce_43(val, _values, result)
396
+ result = tokenize_literal_negation(val[1])
397
+ result
398
+ end
366
399
 
367
400
  # reduce 44 omitted
368
401
 
@@ -372,6 +405,20 @@ end
372
405
 
373
406
  # reduce 47 omitted
374
407
 
408
+ # reduce 48 omitted
409
+
410
+ # reduce 49 omitted
411
+
412
+ # reduce 50 omitted
413
+
414
+ # reduce 51 omitted
415
+
416
+ # reduce 52 omitted
417
+
418
+ # reduce 53 omitted
419
+
420
+ # reduce 54 omitted
421
+
375
422
  def _reduce_none(val, _values, result)
376
423
  val[0]
377
424
  end
data/lib/sparkql/parser.y CHANGED
@@ -102,7 +102,7 @@ rule
102
102
  # on filtering values
103
103
  condition
104
104
  : literal
105
- | function
105
+ | literal_function
106
106
  | literal_list { result = tokenize_list(val[0]) }
107
107
  ;
108
108
 
@@ -115,6 +115,11 @@ rule
115
115
  : function_name LPAREN RPAREN { result = tokenize_function(val[0], []) }
116
116
  | function_name LPAREN function_args RPAREN { result = tokenize_function(val[0], val[2]) }
117
117
  ;
118
+
119
+ literal_function
120
+ : function_name LPAREN RPAREN { result = tokenize_function(val[0], []) }
121
+ | function_name LPAREN literal_function_args RPAREN { result = tokenize_function(val[0], val[2]) }
122
+ ;
118
123
 
119
124
  function_name
120
125
  : KEYWORD
@@ -126,20 +131,31 @@ rule
126
131
  function_args
127
132
  : function_arg
128
133
  | function_args COMMA function_arg { result = tokenize_function_args(val[0], val[2]) }
129
- ;
130
-
134
+ ;
135
+
131
136
  function_arg
132
137
  : literal
133
138
  | literals
134
139
  | field { result = tokenize_field_arg(val[0]) }
135
140
  ;
136
-
141
+
142
+ literal_function_args
143
+ : literal_function_arg
144
+ | literal_function_args COMMA literal_function_arg { result = tokenize_function_args(val[0], val[2]) }
145
+ ;
146
+
147
+ literal_function_arg
148
+ : literal
149
+ | literals
150
+ | literal_function
151
+ ;
152
+
137
153
  ##### Literal List
138
154
  #
139
155
  # A comma delimited list of functions and values.
140
156
  literal_list
141
157
  : literals
142
- | function
158
+ | literal_function
143
159
  | literal_list COMMA literals { result = tokenize_multiple(val[0], val[2]) }
144
160
  | literal_list COMMA function { result = tokenize_multiple(val[0], val[2]) }
145
161
  ;
@@ -4,61 +4,51 @@ module Sparkql::ParserCompatibility
4
4
  MAXIMUM_MULTIPLE_VALUES = 200
5
5
  MAXIMUM_EXPRESSIONS = 75
6
6
  MAXIMUM_LEVEL_DEPTH = 2
7
+ MAXIMUM_FUNCTION_DEPTH = 5
7
8
 
8
- # TODO I Really don't think this is required anymore
9
9
  # Ordered by precedence.
10
10
  FILTER_VALUES = [
11
11
  {
12
12
  :type => :datetime,
13
- :regex => /^[0-9]{4}\-[0-9]{2}\-[0-9]{2}T[0-9]{2}\:[0-9]{2}\:[0-9]{2}\.[0-9]{6}$/,
14
13
  :operators => Sparkql::Token::OPERATORS + [Sparkql::Token::RANGE_OPERATOR]
15
14
  },
16
15
  {
17
16
  :type => :date,
18
- :regex => /^[0-9]{4}\-[0-9]{2}\-[0-9]{2}$/,
19
17
  :operators => Sparkql::Token::OPERATORS + [Sparkql::Token::RANGE_OPERATOR]
20
18
  },
21
19
  {
22
20
  :type => :time,
23
- :regex => /^[0-9]{2}\:[0-9]{2}(\:[0-9]{2})?(\.[0-9]{6)$/,
24
21
  :operators => Sparkql::Token::OPERATORS + [Sparkql::Token::RANGE_OPERATOR]
25
22
  },
26
23
  {
27
24
  :type => :character,
28
- :regex => /^'([^'\\]*(\\.[^'\\]*)*)'$/, # Strings must be single quoted. Any inside single quotes must be escaped.
29
25
  :multiple => /^'([^'\\]*(\\.[^'\\]*)*)'/,
30
26
  :operators => Sparkql::Token::EQUALITY_OPERATORS
31
27
  },
32
28
  {
33
29
  :type => :integer,
34
- :regex => /^\-?[0-9]+$/,
35
30
  :multiple => /^\-?[0-9]+/,
36
31
  :operators => Sparkql::Token::OPERATORS + [Sparkql::Token::RANGE_OPERATOR]
37
32
  },
38
33
  {
39
34
  :type => :decimal,
40
- :regex => /^\-?[0-9]+\.[0-9]+$/,
41
35
  :multiple => /^\-?[0-9]+\.[0-9]+/,
42
36
  :operators => Sparkql::Token::OPERATORS + [Sparkql::Token::RANGE_OPERATOR]
43
37
  },
44
38
  {
45
39
  :type => :shape,
46
- # This type is not parseable, so no regex
47
40
  :operators => Sparkql::Token::EQUALITY_OPERATORS
48
41
  },
49
42
  {
50
43
  :type => :boolean,
51
- :regex => /^true|false$/,
52
44
  :operators => Sparkql::Token::EQUALITY_OPERATORS
53
45
  },
54
46
  {
55
47
  :type => :null,
56
- :regex => /^NULL|Null|null$/,
57
48
  :operators => Sparkql::Token::EQUALITY_OPERATORS
58
49
  },
59
50
  {
60
51
  :type => :function,
61
- # This type is not parseable, so no regex
62
52
  :operators => Sparkql::Token::OPERATORS + [Sparkql::Token::RANGE_OPERATOR]
63
53
  },
64
54
  ]
@@ -206,6 +196,10 @@ module Sparkql::ParserCompatibility
206
196
  MAXIMUM_MULTIPLE_VALUES
207
197
  end
208
198
 
199
+ def max_function_depth
200
+ MAXIMUM_FUNCTION_DEPTH
201
+ end
202
+
209
203
  private
210
204
 
211
205
  def tokenizer_error( error_hash )
@@ -224,11 +218,11 @@ module Sparkql::ParserCompatibility
224
218
  (supports_nulls && expression[:type] == :null)
225
219
  return true
226
220
  # If the field will be passed into a function,
227
- # check the type of the return value (:field_function_type),
221
+ # check the type of the return value of the function
228
222
  # and coerce if necessary.
229
- elsif expression[:field_function_type] &&
230
- expression[:type] == :integer &&
231
- expression[:field_function_type] == :decimal
223
+ elsif expression[:field_manipulations] &&
224
+ expression[:type] == :integer &&
225
+ expression[:field_manipulations][:return_type] == :decimal
232
226
  expression[:type] = :decimal
233
227
  expression[:cast] = :integer
234
228
  return true
@@ -264,9 +258,9 @@ module Sparkql::ParserCompatibility
264
258
  # the function matches what is expected, and that the function supports the
265
259
  # field type as the first argument.
266
260
  def check_function_type?(expression, expected)
267
- return false unless expression[:field_function_type] == expression[:type]
261
+ return false unless expression.key?(:field_manipulations) && expression[:field_manipulations][:return_type] == expression[:type]
268
262
  # Lookup the function arguments
269
- function = Sparkql::FunctionResolver::SUPPORTED_FUNCTIONS[expression[:field_function].to_sym]
263
+ function = Sparkql::FunctionResolver::SUPPORTED_FUNCTIONS[expression[:field_manipulations][:function_name].to_sym]
270
264
  return false if function.nil?
271
265
 
272
266
  Array(function[:args].first).include?(expected)
@@ -24,35 +24,37 @@ module Sparkql::ParserTools
24
24
 
25
25
  def tokenize_expression(field, op, val)
26
26
  operator = get_operator(val,op) unless val.nil?
27
- field_args = {}
28
- # Function support for fields is stapled in here. The function information
29
- # is remapped to the expression
27
+
28
+ field_manipulations = nil
30
29
  if field.is_a?(Hash) && field[:type] == :function
31
- function = Sparkql::FunctionResolver::SUPPORTED_FUNCTIONS[field[:value].to_sym]
32
- if !function.nil?
33
- field_args[:field_function] = field[:value]
34
- field_args[:args] = field[:args]
35
-
36
- if field_args[:field_function] == 'cast'
37
- field_args[:field_function_type] = field[:args].last.to_sym
38
- else
39
- field_args[:field_function_type] = function[:return_type]
40
- end
41
- else
42
- tokenizer_error(:token => field[:value],
30
+ function = Sparkql::FunctionResolver::SUPPORTED_FUNCTIONS[field[:function_name].to_sym]
31
+ if function.nil?
32
+ tokenizer_error(:token => field[:function_name],
43
33
  :message => "Unsupported function type", :status => :fatal )
44
34
  end
45
- field = field[:args].first
35
+ field_manipulations = field
36
+ field = field[:field]
46
37
  end
47
- custom_field = !field.nil? && field.start_with?('"')
38
+
39
+ custom_field = !field.nil? && field.is_a?(String) && field.start_with?('"')
40
+
48
41
  block_group = (@lexer.level == 0) ? 0 : @lexer.block_group_identifier
49
42
  expression = {:field => field, :operator => operator, :conjunction => 'And',
50
43
  :conjunction_level => 0, :level => @lexer.level,
51
- :block_group => block_group, :custom_field => custom_field}.
52
- merge!(field_args)
44
+ :block_group => block_group, :custom_field => custom_field}
45
+
46
+ if !field_manipulations.nil?
47
+ # Keeping field_function and field_function_type for backward compatibility with datacon
48
+ expression.merge!(field_manipulations: field_manipulations,
49
+ field_function: field_manipulations[:function_name],
50
+ field_function_type: field_manipulations[:return_type],
51
+ args: field_manipulations[:function_parameters])
52
+ end
53
+
53
54
  expression = val.merge(expression) unless val.nil?
54
55
  expression[:condition] ||= expression[:value]
55
56
  validate_level_depth expression
57
+ validate_field_function_depth(expression[:field_manipulations])
56
58
  if operator.nil?
57
59
  tokenizer_error(:token => op, :expression => expression,
58
60
  :message => "Operator not supported for this type and value string", :status => :fatal )
@@ -145,10 +147,14 @@ module Sparkql::ParserTools
145
147
  end
146
148
 
147
149
  def tokenize_field_arg(field)
148
- {
149
- :type => :field,
150
- :value => field,
151
- }
150
+ if field.is_a?(Hash) && field[:type] == :function
151
+ field
152
+ else
153
+ {
154
+ :type => :field,
155
+ :value => field,
156
+ }
157
+ end
152
158
  end
153
159
 
154
160
  def tokenize_function(name, f_args)
@@ -180,7 +186,6 @@ module Sparkql::ParserTools
180
186
  def on_error(error_token_id, error_value, value_stack)
181
187
  token_name = token_to_str(error_token_id)
182
188
  token_name.downcase!
183
- token = error_value.to_s.inspect
184
189
  tokenizer_error(:token => @lexer.current_token_value,
185
190
  :message => "Error parsing token #{token_name}",
186
191
  :status => :fatal,
@@ -194,7 +199,15 @@ module Sparkql::ParserTools
194
199
  :status => :fatal, :syntax => false, :constraint => true )
195
200
  end
196
201
  end
197
-
202
+
203
+ def validate_field_function_depth(expression)
204
+ if nested_function_depth(expression) > max_function_depth
205
+ compile_error(:token => "(", :expression => expression,
206
+ :message => "You have exceeded the maximum function nesting level. Please nest no more than #{max_function_depth} levels deep.",
207
+ :status => :fatal, :syntax => false, :constraint => true )
208
+ end
209
+ end
210
+
198
211
  def validate_expressions results
199
212
  if results.size > max_expressions
200
213
  compile_error(:token => results[max_expressions][:field], :expression => results[max_expressions],
@@ -237,4 +250,26 @@ module Sparkql::ParserTools
237
250
  end
238
251
  end
239
252
 
253
+ def nested_function_depth(expression)
254
+ return 0 unless expression && expression[:type] == :function
255
+
256
+ height = 0
257
+ queue = []
258
+ queue.push(expression)
259
+
260
+ while true
261
+ count = queue.size
262
+ return height if count == 0
263
+
264
+ height += 1
265
+
266
+ while count > 0
267
+ node = queue.shift
268
+ node[:args].each do |child|
269
+ queue.push(child) if child[:type] == :function
270
+ end
271
+ count -= 1
272
+ end
273
+ end
274
+ end
240
275
  end