norikra 0.0.15-java → 0.0.16-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -193,15 +193,19 @@ module Norikra
193
193
 
194
194
  def type_convert(event)
195
195
  event = (event.respond_to?(:getUnderlying) ? event.getUnderlying : event).to_hash
196
+ converted = {}
196
197
  event.keys.each do |key|
197
198
  trace "event content key:#{key}, value:#{event[key]}, value class:#{event[key].class}"
199
+ unescaped_key = Norikra::Field.unescape_name(key)
198
200
  if event[key].respond_to?(:to_hash)
199
- event[key] = event[key].to_hash
201
+ converted[unescaped_key] = event[key].to_hash
200
202
  elsif event[key].respond_to?(:to_a)
201
- event[key] = event[key].to_a
203
+ converted[unescaped_key] = event[key].to_a
204
+ else
205
+ converted[unescaped_key] = event[key]
202
206
  end
203
207
  end
204
- event
208
+ converted
205
209
  end
206
210
 
207
211
  def update(new_events, old_events)
data/lib/norikra/field.rb CHANGED
@@ -76,6 +76,14 @@ module Norikra
76
76
  parts.join('$')
77
77
  end
78
78
 
79
+ def self.unescape_name(name)
80
+ if name.index('$')
81
+ name.split(/(?<!\$)\$/).join('.')
82
+ else
83
+ name
84
+ end
85
+ end
86
+
79
87
  def self.regulate_key_chain(keys)
