热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

calcite初试使用sql读取csv文件

文章目录背景主流程代码生成AST树对sql进行验证,是否合法sqlNode转成RelRootRelNode根据规则进行优化RelRoot生成物理执行计划schemaC


文章目录

    • 背景
    • 主流程代码
      • 生成AST 树
      • 对sql 进行验证,是否合法
      • sqlNode转成RelRoot
      • RelNode 根据规则进行优化
      • RelRoot 生成物理执行计划
    • schema
    • CsvTable
    • DemoCsvEnumerator
    • Pom.xml
    • 测试


背景

通过calcite,使用sql来读取csv数据
本文争取利用最少的代码来实现此功能,理解calcite是如何工作的


主流程代码


生成AST 树

SqlParser parser = SqlParser.create("select * from DEPTS where DEPTNO>=20 ", SqlParser.Config.DEFAULT);// 解析SQL字符串, 生成SqlNode树SqlNode sqlNode = parser.parseStmt();System.out.println(sqlNode);

结果 SqlNode

SELECT *
FROM DEPTS
WHERE DEPTNO >= 20


对sql 进行验证,是否合法

CsvSchema csvSchema = new CsvSchema();CalciteSchema rootSchema = CalciteSchema.createRootSchema(true, false);rootSchema.add("test_schema", csvSchema);SchemaPlus schemaPlus = Frameworks.createRootSchema(false);schemaPlus.add("test_schema", csvSchema);CalciteConnectionConfigImpl config = new CalciteConnectionConfigImpl(new Properties());RelDataTypeFactory typeFactory = new JavaTypeFactoryImpl();Prepare.CatalogReader catalogReader = new CalciteCatalogReader(rootSchema, Collections.singletonList("test_schema"), typeFactory, config);SqlValidator.Config validatorConfig = SqlValidator.Config.DEFAULT.withLenientOperatorLookup(config.lenientOperatorLookup()).withSqlConformance(config.conformance()).withDefaultNullCollation(config.defaultNullCollation()).withIdentifierExpansion(true);SqlValidator validator = SqlValidatorUtil.newValidator(SqlStdOperatorTable.instance(), catalogReader, typeFactory, validatorConfig);// 执行SQL验证SqlNode validateSqlNode = validator.validate(sqlNode);System.out.println(sqlNode);

输出 SqlNode
SELECT DEPTS.DEPTNO, DEPTS.NAME
FROM test_schema.DEPTS AS DEPTS
WHERE DEPTS.DEPTNO >= 20


sqlNode转成RelRoot

VolcanoPlanner planner = new VolcanoPlanner(RelOptCostImpl.FACTORY, Contexts.of(config));planner.addRelTraitDef(ConventionTraitDef.INSTANCE);// 创建SqlToRelConverterRelOptCluster cluster = RelOptCluster.create(planner, new RexBuilder(typeFactory));SqlToRelConverter.Config converterConfig = SqlToRelConverter.config().withTrimUnusedFields(true).withExpand(false);SqlToRelConverter converter = new SqlToRelConverter(null, validator, catalogReader, cluster, StandardConvertletTable.INSTANCE, converterConfig);// 将SqlNode树转化为RelNode树RelRoot relNode = converter.convertQuery(validateSqlNode, false, true);System.out.println(relNode);

