Commit 578f642d authored by mouadh's avatar mouadh

remove grako parser

parent 318d06e3
This diff is collapsed.
from __future__ import absolute_import, division, print_function
class SelectStatement:
def __init__(self, select_statement):
self.select_statement = select_statement
def __str__(self):
return '{}'.format(self.select_statement)
(* The ebnf file is the translation and improvement of microsoft mdx's spec, from https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms717923%28v=vs.85%29.aspx *)
(* The ebnf conversion was guided by http://stackoverflow.com/questions/14922242/how-to-convert-bnf-to-ebnf *)
(* The generation of mdx_parser.py is as easy as: /path/to/grako bnf_mdx.ebnf -o mdx_parser.py *)
mdx_statement =
select_statement;
select_statement::SelectStatement = name:'SELECT' [axis_specification_columns:axis_specification]
[',' axis_specification_rows:axis_specification]
'FROM' cube_specification:cube_specification
['WHERE' condition_specification:condition_specification]$
;
axis_specification = [left_accolade] [fetch_form] @:dim_props_place [right_accolade] 'ON' axis_name;
dim_props_place = [left_parentheses] @:dim_props_type [right_parentheses] ;
dim_props_type = [left_accolade] [fetch_type] @:dim_props_op_l1 [right_accolade] [{@:operator dim_props_type}*];
dim_props_op_l1 = [left_parentheses] @:dim_props_op [right_parentheses];
dim_props_op = [left_accolade] @:dim_props_ligne [right_accolade] [{@:comma dim_props_op}*];
dim_props_ligne = [left_parentheses] @:dimension_place [right_parentheses] [{ (@:comma | @:dpoint ) @:dim_props_ligne}*] ;
dimension_place = [left_accolade] @:dim_props [ point @:laste_node] [ @:comma @:dim_props [ point @:laste_node ]] [@:dpoint @:dim_props [ point @:laste_node ]] [right_accolade] | @:dimension_shortcut;
dim_props = {[point] [left_bracket] @:dimension [right_bracket]}* ;
laste_node = "members" | "children" | "Members" | 'ALLMEMBERS' ;
dimension = @:/[a-zA-Z0-9'_'' '',']*/ ;
axis_name = '0' | '1' |'COLUMNS' | 'ROWS' | '_ROWS';
cube_specification = [left_bracket] dimension [right_bracket];
condition_specification = [left_parentheses] {[point] [left_bracket] @:dimension [right_bracket]}* [right_parentheses] ;
digit =
"0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
fetch_type = 'CROSSJOIN' | 'NONEMPTY' | 'union' | 'except' | 'extract' ;
dimension_shortcut = 'all' | 'time' ;
fetch_form = 'NONEMPTY' | 'non_empty' | 'non empty' ;
left_bracket = '[';
right_bracket = ']';
left_parentheses = '(';
right_parentheses = ')';
left_accolade = '{';
right_accolade = '}';
point = '.' ;
dpoint = ':' ;
comma = ',' ;
operator = '+' | '-' | '/' | '*' ;
from __future__ import absolute_import, division, print_function
from grako.model import ModelBuilderSemantics
from .gen_parser.mdxparser import MdxParserGen
from .gen_parser.models import SelectStatement
class MdxParser:
"""Parse the mdx query and split it into well-defined parts."""
START = 'MDX_statement'
@staticmethod
def parsing_mdx_query(axis, query):
"""Split the query into axis.
**Example**::
SELECT
{ [Geography].[Geo].[Country].[France],
[Geography].[Geo].[Country].[Spain] } ON COLUMNS,
{ [Product].[Prod].[Company].[Crazy Development] } ON ROWS
FROM [Sales]
WHERE [Time].[Calendar].[Year].[2010]
+------------+------------------------------------------------+
| | [Geography].[Geo].[Country].[France] |
| column | |
| | [Geography].[Geo].[Country].[Spain] |
+------------+------------------------------------------------+
| row | [Product].[Prod].[Company].[Crazy Development] |
+------------+------------------------------------------------+
| cube | [Sales] |
+------------+------------------------------------------------+
| condition | [Time].[Calendar].[Year].[2010] |
+------------+------------------------------------------------+
:param query: MDX Query
:param axis: column | row | cube | condition | all
:return: Tuples in the axis, from the MDX query
"""
model = MdxParserGen(semantics=ModelBuilderSemantics(
types=[SelectStatement]))
ast = model.parse(query, rule_name=MdxParser.START, ignorecase=True)
if axis == "column":
if ast.select_statement.axis_specification_columns is not None and \
u'' in ast.select_statement.axis_specification_columns:
ast.select_statement.axis_specification_columns.remove(u'')
return ast.select_statement.axis_specification_columns
elif axis == "row":
if ast.select_statement.axis_specification_rows is not None and \
u'' in ast.select_statement.axis_specification_rows:
ast.select_statement.axis_specification_rows.remove(u'')
return ast.select_statement.axis_specification_rows
elif axis == "cube":
if ast.select_statement.cube_specification is not None and \
u'' in ast.select_statement.cube_specification:
ast.select_statement.cube_specification.remove(u'')
return ast.select_statement.cube_specification[1] if \
isinstance(ast.select_statement.cube_specification, list) \
else ast.select_statement.cube_specification
elif axis == "condition":
if ast.select_statement.condition_specification is not None and \
type(ast.select_statement.condition_specification) not in (
unicode, str) and \
u'' in ast.select_statement.condition_specification:
ast.select_statement.condition_specification.remove(u'')
return ast.select_statement.condition_specification
elif axis == "all":
return 'Operation = {} \n' \
'Columns = {} \n' \
'Rows = {} \n' \
'From = {} \n' \
'Where = {} \n'.format(ast.select_statement.name,
ast.select_statement.from_,
ast.select_statement.axis_specification_columns,
ast.select_statement.axis_specification_rows,
ast.select_statement.cube_specification,
ast.select_statement.condition_specification,
)
#
grako
#grako
pandas<1
lxml==3.6.0 #lxml 3.7 causes problems in windows
spyne<3
......
......@@ -4,7 +4,6 @@
#
# pip-compile --output-file requirements.txt requirements.in
#
grako==3.99.9
lxml==3.6.0
numpy==1.12.1 # via pandas
pandas==0.20.1
......
from __future__ import absolute_import, division, print_function
import pandas as pd
from pandas.util.testing import assert_frame_equal
from olapy.core.mdx.executor.execute import MdxEngine
from olapy.core.mdx.parser.parse import MdxParser
CUBE = 'sales'
query1 = "SELECT" \
"{[Measures].[Amount]} ON COLUMNS " \
"FROM [sales]"
query2 = """SELECT
{[Geography].[Economy].[Partnership]} ON COLUMNS
FROM [sales]"""
query3 = """SELECT
{[Measures].[Amount]} on 0,
non empty {[Geography].[Geo].[Country].members} ON COLUMNS
FROM [sales]"""
query4 = """SELECT
{[Geography].[Economy].[Partnership]} ON COLUMNS,
non empty {[Geography].[Geo].[Country].members} on 1
from [sales]"""
query5 = """select
{[Geography].[Economy].[Country]} on 0,
non empty {[Geography].[Geo].[Country].members} on 1
from [sales]"""
query6 = """select
{[Geography].[Economy].[Partnership]} on 0,
{[Product].[Prod].[Company]} on 1
from [sales]"""
query7 = """select
{[Geography].[Economy].[Partnership].[EU]} on 0,
{[Product].[Prod].[Company].[Crazy Development]} on 1
from [sales]"""
query8 = """select
{[Geography].[Economy].[Partnership].[EU],
[Geography].[Economy].[Partnership].[None],
[Geography].[Economy].[Partnership].[NAFTA]} on 0,
{[Product].[Prod].[Company].[Crazy Development],
[Product].[Prod].[Company].[Company_test],
[Product].[Prod].[Company].[test_Development]} on 1
from [sales]"""
query9 = """select
{[Geography].[Economy].[Partnership].[EU],
[Geography].[Economy].[Partnership].[None]} on 0
from [sales]"""
query10 = """select
{[Geography].[Geo].[Country].[France],
[Geography].[Geo].[Country].[Spain]} on 0,
non empty {[Measures].[Amount]} on 1
from [sales]"""
where1 = "Where [Time].[Calendar].[Day].[May 12,2010]"
where2 = "Where[Product].[olapy].[Personal]"
where3 = "Where[Time].[Calendar].[Year].[2010]"
where4 = "Where [Measures].[Count]"
where5 = "where [Count]"
query11 = """
SELECT NON EMPTY Hierarchize(AddCalculatedMembers(DrilldownMember({{DrilldownMember({{DrilldownMember({{
[Time].[Time].[Year].Members}}, {
[Time].[Time].[Year].[2010]})}}, {
[Time].[Time].[Quarter].[2010].[Q2 2010]})}}, {
[Time].[Time].[Month].[2010].[Q2 2010].[May 2010]}))) DIMENSION PROPERTIES PARENT_UNIQUE_NAME,HIERARCHY_UNIQUE_NAME
ON COLUMNS
FROM [sales] WHERE ([Measures].[Amount])
CELL PROPERTIES VALUE, FORMAT_STRING, LANGUAGE, BACK_COLOR, FORE_COLOR, FONT_FLAGS
"""
query12 = """SELECT NON EMPTY Hierarchize(AddCalculatedMembers({
[Geography].[Geography].[Continent].Members}))
DIMENSION PROPERTIES PARENT_UNIQUE_NAME,HIERARCHY_UNIQUE_NAME ON COLUMNS
FROM [sales]
WHERE ([Measures].[Amount])
CELL PROPERTIES VALUE, FORMAT_STRING, LANGUAGE, BACK_COLOR, FORE_COLOR, FONT_FLAGS"""
parser = MdxParser()
executer = MdxEngine(CUBE)
def test_parsing_query1():
assert parser.parsing_mdx_query(
'column', query=query1) == ['Measures', 'Amount']
assert parser.parsing_mdx_query('cube', query=query1) == "sales"
assert parser.parsing_mdx_query('row', query=query1) is None
query1_where = query1 + '\n' + where1
assert parser.parsing_mdx_query(
'condition',
query=query1_where) == [u'Time', u'Calendar', u'Day', u'May 12,2010']
query2_where = query1 + '\n' + where2
assert parser.parsing_mdx_query(
'condition', query=query2_where) == [u'Product', u'olapy', u'Personal']
query3_where = query1 + '\n' + where3
assert parser.parsing_mdx_query(
'condition',
query=query3_where) == [u'Time', u'Calendar', u'Year', u'2010']
def test_parsing_query2():
assert parser.parsing_mdx_query(
'column', query=query2) == [u'Geography', u'Economy', u'Partnership']
assert parser.parsing_mdx_query('cube', query=query2) == "sales"
assert parser.parsing_mdx_query('row', query=query2) is None
query1_where = query2 + '\n' + where1
assert parser.parsing_mdx_query(
'condition',
query=query1_where) == [u'Time', u'Calendar', u'Day', u'May 12,2010']
query2_where = query2 + '\n' + where2
assert parser.parsing_mdx_query(
'condition', query=query2_where) == [u'Product', u'olapy', u'Personal']
query3_where = query2 + '\n' + where3
assert parser.parsing_mdx_query(
'condition',
query=query3_where) == [u'Time', u'Calendar', u'Year', u'2010']
def test_parsing_query3():
assert parser.parsing_mdx_query(
'column', query=query3) == [u'Measures', u'Amount']
assert parser.parsing_mdx_query('cube', query=query3) == "sales"
assert parser.parsing_mdx_query(
'row', query=query3) == [u'Geography', u'Geo', u'Country', u'members']
query1_where = query3 + '\n' + where1
assert parser.parsing_mdx_query(
'condition',
query=query1_where) == [u'Time', u'Calendar', u'Day', u'May 12,2010']
query2_where = query3 + '\n' + where2
assert parser.parsing_mdx_query(
'condition', query=query2_where) == [u'Product', u'olapy', u'Personal']
query3_where = query3 + '\n' + where3
assert parser.parsing_mdx_query(
'condition',
query=query3_where) == [u'Time', u'Calendar', u'Year', u'2010']
def test_parsing_query4():
query0 = query4
assert parser.parsing_mdx_query(
'column', query=query0) == [u'Geography', u'Economy', u'Partnership']
assert parser.parsing_mdx_query('cube', query=query0) == "sales"
assert parser.parsing_mdx_query(
'row', query=query0) == [u'Geography', u'Geo', u'Country', u'members']
query1_where = query0 + '\n' + where1
assert parser.parsing_mdx_query(
'condition',
query=query1_where) == [u'Time', u'Calendar', u'Day', u'May 12,2010']
query2_where = query0 + '\n' + where2
assert parser.parsing_mdx_query(
'condition', query=query2_where) == [u'Product', u'olapy', u'Personal']
query3_where = query0 + '\n' + where3
assert parser.parsing_mdx_query(
'condition',
query=query3_where) == [u'Time', u'Calendar', u'Year', u'2010']
def test_parsing_query5():
query0 = query5
assert parser.parsing_mdx_query(
'column', query=query0) == [u'Geography', u'Economy', u'Country']
assert parser.parsing_mdx_query('cube', query=query0) == "sales"
assert parser.parsing_mdx_query(
'row', query=query0) == [u'Geography', u'Geo', u'Country', u'members']
query1_where = query0 + '\n' + where1
assert parser.parsing_mdx_query(
'condition',
query=query1_where) == [u'Time', u'Calendar', u'Day', u'May 12,2010']
query2_where = query0 + '\n' + where2
assert parser.parsing_mdx_query(
'condition', query=query2_where) == [u'Product', u'olapy', u'Personal']
query3_where = query0 + '\n' + where3
assert parser.parsing_mdx_query(
'condition',
query=query3_where) == [u'Time', u'Calendar', u'Year', u'2010']
def test_parsing_query6():
query0 = query6
assert parser.parsing_mdx_query(
'column', query=query0) == [u'Geography', u'Economy', u'Partnership']
assert parser.parsing_mdx_query('cube', query=query0) == "sales"
assert parser.parsing_mdx_query(
'row', query=query0) == [u'Product', u'Prod', u'Company']
query1_where = query0 + '\n' + where1
assert parser.parsing_mdx_query(
'condition',
query=query1_where) == [u'Time', u'Calendar', u'Day', u'May 12,2010']
query2_where = query0 + '\n' + where2
assert parser.parsing_mdx_query(
'condition', query=query2_where) == [u'Product', u'olapy', u'Personal']
query3_where = query0 + '\n' + where3
assert parser.parsing_mdx_query(
'condition',
query=query3_where) == [u'Time', u'Calendar', u'Year', u'2010']
def test_execution_query1():
executer.mdx_query = query1
assert executer.execute_mdx()['result']['Amount'][0] == 1023
executer.mdx_query = query11
assert executer.execute_mdx()['result']['Amount'][3] == 1
assert executer.execute_mdx()['result']['Amount'][4] == 2
def test_execution_query3():
df = pd.DataFrame({
'Continent': ['America', 'Europe'],
'Amount': [768, 255]
}).groupby(['Continent']).sum()
executer.mdx_query = query12
assert assert_frame_equal(df, executer.execute_mdx()['result']) is None
executer.mdx_query = query11
assert list(executer.execute_mdx()['result'][
'Amount']) == [1023, 1023, 1023, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment