基于Calcite自定义SQL解析器

public void unparse(SqlWriter sqlWriter, int i, int i1) {

sqlWriter.keyword(“jacky”);

sqlWriter.keyword(“job”);

sqlWriter.print(“\n”);

sqlWriter.keyword(“” + jackyString + “”);

}

@Override

public void validate(SqlValidator sqlValidator, SqlValidatorScope sqlValidatorScope) {

System.out.println(“validate”);

}

@Override

public R accept(SqlVisitor sqlVisitor) {

System.out.println(“accept”);

return null;

}

@Override

public boolean equalsDeep(SqlNode sqlNode, Litmus litmus) {

System.out.println(“equalsDeep”);

return false;

}

}

在这个解析类里面,其实我们并没有做很多工作,只是在构造器里面,将变量保存起来。

需要注意的是这个方法,unparse ,这里用于解析显示用的,我们将关键字输出出来。

修改config.fmpp文件

找到

package: “org.apache.calcite.sql.parser.impl”,

将下方的class,替换成一个你自己的类名,后面会用到。例如

class: “JackySqlParserImpl”,

修改Parser.jj文件

首先需要在import的地方引入上面的解析类

import org.apache.calcite.sql.SqlJacky;

然后再后处理代码中加入解析逻辑

SqlNode SqlJacky() :

{

SqlNode stringNode;

}

{

stringNode = StringLiteral()

{

return new SqlJacky(getPos(), token.image);

}

}

接下来找到声明语句的方法

SqlNode SqlStmt() :

|

stmt = SqlJacky()

加入到适当的位置。

最后在

<DEFAULT, DQID, BTID> TOKEN :

的地方将,jacky 和 job 关键字加入

| < JACKY: “JACKY”>

| < JOB: “JOB”>

由于这个文件比较大,这里就不能贴完整的代码了,下面的连接中,有参考案例。

编译

执行maven的编译命令

测试

在构建测试的时候,注意将自己的解析解析类设置好,即在fmpp里设置的类名

.setParserFactory(JackySqlParserImpl.FACTORY)

完整测试代码如下

package cn.flinkhub;

import org.apache.calcite.avatica.util.Casing;

import org.apache.calcite.avatica.util.Quoting;

import org.apache.calcite.schema.SchemaPlus;

import org.apache.calcite.sql.SqlNode;

import org.apache.calcite.sql.parser.SqlParser;

import org.apache.calcite.tools.FrameworkConfig;

import org.apache.calcite.tools.Frameworks;

import org.apache.calcite.sql.parser.impl.JackySqlParserImpl;

public class CustomParser {

public static void main(String[] args) {

SchemaPlus rootSchema = Frameworks.createRootSchema(true);

final FrameworkConfig config = Frameworks.newConfigBuilder()

.parserConfig(SqlParser.configBuilder()

//.setLex(Lex.ORACLE)

.setParserFactory(JackySqlParserImpl.FACTORY)

.setCaseSensitive(false)

.setQuoting(Quoting.BACK_TICK)

.setQuotedCasing(Casing.TO_UPPER)

.setUnquotedCasing(Casing.TO_UPPER)

//.setConformance(SqlConformanceEnum.ORACLE_12)

.build())

.build();

// “jacky ‘select ids, name from test where id < 5’”;

String sql = “jacky job ‘select ids, name from test where id < 5’”;

SqlParser parser = SqlParser.create(sql, config.getParserConfig());

try {

SqlNode sqlNode = parser.parseStmt();

System.out.println(sqlNode.toString());

} catch (Exception e) {

e.printStackTrace();

}

}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

总结

大型分布式系统犹如一个生命,系统中各个服务犹如骨骼,其中的数据犹如血液,而Kafka犹如经络,串联整个系统。这份Kafka源码笔记通过大量的设计图展示、代码分析、示例分享,把Kafka的实现脉络展示在读者面前,帮助读者更好地研读Kafka代码。

麻烦帮忙转发一下这篇文章+关注我

就这一次!拼多多内部架构师培训Kafka源码笔记(现已绝版)

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
" />

总结

大型分布式系统犹如一个生命,系统中各个服务犹如骨骼,其中的数据犹如血液,而Kafka犹如经络,串联整个系统。这份Kafka源码笔记通过大量的设计图展示、代码分析、示例分享,把Kafka的实现脉络展示在读者面前,帮助读者更好地研读Kafka代码。

麻烦帮忙转发一下这篇文章+关注我

[外链图片转存中…(img-S6Q1kJdg-1712894641493)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 27
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用基于Gradle的CalciteSQL测试库,您需要按照以下步骤进行操作: 1. 在您的Gradle项目中添加以下依赖项: ``` dependencies { testCompile group: 'org.apache.calcite', name: 'calcite-core', version: '1.22.0' testCompile group: 'org.apache.calcite', name: 'calcite-test', version: '1.22.0' } ``` 2. 在项目中创建一个名为“resources”的文件夹,并在其中创建一个名为“sql”的子文件夹。 3. 在“sql”文件夹中创建一个名为“schema.json”的文件,其中包含您要测试的SQL模式的定义。 4. 在“sql”文件夹中创建多个以“.sql”为扩展名的SQL测试文件。 5. 在测试类中编写测试代码,如下所示: ``` import org.apache.calcite.jdbc.CalciteConnection; import org.apache.calcite.schema.SchemaPlus; import org.apache.calcite.sql.parser.SqlParseException; import org.apache.calcite.sql.parser.SqlParser; import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.SqlSelect; import org.apache.calcite.tools.Frameworks; import org.apache.calcite.tools.FrameworkConfig; import org.apache.calcite.tools.Frameworks.ConfigBuilder; import org.apache.calcite.tools.ValidationException; import org.junit.BeforeClass; import org.junit.Test; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; import java.util.Properties; public class SqlTest { private static Connection connection; @BeforeClass public static void setUp() throws Exception { Properties info = new Properties(); info.setProperty("lex", "JAVA"); connection = DriverManager.getConnection("jdbc:calcite:", info); } @Test public void testSql() throws SqlParseException, ValidationException { String sql = "SELECT * FROM myTable"; SqlNode sqlNode = parse(sql); SqlSelect sqlSelect = (SqlSelect) sqlNode; SchemaPlus rootSchema = getRootSchema(); ConfigBuilder configBuilder = Frameworks.newConfigBuilder(); configBuilder.defaultSchema(rootSchema); FrameworkConfig frameworkConfig = configBuilder.build(); CalciteConnection calciteConnection = connection.unwrap(CalciteConnection.class); Statement statement = calciteConnection.createStatement(); ResultSet resultSet = statement.executeQuery(sql); // 测试结果验证 // ... } private static SqlNode parse(String sql) throws SqlParseException { SqlParser.Config config = SqlParser.configBuilder().setLex(Lex.JAVA).build(); SqlParser sqlParser = SqlParser.create(sql, config); return sqlParser.parseQuery(); } private static SchemaPlus getRootSchema() { SchemaPlus rootSchema = Frameworks.createRootSchema(true); // 添加模式定义 // ... return rootSchema; } } ``` 上述代码中,“testSql”方法是一个测试方法,它解析一个SQL查询并将其执行。您可以根据需要编写自己的测试逻辑。 6. 运行测试。您可以使用Gradle命令“gradle test”运行测试。 希望这能帮助您使用基于Gradle的CalciteSQL测试库进行测试。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值