输出
Root {kind: SELECT, rel: rel#3:LogicalProject.NONE(input&#61;LogicalFilter#2,inputs&#61;0…1), rowType: RecordType(INTEGER DEPTNO, VARCHAR NAME), fields: [<0, DEPTNO>, <1, NAME>], collation: []}


RelNode 根据规则进行优化

// 规则RuleSet rules &#61; RuleSets.ofList(CoreRules.FILTER_TO_CALC, CoreRules.PROJECT_TO_CALC, CoreRules.FILTER_CALC_MERGE, CoreRules.PROJECT_CALC_MERGE, CoreRules.FILTER_INTO_JOIN, // 过滤谓词下推到Join之前EnumerableRules.ENUMERABLE_TABLE_SCAN_RULE, EnumerableRules.ENUMERABLE_PROJECT_TO_CALC_RULE, EnumerableRules.ENUMERABLE_FILTER_TO_CALC_RULE, EnumerableRules.ENUMERABLE_JOIN_RULE, EnumerableRules.ENUMERABLE_SORT_RULE, EnumerableRules.ENUMERABLE_CALC_RULE, EnumerableRules.ENUMERABLE_AGGREGATE_RULE);Program program &#61; Programs.of(RuleSets.ofList(rules));RelNode optimizerRelTree &#61; program.run(planner, relNode.rel, relNode.rel.getTraitSet().plus(EnumerableConvention.INSTANCE), Collections.emptyList(), Collections.emptyList());System.out.println(optimizerRelTree);

RelRoot 生成物理执行计划

// 生成物理执行计划EnumerableRel enumerable &#61; (EnumerableRel) optimizerRelTree;Map<String, Object> internalParameters &#61; new LinkedHashMap<>();EnumerableRel.Prefer prefer &#61; EnumerableRel.Prefer.ARRAY;Bindable bindable &#61; EnumerableInterpretable.toBindable(internalParameters, null, enumerable, prefer);final Properties properties &#61; new Properties();properties.put("caseSensitive", "true");Connection connection &#61; DriverManager.getConnection("jdbc:calcite:", properties);CalciteConnection calciteConnection &#61; connection.unwrap(CalciteConnection.class);DataContext dataContext &#61; DataContexts.of(calciteConnection, schemaPlus);Enumerable bind &#61; bindable.bind(dataContext);Enumerator enumerator &#61; bind.enumerator();while (enumerator.moveNext()) {Object current &#61; enumerator.current();Object[] values &#61; (Object[]) current;StringBuilder sb &#61; new StringBuilder();for (Object v : values) {sb.append(v).append(",");}sb.setLength(sb.length() - 1);System.out.println(sb);}

schema

public class CsvSchema extends AbstractSchema {&#64;Overrideprotected Map<String, Table> getTableMap() {return createTableMap();}private Map<String, Table> createTableMap() {HashMap<String, Table> hashMap &#61; new HashMap<>();File file &#61; new File(this.getClass().getClassLoader().getResource("sales/DEPTS.csv").getPath());Source sourceDepts &#61; Sources.of(file);hashMap.put("DEPTS", new CsvScannableTable(sourceDepts, null));return hashMap;}
}

CsvTable

public class CsvScannableTable extends CsvTableimplements ScannableTable {CsvScannableTable(Source source, RelProtoDataType protoRowType) {super(source, protoRowType);}&#64;Override public String toString() {return "CsvScannableTable";}&#64;Override public Enumerable< Object[]> scan(DataContext root) {JavaTypeFactory typeFactory &#61; root.getTypeFactory();final List<RelDataType> fieldTypes &#61; getFieldTypes(typeFactory);final List<Integer> fields &#61; ImmutableIntList.identity(fieldTypes.size());return new AbstractEnumerable<&#64;Nullable Object[]>() {&#64;Overridepublic Enumerator<&#64;Nullable Object[]> enumerator() {try {return new DemoCsvEnumerator(source, fieldTypes, fields);} catch (IOException e) {throw new RuntimeException(e);}}};}
}

DemoCsvEnumerator


public class DemoCsvEnumerator<E> implements Enumerator<E> {private final CSVReader reader;private final DemoCsvEnumerator.RowConverter<E> rowConverter;private final &#64;Nullable List<&#64;Nullable String> filterValues;private &#64;Nullable E current;public DemoCsvEnumerator(Source source,List<RelDataType> fieldTypes, List<Integer> fields) throws IOException {//noinspection uncheckedthis(source, null,(DemoCsvEnumerator.RowConverter<E>) converter(fieldTypes, fields));}private static DemoCsvEnumerator.RowConverter<?> converter(List<RelDataType> fieldTypes,List<Integer> fields) {return new DemoCsvEnumerator.ArrayRowConverter(fieldTypes, fields);}public DemoCsvEnumerator(Source source,&#64;Nullable String &#64;Nullable [] filterValues, RowConverter<E> rowConverter) throws IOException {this.rowConverter &#61; rowConverter;this.filterValues &#61; filterValues &#61;&#61; null ? null: ImmutableNullableList.copyOf(filterValues);this.reader &#61; new CSVReader(source.reader());this.reader.readNext(); // skip header row}abstract static class RowConverter<E> {abstract E convertRow(&#64;Nullable String[] rows);&#64;SuppressWarnings("JavaUtilDate")protected &#64;Nullable Object convert(&#64;Nullable RelDataType fieldType, &#64;Nullable String string) {if (fieldType &#61;&#61; null || string &#61;&#61; null) {return string;}switch (fieldType.getSqlTypeName()) {case INTEGER:if (string.length() &#61;&#61; 0) {return null;}return Integer.parseInt(string);case VARCHAR:default:return string;}}}public static RelDataType deduceRowType(JavaTypeFactory typeFactory,Source source, &#64;Nullable List<RelDataType> fieldTypes, Boolean stream) {final List<RelDataType> types &#61; new ArrayList<>();final List<String> names &#61; new ArrayList<>();if (fieldTypes !&#61; null) {fieldTypes.add(toNullableRelDataType(typeFactory, SqlTypeName.INTEGER));fieldTypes.add(toNullableRelDataType(typeFactory, SqlTypeName.VARCHAR));}types.add(toNullableRelDataType(typeFactory, SqlTypeName.INTEGER));types.add(toNullableRelDataType(typeFactory, SqlTypeName.VARCHAR));names.add("DEPTNO");names.add("NAME");return typeFactory.createStructType(Pair.zip(names, types));}private static RelDataType toNullableRelDataType(JavaTypeFactory typeFactory,SqlTypeName sqlTypeName) {return typeFactory.createTypeWithNullability(typeFactory.createSqlType(sqlTypeName), true);}&#64;Overridepublic E current() {return castNonNull(current);}&#64;Overridepublic boolean moveNext() {try {final String[] strings &#61; reader.readNext();if (strings &#61;&#61; null) {current &#61; null;reader.close();return false;}current &#61; rowConverter.convertRow(strings);return true;} catch (IOException e) {throw new RuntimeException(e);}}static class ArrayRowConverter extends RowConverter<&#64;Nullable Object[]> {/*** Field types. List must not be null, but any element may be null.*/private final List<RelDataType> fieldTypes;private final ImmutableIntList fields;ArrayRowConverter(List<RelDataType> fieldTypes, List<Integer> fields) {this.fieldTypes &#61; ImmutableNullableList.copyOf(fieldTypes);this.fields &#61; ImmutableIntList.copyOf(fields);}&#64;Overridepublic &#64;Nullable Object[] convertRow(&#64;Nullable String[] strings) {return convertNormalRow(strings);}public &#64;Nullable Object[] convertNormalRow(&#64;Nullable String[] strings) {final &#64;Nullable Object[] objects &#61; new Object[fields.size()];for (int i &#61; 0; i < fields.size(); i&#43;&#43;) {int field &#61; fields.get(i);objects[i] &#61; convert(fieldTypes.get(field), strings[field]);}return objects;}}&#64;Overridepublic void reset() {throw new UnsupportedOperationException();}&#64;Overridepublic void close() {try {reader.close();} catch (IOException e) {throw new RuntimeException("Error closing CSV reader", e);}}
}

Pom.xml

<dependencies><dependency><groupId>org.apache.calcite</groupId><artifactId>calcite-core</artifactId><version>1.30.0</version></dependency><dependency><groupId>org.apache.calcite</groupId><artifactId>calcite-file</artifactId><version>1.30.0</version></dependency><dependency><groupId>net.sf.opencsv</groupId><artifactId>opencsv</artifactId><version>2.3</version></dependency></dependencies>

测试

数据格式

DEPTNO:int,NAME:string
10,“Sales”
20,“Marketing”
30,“Accounts”

结果
在这里插入图片描述


推荐阅读
  • spring boot使用jetty无法启动 ... [详细]
  • Python3爬虫入门:pyspider的基本使用[python爬虫入门]
    Python学习网有大量免费的Python入门教程,欢迎大家来学习。本文主要通过爬取去哪儿网的旅游攻略来给大家介绍pyspid ... [详细]
  • Gradle 是 Android Studio 中默认的构建工具,了解其基本配置对于开发效率的提升至关重要。本文将详细介绍如何在 Gradle 中定义和使用共享变量,以确保项目的一致性和可维护性。 ... [详细]
  • 本文介绍了Tomcat的基本操作,包括启动、关闭及首次访问的方法,并详细讲解了如何在IDEA中创建Web项目,配置Servlet及其映射,以及如何将项目部署到Tomcat。 ... [详细]
  • Hibernate全自动全映射ORM框架,旨在消除sql,是一个持久层的ORM框架1)、基础概念DAO(DataAccessorOb ... [详细]
  • 在一系列的学习与实践后,Jsoup学习笔记系列即将进入尾声。本文详细介绍了如何使用Jsoup实现从Saz文件到Csv格式的数据解析功能。未来,计划将此功能进一步封装,开发成具有用户界面的独立应用程序,以增强其实用性和便捷性。对于希望深入掌握Jsoup技术的开发者,本文提供了宝贵的参考和实践案例。 ... [详细]
  • ssm关键步骤(2)
    spring:1.pom.xml中的文件配置org.springframework ... [详细]
  • 本文详细介绍如何在SSM(Spring + Spring MVC + MyBatis)框架中实现分页功能。包括分页的基本概念、数据准备、前端分页栏的设计与实现、后端分页逻辑的编写以及最终的测试步骤。 ... [详细]
  • ArcBlock 发布 ABT 节点 1.0.31 版本更新
    2020年11月9日,ArcBlock 区块链基础平台发布了 ABT 节点开发平台的1.0.31版本更新,此次更新带来了多项功能增强与性能优化。 ... [详细]
  • Asynchronous JavaScript and XML (AJAX) 的流行很大程度上得益于 Google 在其产品如 Google Suggest 和 Google Maps 中的应用。本文将深入探讨 AJAX 在 .NET 环境下的工作原理及其实现方法。 ... [详细]
  • 本文详细介绍了如何在Mac操作系统中为IntelliJ IDEA配置更高的内存限制,以提高开发效率和性能。 ... [详细]
  • Maven + Spring + MyBatis + MySQL 环境搭建与实例解析
    本文详细介绍如何使用MySQL数据库进行环境搭建,包括创建数据库表并插入示例数据。随后,逐步指导如何配置Maven项目,整合Spring框架与MyBatis,实现高效的数据访问。 ... [详细]
  • 本文详细介绍了 `org.apache.tinkerpop.gremlin.structure.VertexProperty` 类中的 `key()` 方法,并提供了多个实际应用的代码示例。通过这些示例,读者可以更好地理解该方法在图数据库操作中的具体用途。 ... [详细]
  • 这篇文章主要讲解了AndroidPhoneWindowManager监听屏幕右侧向左滑动实现返回功能的实现,内容清晰明了,对此有兴趣的小伙伴可以学习一下,相信大 ... [详细]
  • 近来有一个需求,是需要在androidjava基础库中插入一些log信息,完成这个工作需要的前置条件有编译好的android源码具体android源码如何编译,这 ... [详细]
author-avatar
帅气zxc_925
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有