Packages
dqe
0.3.2
0.4.15
0.4.14
0.4.13
0.4.12
0.4.11
0.4.10
0.4.9
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.25
0.3.24
0.3.23
0.3.22
0.3.21
0.3.20
0.3.19
0.3.18
0.3.17
0.3.16
0.3.15
0.3.14
0.3.13
0.3.12
0.3.11
0.3.10
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.2.2
0.2.1
0.2.0
0.1.36
0.1.35
0.1.34
0.1.33
0.1.22
0.1.21
0.1.20
0.1.10
0.1.9
DalmatinerDB query engine
Current section
Files
Jump to
Current section
Files
src/dql_parser.yrl
%% -*- erlang -*-
Nonterminals
funs fun selector select timeframe aliases alias int_or_time mb fune tag pit
glob_metric part_or_name calculatable fun_arg fun_args gmb bucket
mfrom var metric where where_part as_part as_clause perhaps_shifted
math math1 math2 number number2 number3.
%% hist calculatables.
Terminals '(' ')' ',' '.' '*' '/' '=' ':' '+' '-'
part integer kw_bucket kw_select kw_last kw_as kw_from date
kw_between kw_and kw_or kw_ago kw_now time float name
kw_after kw_before kw_for kw_where kw_alias pvar dvar kw_shift
kw_by kw_not op_ne.
%% caggr aggr derivate float name
%% kw_after kw_before kw_for histogram percentile avg hfun mm kw_where
%% confidence.
%%%===================================================================
%%% Root statement
%%%===================================================================
Rootsymbol select.
select -> kw_select funs timeframe : {select, '$2', [], '$3'}.
select -> kw_select funs kw_alias aliases timeframe : {select, '$2', '$4', '$5'}.
%%%===================================================================
%%% SELECT part
%%%===================================================================
%% List of functions in the select part of the statement
funs -> perhaps_shifted : ['$1'].
funs -> perhaps_shifted ',' funs : ['$1'] ++ '$3'.
perhaps_shifted -> fune kw_shift kw_by int_or_time : #{op => timeshift,
args => ['$4', '$1']}.
perhaps_shifted -> fune : '$1'.
%% Element in the function list, either a calculatable or a calculatable
%% with a name
fune -> math kw_as as_clause : named('$3', '$1').
fune -> math : '$1'.
as_part -> part_or_name : '$1'.
as_part -> dvar ':' part_or_name : {dvar, {unwrap('$1'), '$3'}}.
as_part -> dvar : {dvar, {<<>>, unwrap('$1')}}.
as_part -> pvar : '$1'.
as_clause -> as_part : ['$1'].
as_clause -> as_part '.' as_clause : ['$1'] ++ '$3'.
math -> math1 : '$1'.
math1 -> math1 '-' math1: #{op => fcall,
args => #{name => <<"diff">>,
inputs => ['$1', '$3']}}.
math1 -> math1 '+' math1 : #{op => fcall,
args => #{name => <<"sum">>,
inputs => ['$1', '$3']}}.
math1 -> math1 '-' number: #{op => fcall,
args => #{name => <<"sub">>,
inputs => ['$1', '$3']}}.
math1 -> math1 '+' number: #{op => fcall,
args => #{name => <<"add">>,
inputs => ['$1', '$3']}}.
math1 -> math2 : '$1'.
math2 -> math2 '*' math2 : #{op => fcall,
args => #{name => <<"product">>,
inputs => ['$1', '$3']}}.
math2 -> math2 '/' math2 : #{op => fcall,
args => #{name => <<"quotient">>,
inputs => ['$1', '$3']}}.
%% math2 -> math2 '*' number : #{op => fcall,
%% args => #{name => <<"multiply">>,
%% inputs => ['$1', '$3']}}.
%% math2 -> math2 '/' number : #{op => fcall,
%% args => #{name => <<"divide">>,
%% inputs => ['$1', '$3']}}.
math2 -> '(' math1 ')' : '$2'.
math2 -> calculatable : '$1'.
%% Something that can be calculated:
%% * a function that can be resolved
calculatable -> fun : '$1'.
%% * a variable that can be looked up
calculatable -> var : '$1'.
%% * a selector that can be retrived
calculatable -> selector : '$1'.
%% * a mathematical expression
%% calculatables -> calculatable : ['$1'].
%% calculatables -> calculatable ',' calculatables : ['$1'] ++ '$3'.
%% hist -> histogram '(' integer ',' integer ',' calculatable ',' int_or_time ')'
%% : {histogram, unwrap('$3'), unwrap('$5'), '$7', '$9'}.
fun_arg -> int_or_time : '$1'.
fun_arg -> math : '$1'.
fun_arg -> float : '$1'.
number -> number '+' number: '$1' + '$3'.
number -> number '-' number: '$1' - '$3'.
number -> number2 : '$1'.
number2 -> number2 '*' number2: '$1' * '$3'.
number2 -> number2 '/' number2: '$1' / '$3'.
number2 -> number3 : '$1'.
number3 -> integer : unwrap('$1').
number3 -> float : unwrap('$1').
number3 -> '(' number ')' : '$2'.
fun_args -> fun_arg : ['$1'].
fun_args -> fun_arg ',' fun_args : ['$1'] ++ '$3'.
fun -> part_or_name '(' fun_args ')' : #{op => fcall,
args => #{name => '$1',
inputs => '$3'}}.
%% %% Histogram based aggregation functiosn
%% fun -> mm '(' hist ')' : {hfun, unwrap('$1'), '$3'}.
%% fun -> hfun '(' hist ')' : {hfun, unwrap('$1'), '$3'}.
%% fun -> avg '(' hist ')' : {hfun, avg, '$3'}.
%% fun -> percentile '(' hist ',' float ')' : {hfun, percentile, '$3', unwrap('$5')}.
%% %% A aggregation function
%% fun -> derivate '(' calculatable ')' : {aggr, derivate, '$3'}.
%% fun -> confidence '(' calculatable ')' : {aggr, confidence, '$3'}.
%% fun -> mm '(' calculatable ',' int_or_time ')' : {f, unwrap('$1'), ['$3', '$5']}.
%% fun -> aggr '(' calculatable ',' int_or_time ')' : {f, unwrap('$1'), ['$3', '$5']}.
%% fun -> avg '(' calculatables ')' : {combine, unwrap('$1'), '$3'}.
%% fun -> avg '(' calculatable ',' int_or_time ')' : {aggr, unwrap('$1'), '$3', '$5'}.
%% fun -> caggr '(' calculatables ')' : {combine, unwrap('$1'), '$3'}.
%% fun -> caggr '(' calculatable ',' int_or_time ')' : {aggr, unwrap('$1'), '$3', '$5'}.
%% fun -> math '(' calculatable ',' integer ')' : {math, unwrap('$1'), '$3', unwrap('$5')}.
%% A variable.
var -> part_or_name : #{op => var, args => ['$1']}.
%% A selector, either a combination of <metric> BUCKET <bucket> or a mget aggregate.
selector -> mb : #{
op => get,
args => '$1',
signature => [integer, integer, integer, metric, bucket],
return => metric
}.
selector -> gmb : #{
op => sget,
args => '$1',
signature => [integer, integer, integer, glob, bucket],
return => metric
}.
selector -> mfrom : #{
op => lookup,
args => '$1',
return => metric
}.
%% A bucket and metric combination used as a solution
mb -> metric kw_bucket part_or_name : ['$3', '$1'].
gmb -> glob_metric kw_bucket bucket : ['$3', '$1'].
mfrom -> metric kw_from bucket : ['$3', '$1'].
mfrom -> metric kw_from bucket kw_where where : ['$3', '$1', '$5'].
tag -> part_or_name : {tag, <<>>, '$1'}.
tag -> part_or_name ':' part_or_name : {tag, '$1', '$3'}.
where_part -> tag '=' part_or_name : {'=', '$1', '$3'}.
where_part -> tag op_ne part_or_name : {'!=', '$1', '$3'}.
where_part -> tag kw_not part_or_name : {'!=', '$1', '$3'}.
where_part -> tag : {'=', '$1', <<>>}.
where_part -> '(' where ')' : '$2'.
where -> where_part : '$1'.
where -> where kw_and where_part : {'and', '$1', '$3'}.
where -> where kw_or where_part : {'or', '$1', '$3'}.
%%%===================================================================
%%% From section, aliased selectors
%%%===================================================================
%% List of aliases after the AS statement
aliases -> alias : ['$1'].
aliases -> alias ',' aliases : ['$1'] ++ '$3'.
%% A single alias in the AS statement
alias -> selector kw_as part_or_name : {alias, '$3', '$1'}.
%%%===================================================================
%%% TIEM related symbols
%%%===================================================================
%% A timeframe for the select statment
timeframe -> kw_last int_or_time : #{op => last, args => ['$2']}.
timeframe -> kw_between pit kw_and pit : #{op => between, args => ['$2', '$4']}.
timeframe -> kw_after pit kw_for int_or_time : #{op => 'after', args => ['$2', '$4']}.
timeframe -> kw_before pit kw_for int_or_time : #{op => before, args => ['$2', '$4']}.
%% A point in time either a integer, a relative time with a AGO statement or the
%% NOW keyword.
pit -> int_or_time kw_ago : #{op => ago, args => ['$1']}.
pit -> integer : unwrap('$1').
pit -> date : {time, qdate:to_unixtime(unwrap('$1')) * 1000, ms}.
pit -> kw_now : now.
%% A relative time either given as absolute integer or relative.
int_or_time -> integer time : time(unwrap('$1'), unwrap('$2')).
int_or_time -> integer : unwrap('$1').
%%%===================================================================
%%% Helper symbols
%%%===================================================================
%% A naming, either wrapped in 's or not if the syntax is supported, reserved
%% words always have to be wrapped in 's
part_or_name -> part : unwrap('$1').
part_or_name -> name : unwrap('$1').
%% A metric, one or more parts seperated by '.'
metric -> part_or_name : ['$1'].
metric -> part_or_name '.' metric: ['$1' | '$3'].
%% A metric including a glob
glob_metric -> '*' : ['*'].
glob_metric -> '*' '.' metric : ['*' | '$3'].
glob_metric -> '*' '.' glob_metric : ['*' | '$3'].
glob_metric -> part_or_name '.' glob_metric : ['$1' | '$3'].
bucket -> part_or_name : '$1'.
%%%===================================================================
%%% Erlang code.
%%%===================================================================
Erlang code.
-ignore_xref([format_error/1, parse_and_scan/1, return_error/2]).
unwrap({_,_,V}) -> V;
unwrap({_,V}) -> V.
time(T, U) ->
#{
op => time,
args => [T, U],
signature => [integer, time_unit],
return => integer
}.
named(N, Q) ->
#{
op => named,
args => [N, Q],
return => undefined
}.