diff --git a/README.md b/README.md index 2b4263d8a..ebb4eb233 100644 --- a/README.md +++ b/README.md @@ -554,12 +554,24 @@ targetName是目标名字,它可以是数据源的名字或者集群的名字 +##### 规律1:与逻辑库名称路径一致的物理表 + +用于 + 1. schema上的配置默认目标 2. 在代理架构下即mycat proxy没有设置成自动返回show语句的情况(比如使用命令配置),则配置的默认命令指向的默认目标 -此默认目标应该有非分片表与分片表的名字的物理库 +此默认目标应该有非分片表与分片表的名字的物理库,此物理库具有提供查询逻辑表信息的作用(因为表名,库名与逻辑表一致),无需经过sql改写即可查询逻辑表的数据 + + + +##### 规律2:若有全局表,则每一个跨服务器的分片建议建立一个相同名称路径的物理表 + +这样的好处是涉及分片表与全局表的sql无需复杂分析,若判断sql涉及一个分片的分片表和任意多个全局表,只需改写分片表部分即可查询 + + diff --git a/autohandler/pom.xml b/autohandler/pom.xml index 962173018..3d86ccbda 100644 --- a/autohandler/pom.xml +++ b/autohandler/pom.xml @@ -5,7 +5,7 @@ parent io.mycat - 1.07-SNAPSHOT + 1.08-SNAPSHOT 4.0.0 diff --git a/booster/pom.xml b/booster/pom.xml index cb34a12ab..57706ec78 100644 --- a/booster/pom.xml +++ b/booster/pom.xml @@ -5,7 +5,7 @@ parent io.mycat - 1.07-SNAPSHOT + 1.08-SNAPSHOT 4.0.0 @@ -21,17 +21,17 @@ io.mycat config - 1.07-SNAPSHOT + 1.08-SNAPSHOT io.mycat common - 1.07-SNAPSHOT + 1.08-SNAPSHOT io.mycat plug - 1.07-SNAPSHOT + 1.08-SNAPSHOT compile diff --git a/common/pom.xml b/common/pom.xml index f3ce68b42..a3597806a 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -5,7 +5,7 @@ parent io.mycat - 1.07-SNAPSHOT + 1.08-SNAPSHOT 4.0.0 @@ -15,7 +15,7 @@ io.mycat config - 1.07-SNAPSHOT + 1.08-SNAPSHOT diff --git a/config/pom.xml b/config/pom.xml index 1897aff62..41e021b01 100644 --- a/config/pom.xml +++ b/config/pom.xml @@ -5,7 +5,7 @@ io.mycat parent - 1.07-SNAPSHOT + 1.08-SNAPSHOT 4.0.0 diff --git a/datasource/pom.xml b/datasource/pom.xml index fe0629e20..7abe75654 100644 --- a/datasource/pom.xml +++ b/datasource/pom.xml @@ -5,7 +5,7 @@ parent io.mycat - 1.07-SNAPSHOT + 1.08-SNAPSHOT 4.0.0 @@ -20,22 +20,22 @@ io.mycat config - 1.07-SNAPSHOT + 1.08-SNAPSHOT io.mycat common - 1.07-SNAPSHOT + 1.08-SNAPSHOT io.mycat plug - 1.07-SNAPSHOT + 1.08-SNAPSHOT io.mycat replica - 1.07-SNAPSHOT + 1.08-SNAPSHOT com.zaxxer diff --git a/example/pom.xml b/example/pom.xml index f1c301887..41536d7c7 100644 --- a/example/pom.xml +++ b/example/pom.xml @@ -5,7 +5,7 @@ parent io.mycat - 1.07-SNAPSHOT + 1.08-SNAPSHOT 4.0.0 @@ -15,7 +15,7 @@ io.mycat mycat2 - 1.07-SNAPSHOT + 1.08-SNAPSHOT diff --git a/example/src/test/resources/io/mycat/example/sharding/mycat.yml b/example/src/test/resources/io/mycat/example/sharding/mycat.yml index 6d363b644..2e1d17b0e 100644 --- a/example/src/test/resources/io/mycat/example/sharding/mycat.yml +++ b/example/src/test/resources/io/mycat/example/sharding/mycat.yml @@ -30,7 +30,7 @@ interceptors: [{ user: {ip: '.', password: '123456', username: root}, sqls:[ - {sql: 'SELECT COUNT(1) FROM db1.travelrecord',command: distributedQuery, cache: 'initialDelay = 1s,refreshInterval = 15s'} +# {sql: 'SELECT COUNT(1) FROM db1.travelrecord',command: distributedQuery, cache: 'initialDelay = 1s,refreshInterval = 15s'} ] }] datasource: @@ -82,7 +82,7 @@ server: maxPengdingLimit: 65535, #每个线程处理任务队列的最大长度 maxThread: 1000, minThread: 2, - timeUnit: SECONDS, + timeUnit: MINUTES, waitTaskTimeout: 5 #超时后将结束闲置的线程 } #负载均衡类型 BALANCE_ALL:所有数据源参与负载均衡 BALANCE_ALL_READ:所以非master数据源参与负载均衡 BALANCE_NONE:只有master(一个)参与负载 diff --git a/hbt/pom.xml b/hbt/pom.xml index 149c0bd72..abe0fe902 100644 --- a/hbt/pom.xml +++ b/hbt/pom.xml @@ -5,7 +5,7 @@ parent io.mycat - 1.07-SNAPSHOT + 1.08-SNAPSHOT 4.0.0 @@ -16,22 +16,22 @@ io.mycat common - 1.07-SNAPSHOT + 1.08-SNAPSHOT io.mycat plug - 1.07-SNAPSHOT + 1.08-SNAPSHOT io.mycat datasource - 1.07-SNAPSHOT + 1.08-SNAPSHOT io.mycat config - 1.07-SNAPSHOT + 1.08-SNAPSHOT com.alibaba.fastsql diff --git a/hbt/src/main/java/io/mycat/calcite/CalciteRunners.java b/hbt/src/main/java/io/mycat/calcite/CalciteRunners.java index 7cf701820..2109d12d8 100644 --- a/hbt/src/main/java/io/mycat/calcite/CalciteRunners.java +++ b/hbt/src/main/java/io/mycat/calcite/CalciteRunners.java @@ -19,12 +19,12 @@ import org.apache.calcite.rel.RelNode; import org.apache.calcite.rel.RelShuttleImpl; import org.apache.calcite.rel.core.TableScan; +import org.apache.calcite.rel.logical.LogicalUnion; import org.apache.calcite.runtime.ArrayBindable; import org.apache.calcite.sql.SqlNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.StringWriter; import java.util.*; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; @@ -47,8 +47,8 @@ public static RelNode compile(MycatCalcitePlanner planner, RelNode relNode, bool relNode = planner.pullUpUnion(relNode); relNode = planner.pushDownBySQL(relNode, forUpdate); return relNode; - }catch (Throwable e){ - LOGGER.error("",e); + } catch (Throwable e) { + LOGGER.error("", e); } return null; } @@ -76,6 +76,18 @@ public RelNode visit(TableScan scan) { final HepPlanner planner2 = new HepPlanner(hepProgramBuilder.build()); planner2.setRoot(relNode); relNode = planner2.findBestExp(); + + //check + relNode.accept(new RelShuttleImpl() { + @Override + public RelNode visit(LogicalUnion union) { + if (union.getInputs().size() > 2) { + throw new AssertionError("union input more 2"); + } + return super.visit(union); + } + }); + fork(calciteDataContext, map); ArrayBindable bindable1 = Interpreters.bindable(relNode); Enumerable bind = bindable1.bind(calciteDataContext); @@ -126,7 +138,7 @@ public Enumerator enumerator() { @Override @SneakyThrows public Enumerator enumerator() { - LOGGER.info("拉取数据"+v.getTargetName()+" sql:"+v.getSql()); + LOGGER.info("拉取数据" + v.getTargetName() + " sql:" + v.getSql()); return new MyCatResultSetEnumerator(cancelFlag, submit.get()); } }; @@ -135,4 +147,11 @@ public Enumerator enumerator() { } } } + + @SneakyThrows + public static RelNode compile(MycatCalcitePlanner planner, SqlNode sql, boolean forUpdate) { + SqlNode validate = planner.validate(sql); + RelNode relNode = planner.convert(validate); + return compile(planner, relNode, forUpdate); + } } \ No newline at end of file diff --git a/hbt/src/main/java/io/mycat/calcite/MycatCalciteSupport.java b/hbt/src/main/java/io/mycat/calcite/MycatCalciteSupport.java index 585804189..e7c3715ce 100644 --- a/hbt/src/main/java/io/mycat/calcite/MycatCalciteSupport.java +++ b/hbt/src/main/java/io/mycat/calcite/MycatCalciteSupport.java @@ -127,7 +127,7 @@ public RelBuilder create(RelOptCluster cluster, RelOptSchema schema) { .withRelBuilderFactory(relBuilderFactory).build(); public final SqlValidator.Config getValidatorConfig() { - return SqlValidator.Config.DEFAULT; + return SqlValidator.Config.DEFAULT.withSqlConformance(calciteConnectionConfig.conformance()); // .withSqlConformance(calciteConnectionConfig.conformance()); } // new SqlValidator.Config() { diff --git a/hbt/src/main/java/io/mycat/calcite/prepare/CalciteSqlValidator.java b/hbt/src/main/java/io/mycat/calcite/prepare/CalciteSqlValidator.java new file mode 100644 index 000000000..2e99b244d --- /dev/null +++ b/hbt/src/main/java/io/mycat/calcite/prepare/CalciteSqlValidator.java @@ -0,0 +1,32 @@ +package io.mycat.calcite.prepare; + +import org.apache.calcite.adapter.java.JavaTypeFactory; +import org.apache.calcite.prepare.CalciteCatalogReader; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.sql.SqlInsert; +import org.apache.calcite.sql.SqlOperatorTable; +import org.apache.calcite.sql.validate.SqlValidatorImpl; + +/** Validator. */ +class CalciteSqlValidator extends SqlValidatorImpl { + + CalciteSqlValidator(SqlOperatorTable opTab, + CalciteCatalogReader catalogReader, JavaTypeFactory typeFactory, + Config config) { + super(opTab, catalogReader, typeFactory, config); + } + + @Override protected RelDataType getLogicalSourceRowType( + RelDataType sourceRowType, SqlInsert insert) { + final RelDataType superType = + super.getLogicalSourceRowType(sourceRowType, insert); + return ((JavaTypeFactory) typeFactory).toSql(superType); + } + + @Override protected RelDataType getLogicalTargetRowType( + RelDataType targetRowType, SqlInsert insert) { + final RelDataType superType = + super.getLogicalTargetRowType(targetRowType, insert); + return ((JavaTypeFactory) typeFactory).toSql(superType); + } +} diff --git a/hbt/src/main/java/io/mycat/calcite/prepare/FastMycatCalciteSQLPrepareObject.java b/hbt/src/main/java/io/mycat/calcite/prepare/FastMycatCalciteSQLPrepareObject.java new file mode 100644 index 000000000..0efd2eaac --- /dev/null +++ b/hbt/src/main/java/io/mycat/calcite/prepare/FastMycatCalciteSQLPrepareObject.java @@ -0,0 +1,104 @@ +/** + * Copyright (C) <2019> + *