80
88
  keys.map{|key|
81
89
  case
@@ -88,6 +88,8 @@ module Norikra
88
88
  case tree.text
89
89
  when 'EVENT_PROP_EXPR'
90
90
  ASTEventPropNode.new(tree.text, children)
91
+ when 'SELECTION_ELEMENT_EXPR'
92
+ ASTSelectionElementNode.new(tree.text, children)
91
93
  when 'LIB_FUNCTION'
92
94
  ASTLibFunctionNode.new(tree.text, children)
93
95
  when 'STREAM_EXPR'
@@ -169,6 +171,18 @@ module Norikra
169
171
  end
170
172
  end
171
173
 
174
+ class ASTSelectionElementNode < ASTNode # SELECTION_ELEMENT_EXPR
175
+ # "count(*) AS cnt" => ["SELECTION_ELEMENT_EXPR", "count", "cnt"]
176
+ # "n.s as s" => ["SELECTION_ELEMENT_EXPR", ["EVENT_PROP_EXPR", ["EVENT_PROP_SIMPLE", "n"], ["EVENT_PROP_SIMPLE", "s"]], "s"]
177
+ def nodetype?(*sym)
178
+ sym.include?(:selection)
179
+ end
180
+
181
+ def alias
182
+ @children.size == 2 ? @children[1].name : nil
183
+ end
184
+ end
185
+
172
186
  class ASTLibFunctionNode < ASTNode # LIB_FUNCTION
173
187
  # "now()" => ["LIB_FUNCTION", "now", "("]
174
188
  # "hoge.length()" => ["LIB_FUNCTION", "hoge", "length", "("]
data/lib/norikra/query.rb CHANGED
@@ -80,9 +80,14 @@ module Norikra
80
80
  field_bag.push(subquery.explore(fields.keys, alias_map))
81
81
  end
82
82
 
83
+ # names of 'AS'
84
+ field_aliases = self.ast.listup(:selection).map(&:alias).compact
85
+
83
86
  known_targets_aliases = fields.keys + alias_map.keys
84
87
  self.ast.fields(default_target, known_targets_aliases).each do |field_def|
85
88
  f = field_def[:f]
89
+ next if field_aliases.include?(f)
90
+
86
91
  all.push(f)
87
92
 
88
93
  if field_def[:t]
@@ -249,12 +254,12 @@ module Norikra
249
254
  # :getFireAndForgetClause,
250
255
  # :getForClause,
251
256
  # (*) :getFromClause,
252
- # :getGroupByClause,
257
+ # (*) :getGroupByClause,
253
258
  # :getHavingClause,
254
259
  # :getInsertInto,
255
260
  # :getMatchRecognizeClause,
256
261
  # :getOnExpr,
257
- # :getOrderByClause,
262
+ # (*) :getOrderByClause,
258
263
  # :getOutputLimitClause,
259
264
  # :getRowLimitClause,
260
265
  # :getScriptExpressions,
@@ -265,7 +270,7 @@ module Norikra
265
270
 
266
271
  def self.traverse_fields(rewriter, recaller, statement_model)
267
272
  #NOTICE: SQLStream is not supported yet.
268
- #TODO: other clauses with fields, especially: OrderBy, Having, GroupBy, For
273
+ #TODO: other clauses with fields, especially: Having, For
269
274
 
270
275
  dig = lambda {|node|
271
276
  rewriter.call(node)
@@ -326,6 +331,20 @@ module Norikra
326
331
  end
327
332
  end
328
333
 
334
+ if statement_model.getGroupByClause
335
+ statement_model.getGroupByClause.getGroupByExpressions.each do |child|
336
+ dig.call(child)
337
+ end
338
+ end
339
+
340
+ if statement_model.getOrderByClause
341
+ statement_model.getOrderByClause.getOrderByExpressions.each do |item|
342
+ if item.respond_to?(:getExpression)
343
+ dig.call(item.getExpression)
344
+ end
345
+ end
346
+ end
347
+
329
348
  statement_model
330
349
  end
331
350
  end
@@ -1,3 +1,3 @@
1
1
  module Norikra
2
- VERSION = "0.0.15"
2
+ VERSION = "0.0.16"
3
3
  end
data/spec/field_spec.rb CHANGED
@@ -32,6 +32,14 @@ describe Norikra::Field do
32
32
  end
33
33
  end
34
34
 
35
+ describe '.unescape_name' do
36
+ it 're_make dotted pattern fieldname for container access chain' do
37
+ expect(Norikra::Field.unescape_name("part1$part2")).to eql('part1.part2')
38
+ expect(Norikra::Field.unescape_name("part1$$0")).to eql('part1.$0')
39
+ expect(Norikra::Field.unescape_name("part1$$$0")).to eql('part1.$$0')
40
+ end
41
+ end
42
+
35
43
  describe '.regulate_key_chain' do
36
44
  it 'escape String chain items and returns by array which started with numeric, with "$$", and joins keys with separator "$"' do
37
45
  expect(Norikra::Field.regulate_key_chain(["part1", "part2"])).to eql(['part1','part2'])
data/spec/query_spec.rb CHANGED
@@ -24,6 +24,23 @@ describe Norikra::Query do
24
24
  end
25
25
  end
26
26
 
27
+ context 'with order by' do
28
+ it 'returns query instances, collectly parsed, without AS_names for fields' do
29
+ expression = 'SELECT name.string, count(*) AS cnt FROM TestTable.win:time_batch(10 sec) WHERE path="/" AND size > 100 and param.length() > 0 GROUP BY name.string ORDER BY cnt'
30
+ q = Norikra::Query.new(
31
+ :name => 'TestTable query1', :expression => expression
32
+ )
33
+ expect(q.name).to eql('TestTable query1')
34
+ expect(q.group).to be_nil
35
+ expect(q.expression).to eql(expression)
36
+ expect(q.targets).to eql(['TestTable'])
37
+
38
+ expect(q.fields).to eql(['name.string', 'param', 'path', 'size'].sort)
39
+ expect(q.fields('TestTable')).to eql(['name.string', 'param','path','size'].sort)
40
+ expect(q.fields(nil)).to eql([])
41
+ end
42
+ end
43
+
27
44
  context 'with query including Static lib call' do
28
45
  it 'returns query instances collectly parsed' do
29
46
  expression = 'SELECT count(*) AS cnt FROM TestTable.win:time_batch(10 sec) AS source WHERE source.path="/" AND Math.abs(-1 * source.size) > 3'
@@ -340,6 +357,18 @@ describe Norikra::Query do
340
357
  model = administrator.compileEPL(e10)
341
358
  mapping = {'StreamA' => 'S1', 'StreamB' => 'S2'}
342
359
  expect(Norikra::Query.rewrite_query(model, mapping).toEPL).to eql(x10)
360
+
361
+ e11 = 'select campaign.id as campaign_id, member.region as region, member.lang as lang, count(*) as click, count(distinct member.id) as uu from applog_linereward.win:time_batch(1 minutes) where type = "click" group by campaign.id, member.region, member.lang'
362
+ x11 = 'select campaign$id as campaign_id, member$region as region, member$lang as lang, count(*) as click, count(distinct member$id) as uu from A1.win:time_batch(1 minutes) where type = "click" group by campaign$id, member$region, member$lang'
363
+ model = administrator.compileEPL(e11)
364
+ mapping = {'applog_linereward' => 'A1'}
365
+ expect(Norikra::Query.rewrite_query(model, mapping).toEPL).to eql(x11)
366
+
367
+ e11 = 'select campaign.id, member.region as region, member.lang as lang, count(*) as click, count(distinct member.id) as uu from applog_linereward.win:time_batch(1 minutes) where type = "click" group by campaign.id, member.region, member.lang order by campaign.id'
368
+ x11 = 'select campaign$id, member$region as region, member$lang as lang, count(*) as click, count(distinct member$id) as uu from A1.win:time_batch(1 minutes) where type = "click" group by campaign$id, member$region, member$lang order by campaign$id'
369
+ model = administrator.compileEPL(e11)
370
+ mapping = {'applog_linereward' => 'A1'}
371
+ expect(Norikra::Query.rewrite_query(model, mapping).toEPL).to eql(x11)
343
372
  end
344
373
  end
345
374
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: norikra
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.15
5
+ version: 0.0.16
6
6
  platform: java
7
7
  authors:
8
8
  - TAGOMORI Satoshi