众所周知,mondrian是用java语言实现的一个olap查询引擎,在数据检索方面mondrian支持MDX(多维查询语言)。最近对这块进行了深入的研究。下面对函数的解析、执行流程作一个简单的总结。其它的内容后续章节继续。由于工作关系,可能会过一段时间
首先说明下,要研究透这部分代码需具备的一些知识
1.熟悉java,最好是熟悉java 5以后的版本的语法
2.了解MDX语法。
3.对mondrian有一定的了解
4.了解jolap的查询模型结构或者是olap4j中的解析结构
5.熟悉编译原理(主要是lr语法分析),了解java cup
其中前3项是必备知识,后两项,在不了解的情况下,我会做相应的说明,不影响阅读本文。
需要的研究环境
1.java 5.0及以上版本
2.java IDE(如 eclipse)
3.mondrian源码包(在此分析的是mondrian-3.1.0.12477版本)
环境搭建方面:
1.安装jdk、IDE等,这里就不详细介绍
2.搭建一个web工程。
3.导入mondrian源码
很不幸的是,在我得到的版本中,有类缺失,而且是关键类。哎……
要了解mdx中的函数执行情况,首先就得出MDX语法解析开始,这部分主要涉及的是mondrian.mdx包和mondrian.olap包!其中mdx语法解析的核心类是mondrian.olap.Parser,很不幸,我下载的源码中没有这个类,如果您也发现没有这个类也不用着急,找到mondrian.olap包下的Parser.cup文件,然后用java cup的命令执行以下就生成了该缺失的类,不生成该类也不影响。
在了解了这些以后,我们先不着急去看Parser类,如果您不熟悉lr语法分析算法,不熟悉java cup,估计您也很难看明白里面是在做什么。首先还是回到Parser.cup文件,搜索“Syntax.Function”内容,定位到MDX函数的语法产生式:value_expression_primary ::=bang_compound_id:i LPAREN exp_list_opt:lis RPAREN.至于其中哪些是终结符,哪些是非终结符不明白没有关系。您可以这样理解,MDX函数语法规则就是一个函数名称(bang_compound_id)后跟一个左括号(LPAREN )后再跟以串参数列表(exp_list_opt)后再跟一个右括号(RPAREN)的形式。其中的参数列表是什么形式,您可以继续去看它的产生式。
了解了函数的语法以后,接下来,就需要看当语法解析器在识别到一个函数语法时做的相应的动作(如何规约)。如下:
{:
RESULT = new UnresolvedFunCall(
i.getSegments().get(i.getSegments().size() - 1).name,
Syntax.Function, Parser.toExpArray(lis));
:} 注:java cup中的action是包含“{:”“:}”对中,其中的i和lis是指产生式中的非终结符
从上面的动作可以看出。解析器在识别到一个mdx函数时,都是将其构建成一个UnresolvedFunCall实例,实例中包含有函数的名称,参数列表(Exp类型的),和
函数标识(Syntax.Function)。
接下来,我们就可以从UnresolvedFunCall入手进行分析了。在mondrian.mdx包中找到该类。该类就如构建时一样,一共三个属性,这里就不做更多的说明了。重点说下其中的两个方法:1:public void unparse(PrintWriter pw) 2:public Exp accept(Validator validator)
其中前者是将该结构翻译成mdx语言,并将其写入到pw中。后者就是执行该结构的信息(如执行函数)。
执行的步骤如下:查到到该函数的实例。然后再调用函数的createCall方法。剩下的就是去看具体函数是怎么样来实现该createCall方法的了。
附:要理解MDX语法的解析,弄清楚其对应的语法结构关系是关键,主要就是mondrian.mdx包。当然也牵涉了一些mondrian.olap包中的内容
以上信息希望对研究这部分的人有快速定位的帮助
作者:slob
2009-12-11