#gStore-weekly | SPARQL 解析(上)

#gStore-weekly | SPARQL 解析(上)

1.1 简介

gStore 的 SPARQL 解析发生在发起查询时(包括使用 gquery 和 ghttp 来发起查询)。如使用 gquery 发起查询:

$ bin/gquery -db example -q example.sparql

则 gStore 会读入 SPARQL 查询文件 example.sparql ,对其进行解析,并交由查询执行器执行。

1.2 类层次结构

SPARQL 解析由 QueryParser 类完成。QueryParser 类继承了解析器生成器 ANTLR 由 SPARQL 语法自动生成的 SPARQLBaseVisitor 类,生成查询的语法树,并通过访问语法树的相关结点获取关键信息,填充到表征查询的 QueryTree 类对象中。

1.3 QueryTree 类

QueryTree 类用于表示查询结构、存储查询中的关键信息。

1.3.1 类成员变量
变量类型注释
QueryFormenum 公有标识查询类型(SELECT或ASK)
ProjectionModifierenum 公有标识查询投影变量是否有修饰符(目前支持无修饰符Modifier_None、DISTINCT修饰符Modifier_Distinct)
UpdateTypeenum 公有标识更新语句的类型(若为查询,则值为Not_Update;暂未支持Modify_Clause)
query_formQueryForm 私有查询类型
projection_modifierProjectionModifier 私有查询投影变量的修饰符
projectionstd::vector 私有投影的变量/函数
projection_asteriskbool 私有是否投影查询中出现的所有变量(SELECT *)
group_byVarset 私有GROUP BY语句中出现的变量集合
order_bystd::vector 私有ORDER BY语句中的条件
offsetint 私有OFFSET语句中的数值,表示从第几行结果开始输出,一般与ORDER BY配合使用
limitint 私有LIMIT语句中的数值,表示输出的结果数量上限
group_patternGroupPattern 私有查询中最外层的组图模式(即最外层大括号括起的部分)
singleBGPbool 私有查询中是否仅包含一个基本图模式(Basic Graph Pattern, BGP)
update_typeUpdateType 私有更新语句的类型
insert_patternsGroupPattern 私有INSERT类更新语句中最外层的组图模式
delete_patternsGroupPattern 私有DELETE类更新语句中最外层的组图模式

其中 group_pattern 为嵌套类 QueryTree::GroupPattern 对象,有成员变量 vector<QueryTree::GroupPattern::SubGroupPattern> sub_group_pattern ,表示组图模式中互为连接关系的子图模式。

1.3.2 关键嵌套类 QueryTree::GroupPattern::SubGroupPattern

这一嵌套类表示组图模式中的子图模式,分为以下类型:嵌套组图模式、三元组模式、UNION图模式、OPTIONAL图模式、MINUS图模式、FILTER结构/BIND结构。为某种类型时,相应的成员变量中存储其相关信息:如为三元组模式时,为 QueryTree::GroupPattern::Pattern 类对象的成员变量 pattern 中存储三元组的主语、谓词和宾语。

QueryTree::GroupPattern::SubGroupPattern 类的成员变量如下:

变量类型注释
SubGroupPatternTypeenum 公有标识子模式类型(嵌套组图模式/三元组模式/UNION图模式/OPTIONAL图模式/MINUS图模式/FILTER结构/BIND结构)
typeSubGroupPatternType 公有当前子模式的类型
patternPattern 公有当前子模式为三元组模式时,给出其具体信息
group_patternGroupPattern 公有当前子模式为嵌套组图模式时,给出其具体信息
unionsstd::vector 公有当前子模式为UNION图模式时,给出其具体信息
optionalGroupPattern 公有当前子模式为OPTIONAL图模式时,给出其具体信息
filterCompTreeNode 公有当前子模式为FILTER结构时,给出其具体信息
bindBind 公有当前子模式为BIND结构时,给出其具体信息

1.4 QueryParser::SPARQLParse

QueryParser::SPARQLParse 为 QueryParser 类中驱动 SPARQL 解析的成员函数。

函数原型:

void SPARQLParse(const std::string &query);

关键代码段说明如下。

函数整体为 try-catch 结构,尝试进行 SPARQL 解析,若其中遇到语法错误并抛出异常,则捕获异常并打印错误信息。

try{
...
}catch(const runtime_error& e1)
{
  throw runtime_error(e1.what());
}

在 try 分支中,首先由输入参数 query 字符串创建 istringstream 类对象,并创建用于捕捉和报告语法错误的 SPARQLErrorListener 类对象:

istringstream ifs(query);
SPARQLErrorListener lstnr;

然后使用 ANTLR 自动生成的 SPARQL 词法解析器 SPARQLLexer ,对查询进行词法解析(将其原有的错误报告器替换为自定义配置过的 lstnr ):

antlr4::ANTLRInputStream input(ifs);
SPARQLLexer lexer(&input);
lexer.removeErrorListeners();
lexer.addErrorListener(&lstnr);

再使用 ANTLR 自动生成的 SPARQL 语法解析器 SPARQParser 对词法解析的结果进行语法解析(同样将其原有的错误报告器替换为 lstnr ):

antlr4::CommonTokenStream tokens(&lexer);
SPARQLParser parser(&tokens);
parser.removeErrorListeners();
parser.addErrorListener(&lstnr);

最后调用入口函数 QueryParser::visitEntry ,从语法解析树的根结点开始遍历之,收集关键信息填入 QueryTree:

SPARQLParser::EntryContext *tree = parser.entry();
visitEntry(tree);

1.5 小结

本篇介绍了 gStore 的 SPARQL 解析机制,主要详细分析了 QueryTree 类的结构和 QueryParser 类中的驱动函数 QueryParser::SPARQLParse,建议在阅读的同时结合源码 Query/QueryTree.h、Parser/QueryParser.cpp 一起分析,会更容易理解。在本章的下篇中,我们将继续介绍 QueryParser 类在遍历语法解析树的过程中调用的关键函数。
#gStore-weekly | SPARQL 解析(下)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值