+ * This program is free software: you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + *

+ * You should have received a copy of the GNU General Public License along with this program. If + * not, see . + */ +package io.mycat.calcite.prepare; + +import io.mycat.PlanRunner; +import io.mycat.beans.mycat.MycatRowMetaData; +import io.mycat.upondb.MycatDBContext; +import lombok.Getter; +import org.apache.calcite.sql.SqlLiteral; +import org.apache.calcite.sql.SqlNode; +import org.apache.calcite.sql.dialect.MysqlSqlDialect; +import org.apache.calcite.sql.parser.SqlParserPos; +import org.apache.calcite.util.DateString; +import org.apache.calcite.util.TimeString; +import org.apache.calcite.util.TimestampString; + +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.List; + +/** + * @author Junwen Chen + **/ +@Getter +public class FastMycatCalciteSQLPrepareObject extends MycatSQLPrepareObject { + private final SqlNode sqlNode; + private boolean forUpdate; + private final MycatDBContext dataContext; + + public FastMycatCalciteSQLPrepareObject(Long id, String sql, SqlNode sqlNode, MycatRowMetaData parameterRowType, MycatRowMetaData resultSetRowType, boolean forUpdate, MycatDBContext dataContext) { + super(id,dataContext,sql,forUpdate); + this.sqlNode = sqlNode; + this.forUpdate = forUpdate; + this.dataContext = dataContext; + } + + @Override + public MycatRowMetaData prepareParams() { + return null; + } + + @Override + public MycatRowMetaData resultSetRowType() { + return null; + } + + @Override + public PlanRunner plan(List params) { + return new MycatSqlPlanner(this, sqlNode.toSqlString(MysqlSqlDialect.DEFAULT).getSql(),dataContext); + } + + public static SqlNode literal(Object value) { + SqlParserPos zero = SqlParserPos.ZERO; + SqlNode literal; + if (value == null) { + literal = SqlLiteral.createNull(zero); + } else if (value instanceof Boolean) { + literal = SqlLiteral.createBoolean((Boolean) value, zero); + } else if (value instanceof BigDecimal) { + literal = SqlLiteral.createExactNumeric(((BigDecimal) value).toPlainString(), zero); + } else if (value instanceof Number) { + literal = SqlLiteral.createExactNumeric(value.toString(), zero); + } else if (value instanceof String) { + literal = SqlLiteral.createCharString((String) value, zero); + } else if (value instanceof byte[]) { + literal = SqlLiteral.createBinaryString((byte[]) value, zero); + } else if (value instanceof LocalDate) { + LocalDate value1 = (LocalDate) value; + DateString dateString = new DateString(value1.getYear(), value1.getMonthValue(), value1.getDayOfMonth()); + literal = SqlLiteral.createDate(dateString, zero); + } else if (value instanceof LocalTime) { + LocalTime value1 = (LocalTime) value; + TimeString timeString = new TimeString(value1.getHour(), value1.getMinute(), value1.getSecond()); + literal = SqlLiteral.createTime(timeString, 64, zero); + } else if (value instanceof LocalDateTime) { + LocalDateTime value1 = (LocalDateTime) value; + TimestampString timeString = new TimestampString(value1.getYear(), value1.getMonthValue(), value1.getDayOfMonth(), value1.getHour(), value1.getMinute(), value1.getSecond()); + timeString = timeString.withNanos(value1.getNano()); + literal = SqlLiteral.createTimestamp(timeString, 64, zero); + } else { + throw new IllegalArgumentException("cannot convert " + value + + " (" + value.getClass() + ") to a constant"); + } + return literal; + } + + public boolean isForUpdate() { + return forUpdate; + } +} \ No newline at end of file diff --git a/hbt/src/main/java/io/mycat/calcite/prepare/MycatCalcitePlanner.java b/hbt/src/main/java/io/mycat/calcite/prepare/MycatCalcitePlanner.java index 29aca8655..3982b2880 100644 --- a/hbt/src/main/java/io/mycat/calcite/prepare/MycatCalcitePlanner.java +++ b/hbt/src/main/java/io/mycat/calcite/prepare/MycatCalcitePlanner.java @@ -21,7 +21,10 @@ import io.mycat.calcite.MycatRelBuilder; import io.mycat.calcite.rules.LimitPushRemoveRule; import io.mycat.calcite.rules.PushDownLogicTableRule; -import io.mycat.calcite.table.*; +import io.mycat.calcite.table.MycatPhysicalTable; +import io.mycat.calcite.table.MycatSQLTableScan; +import io.mycat.calcite.table.MycatTransientSQLTableScan; +import io.mycat.calcite.table.SingeTargetSQLTable; import io.mycat.upondb.MycatDBContext; import org.apache.calcite.adapter.enumerable.EnumerableConvention; import org.apache.calcite.interpreter.Bindables; @@ -33,34 +36,30 @@ import org.apache.calcite.plan.hep.HepProgramBuilder; import org.apache.calcite.plan.volcano.VolcanoPlanner; import org.apache.calcite.prepare.CalciteCatalogReader; -import org.apache.calcite.prepare.PlannerImpl; import org.apache.calcite.rel.RelHomogeneousShuttle; import org.apache.calcite.rel.RelNode; -import org.apache.calcite.rel.RelRoot; import org.apache.calcite.rel.RelShuttleImpl; import org.apache.calcite.rel.core.*; import org.apache.calcite.rel.logical.LogicalAggregate; import org.apache.calcite.rel.logical.LogicalUnion; import org.apache.calcite.rel.rules.*; -import org.apache.calcite.rel.type.RelDataType; import org.apache.calcite.rel.type.RelDataTypeFactory; import org.apache.calcite.rex.RexNode; import org.apache.calcite.schema.SchemaPlus; import org.apache.calcite.sql.SqlKind; -import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.SqlOperatorTable; -import org.apache.calcite.sql.parser.SqlParseException; import org.apache.calcite.sql.type.SqlTypeFamily; import org.apache.calcite.sql.validate.SqlValidatorCatalogReader; import org.apache.calcite.sql.validate.SqlValidatorImpl; import org.apache.calcite.sql.validate.SqlValidatorUtil; import org.apache.calcite.sql2rel.SqlToRelConverter; -import org.apache.calcite.tools.*; -import org.apache.calcite.util.Pair; +import org.apache.calcite.tools.Program; +import org.apache.calcite.tools.Programs; +import org.apache.calcite.tools.RelBuilder; +import org.apache.calcite.tools.RuleSets; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.Reader; import java.util.*; import java.util.function.Consumer; import java.util.function.Predicate; @@ -72,35 +71,19 @@ /** * @author Junwen Chen **/ -public class MycatCalcitePlanner implements Planner, RelOptTable.ViewExpander { +public class MycatCalcitePlanner extends PlannerImpl implements RelOptTable.ViewExpander { private final static Logger LOGGER = LoggerFactory.getLogger(MycatCalcitePlanner.class); private final SchemaPlus rootSchema; - private final PlannerImpl planner; - CalciteCatalogReader reader = null; + private MycatCalciteDataContext dataContext; public MycatCalcitePlanner(MycatCalciteDataContext dataContext) { + super(dataContext); this.dataContext = dataContext; this.rootSchema = dataContext.getRootSchema(); - this.planner = new PlannerImpl(dataContext); } - public CalciteCatalogReader createCalciteCatalogReader() { - if (reader == null) { - List path = Collections.emptyList(); - SchemaPlus defaultSchema = dataContext.getDefaultSchema(); - if (defaultSchema != null) { - String name = defaultSchema.getName(); - path = Collections.singletonList(name); - } - CalciteCatalogReader calciteCatalogReader = new CalciteCatalogReader( - CalciteSchema.from(rootSchema), - path, - MycatCalciteSupport.INSTANCE.TypeFactory, MycatCalciteSupport.INSTANCE.getCalciteConnectionConfig()); - reader = calciteCatalogReader; - } - return reader; - } + public MycatRelBuilder createRelBuilder(RelOptCluster cluster) { return (MycatRelBuilder) MycatCalciteSupport.INSTANCE.relBuilderFactory.create(cluster, createCalciteCatalogReader()); @@ -118,7 +101,7 @@ public SqlValidatorImpl getSqlValidator() { } public SqlToRelConverter createSqlToRelConverter() { - return new SqlToRelConverter(planner, getSqlValidator(), + return new SqlToRelConverter(this, getSqlValidator(), createCalciteCatalogReader(), newCluster(), MycatCalciteSupport.MycatStandardConvertletTable.INSTANCE, MycatCalciteSupport.INSTANCE.sqlToRelConverterConfig); } @@ -345,61 +328,6 @@ public RelOptCluster newCluster() { } - @Override - public RelRoot expandView(RelDataType rowType, String queryString, List schemaPath, List viewPath) { - return planner.expandView(rowType, queryString, schemaPath, viewPath); - } - - @Override - public SqlNode parse(Reader source) throws SqlParseException { - return planner.parse(source); - } - - @Override - public SqlNode validate(SqlNode sqlNode) throws ValidationException { - return planner.validate(sqlNode); - } - - @Override - public Pair validateAndGetType(SqlNode sqlNode) throws ValidationException { - return planner.validateAndGetType(sqlNode); - } - - @Override - public RelRoot rel(SqlNode sql) throws RelConversionException { - return planner.rel(sql); - } - - @Override - public RelNode convert(SqlNode sql) throws RelConversionException { - return planner.convert(sql); - } - - @Override - public RelDataTypeFactory getTypeFactory() { - return planner.getTypeFactory(); - } - - @Override - public RelNode transform(int ruleSetIndex, RelTraitSet requiredOutputTraits, RelNode rel) throws RelConversionException { - return planner.transform(ruleSetIndex, requiredOutputTraits, rel); - } - - @Override - public void reset() { - planner.reset(); - } - - @Override - public void close() { - planner.close(); - } - - @Override - public RelTraitSet getEmptyTraitSet() { - return planner.getEmptyTraitSet(); - } - public void convert(String sql) { } @@ -436,7 +364,7 @@ public RelNode convertToMycatRel(RelNode relNode) { public RelNode visit(TableScan scan) { MycatSQLTableScan unwrap = scan.getTable().unwrap(MycatSQLTableScan.class); if (unwrap != null) { - return unwrap.toRel(ViewExpanders.toRelContext(planner, MycatCalcitePlanner.this.newCluster()), scan.getTable()); + return unwrap.toRel(ViewExpanders.toRelContext(MycatCalcitePlanner.this, MycatCalcitePlanner.this.newCluster()), scan.getTable()); } return super.visit(scan); } @@ -448,7 +376,7 @@ public RelNode visit(TableScan scan) { static final ImmutableSet PULL_RULES = ImmutableSet.of( UnionEliminatorRule.INSTANCE, UnionMergeRule.INTERSECT_INSTANCE, - UnionMergeRule.INTERSECT_INSTANCE, + UnionMergeRule.INSTANCE, UnionMergeRule.MINUS_INSTANCE, UnionPullUpConstantsRule.INSTANCE, UnionToDistinctRule.INSTANCE, @@ -462,16 +390,21 @@ public RelNode visit(TableScan scan) { ProjectRemoveRule.INSTANCE, JoinUnionTransposeRule.LEFT_UNION, JoinUnionTransposeRule.RIGHT_UNION, - AggregateProjectMergeRule.INSTANCE,//该类有效 + AggregateProjectMergeRule.INSTANCE,// AggregateUnionTransposeRule.INSTANCE,//该实现可能有问题 AggregateUnionAggregateRule.INSTANCE, AggregateProjectMergeRule.INSTANCE, AggregateRemoveRule.INSTANCE, AggregateProjectPullUpConstantsRule.INSTANCE2, - ProjectSetOpTransposeRule.INSTANCE,//该实现可能有问题 + /** + * + * at org.apache.calcite.rel.rules.PushProjector.getAdjustments(PushProjector.java:572) + * at org.apache.calcite.rel.rules.ProjectSetOpTransposeRule.onMatch(ProjectSetOpTransposeRule.java:92) + */ +// ProjectSetOpTransposeRule.INSTANCE,//该实现可能有问题 ProjectSortTransposeRule.INSTANCE, AggregateCaseToFilterRule.INSTANCE, - AggregateFilterTransposeRule.INSTANCE, +// AggregateFilterTransposeRule.INSTANCE,#该改造产生有问题的group by字段 AggregateValuesRule.INSTANCE, //sort SortJoinCopyRule.INSTANCE, @@ -495,6 +428,7 @@ public RelNode pullUpUnion(RelNode relNode1) { } + private class ComputePushDownInfo { private RelNode bestExp1; private IdentityHashMap cache; diff --git a/hbt/src/main/java/io/mycat/calcite/prepare/MycatSqlPlanner.java b/hbt/src/main/java/io/mycat/calcite/prepare/MycatSqlPlanner.java index 31f38e5f9..1dabc3873 100644 --- a/hbt/src/main/java/io/mycat/calcite/prepare/MycatSqlPlanner.java +++ b/hbt/src/main/java/io/mycat/calcite/prepare/MycatSqlPlanner.java @@ -28,6 +28,7 @@ import org.apache.calcite.rel.RelShuttleImpl; import org.apache.calcite.rel.core.TableScan; import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.sql.SqlNode; import java.util.ArrayList; import java.util.List; @@ -49,7 +50,12 @@ public MycatSqlPlanner(MycatSQLPrepareObject prepare, String sql, MycatDBContext MycatCalcitePlanner planner = MycatCalciteSupport.INSTANCE.createPlanner(mycatCalciteDataContext); this.relNode = CalciteRunners.compile(planner, sql, prepare.isForUpdate()); } - + public MycatSqlPlanner(MycatSQLPrepareObject prepare, SqlNode sql, MycatDBContext uponDBContext) { + this.prepare = prepare; + this.mycatCalciteDataContext = MycatCalciteSupport.INSTANCE.create(uponDBContext); + MycatCalcitePlanner planner = MycatCalciteSupport.INSTANCE.createPlanner(mycatCalciteDataContext); + this.relNode = CalciteRunners.compile(planner, sql, prepare.isForUpdate()); + } public List explain() { RelDataType rowType = relNode.getRowType(); return Explains.explain(prepare.getSql(), diff --git a/hbt/src/main/java/io/mycat/calcite/prepare/PlannerImpl.java b/hbt/src/main/java/io/mycat/calcite/prepare/PlannerImpl.java new file mode 100644 index 000000000..185bb0948 --- /dev/null +++ b/hbt/src/main/java/io/mycat/calcite/prepare/PlannerImpl.java @@ -0,0 +1,398 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to you under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.mycat.calcite.prepare; + +import com.google.common.collect.ImmutableList; +import io.mycat.calcite.MycatCalciteDataContext; +import io.mycat.calcite.MycatCalciteSupport; +import org.apache.calcite.adapter.java.JavaTypeFactory; +import org.apache.calcite.config.CalciteConnectionConfig; +import org.apache.calcite.config.CalciteConnectionConfigImpl; +import org.apache.calcite.config.CalciteConnectionProperty; +import org.apache.calcite.config.CalciteSystemProperty; +import org.apache.calcite.jdbc.CalciteSchema; +import org.apache.calcite.jdbc.JavaTypeFactoryImpl; +import org.apache.calcite.plan.*; +import org.apache.calcite.plan.RelOptTable.ViewExpander; +import org.apache.calcite.plan.volcano.VolcanoPlanner; +import org.apache.calcite.prepare.CalciteCatalogReader; +import org.apache.calcite.rel.RelCollationTraitDef; +import org.apache.calcite.rel.RelNode; +import org.apache.calcite.rel.RelRoot; +import org.apache.calcite.rel.metadata.CachingRelMetadataProvider; +import org.apache.calcite.rel.type.RelDataType; +import org.apache.calcite.rel.type.RelDataTypeSystem; +import org.apache.calcite.rex.RexBuilder; +import org.apache.calcite.rex.RexExecutor; +import org.apache.calcite.runtime.Hook; +import org.apache.calcite.schema.SchemaPlus; +import org.apache.calcite.sql.SqlNode; +import org.apache.calcite.sql.SqlOperatorTable; +import org.apache.calcite.sql.parser.SqlParseException; +import org.apache.calcite.sql.parser.SqlParser; +import org.apache.calcite.sql.util.ChainedSqlOperatorTable; +import org.apache.calcite.sql.validate.SqlValidator; +import org.apache.calcite.sql2rel.RelDecorrelator; +import org.apache.calcite.sql2rel.SqlRexConvertletTable; +import org.apache.calcite.sql2rel.SqlToRelConverter; +import org.apache.calcite.tools.*; +import org.apache.calcite.util.Pair; + +import java.io.Reader; +import java.util.Collections; +import java.util.List; +import java.util.Properties; + +/** + * Implementation of {@link org.apache.calcite.tools.Planner}. + */ +public class PlannerImpl implements Planner, ViewExpander { + private static final SqlOperatorTable operatorTable; + private static final ImmutableList programs; + private static final RelOptCostFactory costFactory; + private static final Context context; + private static final CalciteConnectionConfig connectionConfig; + private final MycatCalciteDataContext config; + + CalciteCatalogReader reader = null; + /** + * Holds the trait definitions to be registered with planner. May be null. + */ + private static final ImmutableList traitDefs; + + private static final SqlParser.Config parserConfig; + private static final SqlValidator.Config sqlValidatorConfig; + private static final SqlToRelConverter.Config sqlToRelConverterConfig; + private static final SqlRexConvertletTable convertletTable; + + private State state; + + // set in STATE_1_RESET + private boolean open; + + // set in STATE_2_READY + private SchemaPlus defaultSchema; + private final static JavaTypeFactory typeFactory = MycatCalciteSupport.INSTANCE.TypeFactory; + private RelOptPlanner planner; + private final static RexExecutor executor; + + // set in STATE_4_VALIDATE + private SqlValidator validator; + private SqlNode validatedSqlNode; + + // set in STATE_5_CONVERT + private RelRoot root; + + static { + FrameworkConfig frameworkConfig = MycatCalciteSupport.INSTANCE.config; + costFactory = frameworkConfig.getCostFactory(); + operatorTable = frameworkConfig.getOperatorTable(); + programs = frameworkConfig.getPrograms(); + parserConfig = frameworkConfig.getParserConfig(); + sqlValidatorConfig = frameworkConfig.getSqlValidatorConfig(); + sqlToRelConverterConfig = frameworkConfig.getSqlToRelConverterConfig(); + traitDefs = frameworkConfig.getTraitDefs(); + convertletTable = frameworkConfig.getConvertletTable(); + executor = frameworkConfig.getExecutor(); + context = frameworkConfig.getContext(); + connectionConfig = MycatCalciteSupport.INSTANCE.calciteConnectionConfig; + } + + /** + * Creates a planner. Not a public API; call + * {@link org.apache.calcite.tools.Frameworks#getPlanner} instead. + */ + public PlannerImpl(MycatCalciteDataContext config) { + defaultSchema = config.getDefaultSchema(); + this.config = config; + this.state = State.STATE_0_CLOSED; + reset(); + } + + /** + * Gets a user defined config and appends default connection values + */ +// private CalciteConnectionConfig connConfig() { +// +// return config; +// } + + /** + * Makes sure that the state is at least the given state. + */ + private void ensure(State state) { + + } + + public RelTraitSet getEmptyTraitSet() { + return planner.emptyTraitSet(); + } + + public void close() { + open = false; + state = State.STATE_0_CLOSED; + } + + public void reset() { + ensure(State.STATE_0_CLOSED); + open = true; + state = State.STATE_1_RESET; + } + + private void ready() { + switch (state) { + case STATE_0_CLOSED: + reset(); + } + ensure(State.STATE_1_RESET); + planner = new VolcanoPlanner(costFactory, context); + RelOptUtil.registerDefaultRules(planner, + connectionConfig.materializationsEnabled(), + Hook.ENABLE_BINDABLE.get(false)); + planner.setExecutor(executor); + + state = State.STATE_2_READY; + + // If user specify own traitDef, instead of default default trait, + // register the trait def specified in traitDefs. + if (this.traitDefs == null) { + planner.addRelTraitDef(ConventionTraitDef.INSTANCE); + if (CalciteSystemProperty.ENABLE_COLLATION_TRAIT.value()) { + planner.addRelTraitDef(RelCollationTraitDef.INSTANCE); + } + } else { + for (RelTraitDef def : this.traitDefs) { + planner.addRelTraitDef(def); + } + } + } + + public SqlNode parse(final Reader reader) throws SqlParseException { + switch (state) { + case STATE_0_CLOSED: + case STATE_1_RESET: + ready(); + } + ensure(State.STATE_2_READY); + SqlParser parser = SqlParser.create(reader, parserConfig); + SqlNode sqlNode = parser.parseStmt(); + state = State.STATE_3_PARSED; + return sqlNode; + } + + public SqlNode validate(SqlNode sqlNode) throws ValidationException { + ensure(State.STATE_3_PARSED); + this.validator = createSqlValidator(createCatalogReader()); + try { + validatedSqlNode = validator.validate(sqlNode); + } catch (RuntimeException e) { + throw new ValidationException(e); + } + state = State.STATE_4_VALIDATED; + return validatedSqlNode; + } + + public Pair validateAndGetType(SqlNode sqlNode) + throws ValidationException { + final SqlNode validatedNode = this.validate(sqlNode); + final RelDataType type = + this.validator.getValidatedNodeType(validatedNode); + return Pair.of(validatedNode, type); + } + + @SuppressWarnings("deprecation") + public final RelNode convert(SqlNode sql) { + return rel(sql).rel; + } + + public RelRoot rel(SqlNode sql) { + ensure(State.STATE_4_VALIDATED); + assert validatedSqlNode != null; + final RexBuilder rexBuilder = createRexBuilder(); + final RelOptCluster cluster = RelOptCluster.create(planner, rexBuilder); + final SqlToRelConverter.Config config = SqlToRelConverter.configBuilder() + .withConfig(sqlToRelConverterConfig) + .withTrimUnusedFields(false) + .build(); + final SqlToRelConverter sqlToRelConverter = + new SqlToRelConverter(this, validator, + createCatalogReader(), cluster, convertletTable, config); + root = + sqlToRelConverter.convertQuery(validatedSqlNode, false, true); + root = root.withRel(sqlToRelConverter.flattenTypes(root.rel, true)); + final RelBuilder relBuilder = + config.getRelBuilderFactory().create(cluster, null); + root = root.withRel( + RelDecorrelator.decorrelateQuery(root.rel, relBuilder)); + state = State.STATE_5_CONVERTED; + return root; + } + + + /** + * @deprecated Now {@link PlannerImpl} implements {@link ViewExpander} + * directly. + */ + @Deprecated + public class ViewExpanderImpl implements ViewExpander { + ViewExpanderImpl() { + } + + public RelRoot expandView(RelDataType rowType, String queryString, + List schemaPath, List viewPath) { + return PlannerImpl.this.expandView(rowType, queryString, schemaPath, + viewPath); + } + } + + @Override + public RelRoot expandView(RelDataType rowType, String queryString, + List schemaPath, List viewPath) { + if (planner == null) { + ready(); + } + SqlParser parser = SqlParser.create(queryString, parserConfig); + SqlNode sqlNode; + try { + sqlNode = parser.parseQuery(); + } catch (SqlParseException e) { + throw new RuntimeException("parse failed", e); + } + + final CalciteCatalogReader catalogReader = + createCatalogReader().withSchemaPath(schemaPath); + final SqlValidator validator = createSqlValidator(catalogReader); + + final RexBuilder rexBuilder = createRexBuilder(); + final RelOptCluster cluster = RelOptCluster.create(planner, rexBuilder); + final SqlToRelConverter.Config config = SqlToRelConverter + .configBuilder() + .withConfig(sqlToRelConverterConfig) + .withTrimUnusedFields(false) + .build(); + final SqlToRelConverter sqlToRelConverter = + new SqlToRelConverter(this, validator, + catalogReader, cluster, convertletTable, config); + + final RelRoot root = + sqlToRelConverter.convertQuery(sqlNode, true, false); + final RelRoot root2 = + root.withRel(sqlToRelConverter.flattenTypes(root.rel, true)); + final RelBuilder relBuilder = + config.getRelBuilderFactory().create(cluster, null); + return root2.withRel( + RelDecorrelator.decorrelateQuery(root.rel, relBuilder)); + } + + // CalciteCatalogReader is stateless; no need to store one + public CalciteCatalogReader createCatalogReader() { + return createCalciteCatalogReader(); + } + public CalciteCatalogReader createCalciteCatalogReader() { + if (reader == null) { + List path = Collections.emptyList(); + if (defaultSchema != null) { + String name = defaultSchema.getName(); + path = Collections.singletonList(name); + } + reader = new CalciteCatalogReader( + CalciteSchema.from(config.getRootSchema()), + path, + MycatCalciteSupport.INSTANCE.TypeFactory, MycatCalciteSupport.INSTANCE.getCalciteConnectionConfig()); + } + return reader; + } + private SqlValidator createSqlValidator(CalciteCatalogReader catalogReader) { + final SqlOperatorTable opTab = + ChainedSqlOperatorTable.of(operatorTable, catalogReader); + return new CalciteSqlValidator(opTab, + catalogReader, + typeFactory, + sqlValidatorConfig + .withDefaultNullCollation(connectionConfig.defaultNullCollation()) + .withLenientOperatorLookup(connectionConfig.lenientOperatorLookup()) + .withSqlConformance(connectionConfig.conformance()) + .withIdentifierExpansion(true)); + } + + private static SchemaPlus rootSchema(SchemaPlus schema) { + for (; ; ) { + if (schema.getParentSchema() == null) { + return schema; + } + schema = schema.getParentSchema(); + } + } + + // RexBuilder is stateless; no need to store one + private RexBuilder createRexBuilder() { + return new RexBuilder(typeFactory); + } + + public JavaTypeFactory getTypeFactory() { + return typeFactory; + } + + public RelNode transform(int ruleSetIndex, RelTraitSet requiredOutputTraits, + RelNode rel) { + ensure(State.STATE_5_CONVERTED); + rel.getCluster().setMetadataProvider( + new CachingRelMetadataProvider( + rel.getCluster().getMetadataProvider(), + rel.getCluster().getPlanner())); + Program program = programs.get(ruleSetIndex); + return program.run(planner, rel, requiredOutputTraits, ImmutableList.of(), + ImmutableList.of()); + } + + /** + * Stage of a statement in the query-preparation lifecycle. + */ + private enum State { + STATE_0_CLOSED { + @Override + void from(PlannerImpl planner) { + planner.close(); + } + }, + STATE_1_RESET { + @Override + void from(PlannerImpl planner) { + planner.ensure(STATE_0_CLOSED); + planner.reset(); + } + }, + STATE_2_READY { + @Override + void from(PlannerImpl planner) { + STATE_1_RESET.from(planner); + planner.ready(); + } + }, + STATE_3_PARSED, + STATE_4_VALIDATED, + STATE_5_CONVERTED; + + /** + * Moves planner's state to this state. This must be a higher state. + */ + void from(PlannerImpl planner) { + throw new IllegalArgumentException("cannot move from " + planner.state + + " to " + this); + } + } +} diff --git a/hbt/src/main/java/io/mycat/calcite/resultset/EnumeratorRowIterator.java b/hbt/src/main/java/io/mycat/calcite/resultset/EnumeratorRowIterator.java index 3b3898846..11181d83c 100644 --- a/hbt/src/main/java/io/mycat/calcite/resultset/EnumeratorRowIterator.java +++ b/hbt/src/main/java/io/mycat/calcite/resultset/EnumeratorRowIterator.java @@ -4,6 +4,9 @@ import io.mycat.beans.mycat.MycatRowMetaData; import org.apache.calcite.linq4j.Enumerator; +import java.sql.Date; +import java.sql.Timestamp; + /** * @author chen junwen */ @@ -31,9 +34,28 @@ public boolean next() { } } + @Override + public Date getDate(int columnIndex) { + Object o = getObject(columnIndex); + if (wasNull) return null; + if (o instanceof Integer) { + return new Date((Integer) o); + } + return (Date) o; + } + @Override public void close() { iterator.close(); } + @Override + public Timestamp getTimestamp(int columnIndex) { + Object o = getObject(columnIndex); + if (wasNull) return null; + if (o instanceof Long) { + return new Timestamp((Long) (o)); + } + return (Timestamp) o; + } } \ No newline at end of file diff --git a/hbt/src/main/java/io/mycat/calcite/rules/StreamUnionRule.java b/hbt/src/main/java/io/mycat/calcite/rules/StreamUnionRule.java index e379401de..4cc500c54 100644 --- a/hbt/src/main/java/io/mycat/calcite/rules/StreamUnionRule.java +++ b/hbt/src/main/java/io/mycat/calcite/rules/StreamUnionRule.java @@ -41,7 +41,7 @@ public class StreamUnionRule extends RelOptRule { public static final StreamUnionRule INSTANCE = new StreamUnionRule(); public StreamUnionRule() { - super(operandJ(Union.class, null, input -> input.getInputs().size() > 2, any()), "UnionRule"); + super(operandJ(Union.class, null, input -> input.getInputs().size() >= 2, any()), "UnionRule"); } diff --git a/hbt/src/main/java/io/mycat/upondb/MycatDBSharedServerImpl.java b/hbt/src/main/java/io/mycat/upondb/MycatDBSharedServerImpl.java index 66e939ea3..fae6d10f9 100644 --- a/hbt/src/main/java/io/mycat/upondb/MycatDBSharedServerImpl.java +++ b/hbt/src/main/java/io/mycat/upondb/MycatDBSharedServerImpl.java @@ -416,15 +416,7 @@ private MycatSQLPrepareObject complieQuery(String sql, Long id, SQLStatement MycatCalciteMySqlNodeVisitor calciteMySqlNodeVisitor = new MycatCalciteMySqlNodeVisitor(); sqlStatement.accept(calciteMySqlNodeVisitor); SqlNode sqlNode = calciteMySqlNodeVisitor.getSqlNode(); - MycatCalcitePlanner planner = MycatCalciteSupport.INSTANCE.createPlanner(dataContext); - SqlValidatorImpl sqlValidator = planner.getSqlValidator(); - sqlNode = sqlValidator.validate(sqlNode); - MycatRowMetaData parameterRowType = null; - if (id != null) { - parameterRowType = new CalciteRowMetaData(sqlValidator.getParameterRowType(sqlNode).getFieldList()); - } - MycatRowMetaData resultRowType = new CalciteRowMetaData(sqlValidator.getValidatedNodeType(sqlNode).getFieldList()); - return new MycatCalciteSQLPrepareObject(id, sql, sqlNode, parameterRowType, resultRowType, forUpdate, dataContext); + return new FastMycatCalciteSQLPrepareObject(id, sql, sqlNode, null, null, forUpdate, dataContext); } diff --git a/hbt/src/main/java/io/mycat/upondb/MysqlFunctions.java b/hbt/src/main/java/io/mycat/upondb/MysqlFunctions.java index e57b6d1ef..0dee64979 100644 --- a/hbt/src/main/java/io/mycat/upondb/MysqlFunctions.java +++ b/hbt/src/main/java/io/mycat/upondb/MysqlFunctions.java @@ -1,16 +1,24 @@ package io.mycat.upondb; +import com.alibaba.fastsql.sql.ast.expr.SQLDateExpr; +import com.alibaba.fastsql.sql.ast.expr.SQLDateTimeExpr; +import com.google.common.collect.ImmutableSet; import io.mycat.plug.sequence.SequenceGenerator; import io.mycat.util.MySQLFunction; import io.mycat.util.SQLContext; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.Date; +import java.util.Set; +import java.util.TimeZone; import java.util.function.Supplier; public class MysqlFunctions { public static final MySQLFunction next_value_for = new MySQLFunction() { @Override - public String getFunctionName() { - return "next_value_for"; + public Set getFunctionNames() { + return ImmutableSet.of( "next_value_for"); } @Override @@ -29,8 +37,8 @@ public Object eval(SQLContext context, Object[] args) { public static final MySQLFunction last_insert_id = new MySQLFunction() { @Override - public String getFunctionName() { - return "last_insert_id"; + public Set getFunctionNames() { + return ImmutableSet.of("last_insert_id"); } @Override @@ -47,8 +55,8 @@ public Object eval(SQLContext context, Object[] args) { //SELECT current_user() mysql workbench public static final MySQLFunction current_user = new MySQLFunction() { @Override - public String getFunctionName() { - return "current_user"; + public Set getFunctionNames() { + return ImmutableSet.of("current_user"); } @Override @@ -61,4 +69,37 @@ public Object eval(SQLContext context, Object[] args) { return context.getSQLVariantRef("current_user"); } }; + + public static final MySQLFunction CURRENT_DATE = new MySQLFunction() { + @Override + public Set getFunctionNames() { + return ImmutableSet.of("CURRENT_DATE", "CURDATE", "curdate"); + } + + @Override + public int getArgumentSize() { + return 0; + } + + @Override + public Object eval(SQLContext context, Object[] args) { + return LocalDate.now().toString(); + } + }; + public static final MySQLFunction NOW = new MySQLFunction() { + @Override + public Set getFunctionNames() { + return ImmutableSet.of("NOW"); + } + + @Override + public int getArgumentSize() { + return 0; + } + + @Override + public Object eval(SQLContext context, Object[] args) { + return LocalDateTime.now().toString(); + } + }; } \ No newline at end of file diff --git a/hbt/src/main/java/io/mycat/util/ContextExecuter.java b/hbt/src/main/java/io/mycat/util/ContextExecuter.java index a80ce8a93..8426b44cd 100644 --- a/hbt/src/main/java/io/mycat/util/ContextExecuter.java +++ b/hbt/src/main/java/io/mycat/util/ContextExecuter.java @@ -4,10 +4,7 @@ import com.alibaba.fastsql.sql.ast.SQLExpr; import com.alibaba.fastsql.sql.ast.SQLObject; import com.alibaba.fastsql.sql.ast.SQLReplaceable; -import com.alibaba.fastsql.sql.ast.expr.SQLExprUtils; -import com.alibaba.fastsql.sql.ast.expr.SQLMethodInvokeExpr; -import com.alibaba.fastsql.sql.ast.expr.SQLPropertyExpr; -import com.alibaba.fastsql.sql.ast.expr.SQLVariantRefExpr; +import com.alibaba.fastsql.sql.ast.expr.*; import com.alibaba.fastsql.sql.ast.statement.SQLAssignItem; import com.alibaba.fastsql.sql.ast.statement.SQLExprTableSource; import com.alibaba.fastsql.sql.ast.statement.SQLSelectItem; @@ -34,7 +31,12 @@ public boolean visit(SQLMethodInvokeExpr x) { if (mySQLFunction != null) { String[] strings = arguments.stream().map(i -> SQLUtils.normalize(Objects.toString(i))).toArray(i -> new String[i]); Object res = mySQLFunction.eval(context, strings); - SQLExpr sqlExpr = SQLExprUtils.fromJavaObject(res); + SQLExpr sqlExpr; + if (res instanceof SQLValuableExpr){ + sqlExpr =(SQLValuableExpr) res; + }else { + sqlExpr = SQLExprUtils.fromJavaObject(res); + } sqlExpr.setParent(parent); ((SQLReplaceable) parent).replace(x, sqlExpr); diff --git a/hbt/src/main/java/io/mycat/util/MySQLFunction.java b/hbt/src/main/java/io/mycat/util/MySQLFunction.java index 31d6e9cff..73c8fd76c 100644 --- a/hbt/src/main/java/io/mycat/util/MySQLFunction.java +++ b/hbt/src/main/java/io/mycat/util/MySQLFunction.java @@ -1,7 +1,9 @@ package io.mycat.util; +import java.util.Set; + public interface MySQLFunction { - public String getFunctionName(); + public Set getFunctionNames(); int getArgumentSize(); diff --git a/hbt/src/main/java/io/mycat/util/SQLContextImpl.java b/hbt/src/main/java/io/mycat/util/SQLContextImpl.java index 26d1859d3..1414608ca 100644 --- a/hbt/src/main/java/io/mycat/util/SQLContextImpl.java +++ b/hbt/src/main/java/io/mycat/util/SQLContextImpl.java @@ -314,11 +314,15 @@ public long lastInsertId() { addFunction(MysqlFunctions.next_value_for); addFunction(MysqlFunctions.last_insert_id); addFunction(MysqlFunctions.current_user); + addFunction(MysqlFunctions.CURRENT_DATE); +// addFunction(MysqlFunctions.NOW); } static void addFunction(MySQLFunction function) { - functions.put(function.getFunctionName(), function); - functions.put(function.getFunctionName().toUpperCase(), function); - functions.put(function.getFunctionName().toLowerCase(), function); + for (String functionName : function.getFunctionNames()) { + functions.put(functionName, function); + functions.put(functionName.toUpperCase(), function); + functions.put(functionName.toLowerCase(), function); + } } } \ No newline at end of file diff --git a/hbt2/pom.xml b/hbt2/pom.xml index 1710b04cc..2e98ef32e 100644 --- a/hbt2/pom.xml +++ b/hbt2/pom.xml @@ -5,7 +5,7 @@ parent io.mycat - 1.07-SNAPSHOT + 1.08-SNAPSHOT 4.0.0 @@ -14,7 +14,8 @@ io.mycat - mycat + mycat2 + 1.08-SNAPSHOT \ No newline at end of file diff --git a/mycat2/pom.xml b/mycat2/pom.xml index 77ec3e116..caeea8cd2 100644 --- a/mycat2/pom.xml +++ b/mycat2/pom.xml @@ -5,7 +5,7 @@ parent io.mycat - 1.07-SNAPSHOT + 1.08-SNAPSHOT 4.0.0 jar @@ -15,29 +15,29 @@ io.mycat proxy - 1.07-SNAPSHOT + 1.08-SNAPSHOT io.mycat common - 1.07-SNAPSHOT + 1.08-SNAPSHOT io.mycat datasource - 1.07-SNAPSHOT + 1.08-SNAPSHOT io.mycat pattern - 1.07-SNAPSHOT + 1.08-SNAPSHOT io.mycat proxy - 1.07-SNAPSHOT + 1.08-SNAPSHOT org.eclipse.collections @@ -82,13 +82,13 @@ io.mycat booster - 1.07-SNAPSHOT + 1.08-SNAPSHOT compile io.mycat booster - 1.07-SNAPSHOT + 1.08-SNAPSHOT compile diff --git a/mycat2/src/test/java/io/mycat/sql/AggSQLChecker.java b/mycat2/src/test/java/io/mycat/sql/AggSQLChecker.java index 9902e8c62..ebf9274ba 100644 --- a/mycat2/src/test/java/io/mycat/sql/AggSQLChecker.java +++ b/mycat2/src/test/java/io/mycat/sql/AggSQLChecker.java @@ -46,8 +46,8 @@ public void run() { check("select id,COUNT(DISTINCT user_id) from db1.travelrecord GROUP BY id", "(1,1)(999999999,1)"); check("select MAX(id) from db1.travelrecord", "(999999999)"); check("select MIN(id) from db1.travelrecord", "(1)"); - check("select id,sum(id) from db1.travelrecord GROUP BY id", "(1,1)(999999999,999999999)"); - check("select id,avg(id) from db1.travelrecord GROUP BY id", "(1,1)(999999999,999999999)"); + check("select id,sum(id) from db1.travelrecord GROUP BY id order by id limit 2", "(1,1)(999999999,999999999)"); + check("select id,avg(id) from db1.travelrecord GROUP BY id order by id limit 2", "(1,1.0)(999999999,9.99999999E8)"); check("select id from db1.travelrecord order by id asc", "(1)(999999999)"); check("select id from db1.travelrecord order by id desc", "(999999999)(1)"); diff --git a/pattern/pom.xml b/pattern/pom.xml index 5e6129f38..07ac1d6e5 100644 --- a/pattern/pom.xml +++ b/pattern/pom.xml @@ -5,7 +5,7 @@ parent io.mycat - 1.07-SNAPSHOT + 1.08-SNAPSHOT 4.0.0 @@ -15,7 +15,7 @@ io.mycat common - 1.07-SNAPSHOT + 1.08-SNAPSHOT org.projectlombok @@ -92,12 +92,12 @@ io.mycat config - 1.07-SNAPSHOT + 1.08-SNAPSHOT io.mycat hbt - 1.07-SNAPSHOT + 1.08-SNAPSHOT diff --git a/plug/pom.xml b/plug/pom.xml index 62c98e3fa..08696d911 100644 --- a/plug/pom.xml +++ b/plug/pom.xml @@ -5,7 +5,7 @@ parent io.mycat - 1.07-SNAPSHOT + 1.08-SNAPSHOT 4.0.0 plug @@ -13,12 +13,12 @@ io.mycat router - 1.07-SNAPSHOT + 1.08-SNAPSHOT io.mycat common - 1.07-SNAPSHOT + 1.08-SNAPSHOT diff --git a/pom.xml b/pom.xml index f90198fca..88f096281 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 io.mycat parent - 1.07-SNAPSHOT + 1.08-SNAPSHOT config proxy diff --git a/proxy/pom.xml b/proxy/pom.xml index b8c90a0aa..3868333b5 100644 --- a/proxy/pom.xml +++ b/proxy/pom.xml @@ -5,7 +5,7 @@ io.mycat parent - 1.07-SNAPSHOT + 1.08-SNAPSHOT 4.0.0 @@ -15,32 +15,32 @@ io.mycat config - 1.07-SNAPSHOT + 1.08-SNAPSHOT io.mycat plug - 1.07-SNAPSHOT + 1.08-SNAPSHOT io.mycat router - 1.07-SNAPSHOT + 1.08-SNAPSHOT io.mycat common - 1.07-SNAPSHOT + 1.08-SNAPSHOT io.mycat replica - 1.07-SNAPSHOT + 1.08-SNAPSHOT io.mycat datasource - 1.07-SNAPSHOT + 1.08-SNAPSHOT diff --git a/replica/pom.xml b/replica/pom.xml index db79f7fbf..75b911032 100644 --- a/replica/pom.xml +++ b/replica/pom.xml @@ -5,7 +5,7 @@ parent io.mycat - 1.07-SNAPSHOT + 1.08-SNAPSHOT 4.0.0 @@ -15,12 +15,12 @@ io.mycat common - 1.07-SNAPSHOT + 1.08-SNAPSHOT io.mycat plug - 1.07-SNAPSHOT + 1.08-SNAPSHOT \ No newline at end of file diff --git a/router/pom.xml b/router/pom.xml index 88eb892e9..10b6180dc 100644 --- a/router/pom.xml +++ b/router/pom.xml @@ -5,7 +5,7 @@ parent io.mycat - 1.07-SNAPSHOT + 1.08-SNAPSHOT 4.0.0 @@ -15,12 +15,12 @@ io.mycat config - 1.07-SNAPSHOT + 1.08-SNAPSHOT io.mycat common - 1.07-SNAPSHOT + 1.08-SNAPSHOT diff --git a/statistic/pom.xml b/statistic/pom.xml index 8e2e038cf..07f66aa51 100644 --- a/statistic/pom.xml +++ b/statistic/pom.xml @@ -5,7 +5,7 @@ parent io.mycat - 1.07-SNAPSHOT + 1.08-SNAPSHOT 4.0.0 @@ -14,13 +14,13 @@ io.mycat config - 1.07-SNAPSHOT + 1.08-SNAPSHOT compile io.mycat hbt - 1.07-SNAPSHOT + 1.08-SNAPSHOT compile diff --git a/testsuite/pom.xml b/testsuite/pom.xml index 3a398ae8c..be2a01915 100644 --- a/testsuite/pom.xml +++ b/testsuite/pom.xml @@ -5,7 +5,7 @@ parent io.mycat - 1.07-SNAPSHOT + 1.08-SNAPSHOT 4.0.0 @@ -20,7 +20,7 @@ io.mycat example - 1.07-SNAPSHOT + 1.08-SNAPSHOT test