├── LICENSE
├── README.md
├── pom.xml
└── src
├── main
├── java
│ └── pers
│ │ └── shezm
│ │ └── calcite
│ │ ├── csv
│ │ ├── CsvEnumerator.java
│ │ ├── CsvSchema.java
│ │ ├── CsvSchemaFactory.java
│ │ └── CsvTable.java
│ │ ├── optimizer
│ │ ├── converter
│ │ │ ├── CSVFilterConverter.java
│ │ │ ├── CSVNewProjectConverter.java
│ │ │ ├── CSVNewProjectRule.java
│ │ │ ├── CSVProjectConverter.java
│ │ │ └── CSVTableScanConverter.java
│ │ ├── cost
│ │ │ ├── CSVRelMdDistinctRowCount.java
│ │ │ ├── CSVRelMdRowCount.java
│ │ │ └── DefaultRelMetadataProvider.java
│ │ └── reloperators
│ │ │ ├── CSVFilter.java
│ │ │ ├── CSVProject.java
│ │ │ ├── CSVRel.java
│ │ │ ├── CSVTableScan.java
│ │ │ └── NewCsvProject.java
│ │ ├── test
│ │ ├── Test1.java
│ │ ├── Test2.java
│ │ ├── Test3.java
│ │ ├── Test4.java
│ │ ├── Test5.java
│ │ └── Test6.java
│ │ └── utils
│ │ └── CalciteUtil.java
└── resources
│ ├── TEST01.csv
│ ├── TEST02.csv
│ └── model.json
└── test
└── java
└── org
└── example
└── AppTest.java
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 shezm
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # calcite-demo
2 | calcite的相关练习代码,包含CSV适配器,使用CSV适配器来进行SQL查询。SQL的parse和validate,以及RBO和CBO的使用。
3 | # 项目结构
4 | - pers.shezm.calcite
5 | - - csv : csv适配器相关内容
6 | - - optimizer : 优化器相关内容,包含自定义的 RelNode,Converter,以及Cost计算相关内容
7 | - - test : 主要演示的地方,包含各种代码演示
8 | - - utils : 工具类
9 | # 关联博客
10 |
11 | [深入浅出Calcite与SQL CBO(Cost-Based Optimizer)优化](https://zhuanlan.zhihu.com/p/248796415)
12 |
13 | [Hive使用Calcite CBO优化流程及SQL优化实战](https://zhuanlan.zhihu.com/p/258081600)
14 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 | 4.0.0
6 |
7 | org.example
8 | calcite-demo
9 | 1.0-SNAPSHOT
10 |
11 | calcite-demo
12 |
13 | http://www.example.com
14 |
15 |
16 | UTF-8
17 | 1.8
18 | 1.8
19 |
20 |
21 |
22 |
23 |
24 | org.apache.calcite
25 | calcite-core
26 | 1.22.0
27 |
28 |
29 | com.alibaba
30 | fastjson
31 | 1.2.54
32 |
33 |
34 |
35 | com.google.guava
36 | guava
37 | 24.1-jre
38 |
39 |
40 |
41 | org.slf4j
42 | slf4j-log4j12
43 | 1.7.26
44 |
45 |
46 |
47 | junit
48 | junit
49 | 4.11
50 | test
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | maven-clean-plugin
60 | 3.1.0
61 |
62 |
63 |
64 | maven-resources-plugin
65 | 3.0.2
66 |
67 |
68 | maven-compiler-plugin
69 | 3.8.0
70 |
71 |
72 | maven-surefire-plugin
73 | 2.22.1
74 |
75 |
76 | maven-jar-plugin
77 | 3.0.2
78 |
79 |
80 | maven-install-plugin
81 | 2.5.2
82 |
83 |
84 | maven-deploy-plugin
85 | 2.8.2
86 |
87 |
88 |
89 | maven-site-plugin
90 | 3.7.1
91 |
92 |
93 | maven-project-info-reports-plugin
94 | 3.0.0
95 |
96 |
97 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/src/main/java/pers/shezm/calcite/csv/CsvEnumerator.java:
--------------------------------------------------------------------------------
1 | package pers.shezm.calcite.csv;
2 |
3 | import org.apache.calcite.linq4j.Enumerator;
4 | import org.apache.calcite.util.Source;
5 |
6 | import java.io.BufferedReader;
7 | import java.io.IOException;
8 |
9 | public class CsvEnumerator implements Enumerator {
10 |
11 | private E current;
12 |
13 | private BufferedReader br;
14 |
15 | public CsvEnumerator(Source source) {
16 | try {
17 | this.br = new BufferedReader(source.reader());
18 | this.br.readLine();
19 | } catch (IOException e) {
20 | e.printStackTrace();
21 | }
22 |
23 | }
24 |
25 | @Override
26 | public E current() {
27 | return current;
28 | }
29 |
30 | @Override
31 | public boolean moveNext() {
32 | try {
33 | String line = br.readLine();
34 | if (line == null) {
35 | return false;
36 | }
37 |
38 | current = (E) line.split(","); // 如果是多列,这里要多个值
39 | } catch (IOException e) {
40 | e.printStackTrace();
41 | return false;
42 | }
43 | return true;
44 | }
45 |
46 | /**
47 | * 出现异常走这里
48 | */
49 | @Override
50 | public void reset() {
51 | System.out.println("报错了兄弟,不支持此操作");
52 | }
53 |
54 | /**
55 | * InputStream流在这里关闭
56 | */
57 | @Override
58 | public void close() {
59 |
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/main/java/pers/shezm/calcite/csv/CsvSchema.java:
--------------------------------------------------------------------------------
1 | package pers.shezm.calcite.csv;
2 |
3 | import com.google.common.collect.ImmutableMap;
4 | import com.google.common.io.Resources;
5 | import org.apache.calcite.schema.Table;
6 | import org.apache.calcite.schema.impl.AbstractSchema;
7 | import org.apache.calcite.util.Source;
8 | import org.apache.calcite.util.Sources;
9 |
10 | import java.net.URL;
11 | import java.util.Map;
12 |
13 | public class CsvSchema extends AbstractSchema {
14 | private Map tableMap;
15 | private String dataFiles;
16 |
17 | public CsvSchema(String dataFile) {
18 | this.dataFiles = dataFile;
19 | }
20 |
21 | @Override
22 | protected Map getTableMap() {
23 | final ImmutableMap.Builder builder = ImmutableMap.builder();
24 | for (String dataFile : dataFiles.split(",")) {
25 | URL url = Resources.getResource(dataFile);
26 | Source source = Sources.of(url);
27 | builder.put(dataFile.split("\\.")[0], new CsvTable(source));
28 | }
29 | // 一个数据库有多个表名,这里初始化,大小写要注意了
30 | tableMap = builder.build();
31 |
32 | return tableMap;
33 | }
34 | }
--------------------------------------------------------------------------------
/src/main/java/pers/shezm/calcite/csv/CsvSchemaFactory.java:
--------------------------------------------------------------------------------
1 | package pers.shezm.calcite.csv;
2 |
3 | import org.apache.calcite.schema.Schema;
4 | import org.apache.calcite.schema.SchemaFactory;
5 | import org.apache.calcite.schema.SchemaPlus;
6 |
7 | import java.util.Map;
8 |
9 | public class CsvSchemaFactory implements SchemaFactory {
10 |
11 | /**
12 | * parentSchema 他的父节点,一般为root
13 | * name 数据库的名字,它在model中定义的
14 | * operand 也是在mode中定义的,是Map类型,用于传入自定义参数。
15 | */
16 | @Override
17 | public Schema create(SchemaPlus parentSchema, String name, Map operand) {
18 | return new CsvSchema(String.valueOf(operand.get("dataFile")));
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/pers/shezm/calcite/csv/CsvTable.java:
--------------------------------------------------------------------------------
1 | package pers.shezm.calcite.csv;
2 |
3 | import com.google.common.collect.Lists;
4 | import org.apache.calcite.DataContext;
5 | import org.apache.calcite.linq4j.AbstractEnumerable;
6 | import org.apache.calcite.linq4j.Enumerable;
7 | import org.apache.calcite.linq4j.Enumerator;
8 | import org.apache.calcite.rel.type.RelDataType;
9 | import org.apache.calcite.rel.type.RelDataTypeFactory;
10 | import org.apache.calcite.schema.ScannableTable;
11 | import org.apache.calcite.schema.impl.AbstractTable;
12 | import org.apache.calcite.sql.type.SqlTypeName;
13 | import org.apache.calcite.util.Pair;
14 | import org.apache.calcite.util.Source;
15 |
16 | import java.io.BufferedReader;
17 | import java.io.FileNotFoundException;
18 | import java.io.FileReader;
19 | import java.io.IOException;
20 | import java.util.List;
21 |
22 | public class CsvTable extends AbstractTable implements ScannableTable {
23 | private Source source;
24 |
25 | public CsvTable(Source source) {
26 | this.source = source;
27 | }
28 |
29 | /**
30 | * 获取字段类型
31 | */
32 | @Override
33 | public RelDataType getRowType(RelDataTypeFactory relDataTypeFactory) {
34 | RelDataTypeFactory typeFactory = relDataTypeFactory;
35 |
36 | // JavaTypeFactory typeFactory = (JavaTypeFactory)relDataTypeFactory;
37 |
38 | List names = Lists.newLinkedList();
39 | List types = Lists.newLinkedList();
40 |
41 | try {
42 | BufferedReader reader = new BufferedReader(new FileReader(source.file()));
43 | String line = reader.readLine();
44 | List lines = Lists.newArrayList(line.split(","));
45 | lines.forEach(column -> {
46 | String name = column.split(":")[0];
47 | String type = column.split(":")[1];
48 | names.add(name);
49 | types.add(typeFactory.createSqlType(SqlTypeName.get(type)));
50 | });
51 |
52 | } catch (FileNotFoundException e) {
53 | e.printStackTrace();
54 | } catch (IOException e) {
55 | e.printStackTrace();
56 | }
57 |
58 | return typeFactory.createStructType(Pair.zip(names, types));
59 | }
60 |
61 | @Override
62 | public Enumerable