未验证 提交 36288f21 编写于 作者: J Juan Pan(Trista) 提交者: GitHub

support group by for mysql (#4282)

上级 87d6bd63
......@@ -27,6 +27,7 @@ import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.Duplica
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.EscapedTableReferenceContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ExprContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.FromClauseContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.GroupByClauseContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.InsertContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.InsertValuesClauseContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.JoinedTableContext;
......@@ -36,6 +37,7 @@ import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.LimitRo
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.MultipleTableNamesContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.MultipleTablesClauseContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.OnDuplicateKeyClauseContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.OrderByItemContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ProjectionContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ProjectionsContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.QualifiedShorthandContext;
......@@ -66,7 +68,9 @@ import org.apache.shardingsphere.sql.parser.sql.segment.dml.item.ExpressionProje
import org.apache.shardingsphere.sql.parser.sql.segment.dml.item.ProjectionSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.item.ProjectionsSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.item.ShorthandProjectionSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.order.GroupBySegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.order.OrderBySegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.order.item.OrderByItemSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.pagination.PaginationValueSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.pagination.limit.LimitSegment;
import org.apache.shardingsphere.sql.parser.sql.segment.dml.pagination.limit.NumberLiteralLimitValueSegment;
......@@ -295,6 +299,11 @@ public final class MySQLDMLVisitor extends MySQLVisitor {
result.setWhere(where);
result.getAllSQLSegments().add(where);
}
if (null != ctx.groupByClause()) {
GroupBySegment groupBy = (GroupBySegment) visit(ctx.groupByClause());
result.setGroupBy(groupBy);
result.getAllSQLSegments().add(groupBy);
}
if (null != ctx.orderByClause()) {
OrderBySegment orderBy = (OrderBySegment) visit(ctx.orderByClause());
result.setOrderBy(orderBy);
......@@ -457,6 +466,15 @@ public final class MySQLDMLVisitor extends MySQLVisitor {
return result;
}
@Override
public ASTNode visitGroupByClause(final GroupByClauseContext ctx) {
Collection<OrderByItemSegment> items = new LinkedList<>();
for (OrderByItemContext each : ctx.orderByItem()) {
items.add((OrderByItemSegment) visit(each));
}
return new GroupBySegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), items);
}
@Override
public ASTNode visitLimitClause(final LimitClauseContext ctx) {
if (null == ctx.limitOffset()) {
......
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<sql-parser-test-cases>
<select sql-case-id="select_group_by_with_sum">
<table name="t_order" start-index="49" stop-index="55" />
<projections start-index="7" stop-index="42">
<aggregation-projection type="SUM" alias="orders_sum" inner-expression-start-index="10" start-index="7" stop-index="19" />
<column-projection name="user_id" start-index="36" stop-index="42" />
</projections>
<group-by>
<column-item name="user_id" />
</group-by>
<order-by>
<column-item name="user_id" />
</order-by>
</select>
<select sql-case-id="select_group_by_with_count">
<table name="t_order" start-index="53" stop-index="59" />
<projections start-index="7" stop-index="46">
<aggregation-projection type="COUNT" alias="orders_count" inner-expression-start-index="12" start-index="7" stop-index="21" />
<column-projection name="user_id" start-index="40" stop-index="46" />
</projections>
<group-by>
<column-item name="user_id" />
</group-by>
<order-by>
<column-item name="user_id" />
</order-by>
</select>
<select sql-case-id="select_group_by_with_max">
<table name="t_order" start-index="51" stop-index="57" />
<projections start-index="7" stop-index="44">
<aggregation-projection type="MAX" alias="max_order_id" inner-expression-start-index="10" start-index="7" stop-index="19" />
<column-projection name="user_id" start-index="38" stop-index="44" />
</projections>
<group-by>
<column-item name="user_id" />
</group-by>
<order-by>
<column-item name="user_id" />
</order-by>
</select>
<select sql-case-id="select_group_by_with_min">
<table name="t_order" start-index="51" stop-index="57" />
<projections start-index="7" stop-index="44">
<aggregation-projection type="MIN" alias="min_order_id" inner-expression-start-index="10" start-index="7" stop-index="19" />
<column-projection name="user_id" start-index="38" stop-index="44" />
</projections>
<group-by>
<column-item name="user_id" />
</group-by>
<order-by>
<column-item name="user_id" />
</order-by>
</select>
<select sql-case-id="select_group_by_with_avg">
<table name="t_order" start-index="49" stop-index="55" />
<projections start-index="7" stop-index="42">
<aggregation-projection type="AVG" alias="orders_avg" inner-expression-start-index="10" start-index="7" stop-index="19" />
<column-projection name="user_id" start-index="36" stop-index="42" />
</projections>
<group-by>
<column-item name="user_id" />
</group-by>
<order-by>
<column-item name="user_id" />
</order-by>
</select>
<select sql-case-id="select_group_by_with_order_by_desc">
<table name="t_order" start-index="49" stop-index="55" />
<projections start-index="7" stop-index="42">
<aggregation-projection type="SUM" inner-expression-start-index="10" alias="orders_sum" start-index="7" stop-index="19" />
<column-projection name="user_id" start-index="36" stop-index="42" />
</projections>
<group-by>
<column-item name="user_id" />
</group-by>
<order-by>
<column-item name="orders_sum" order-direction="DESC" />
</order-by>
</select>
<select sql-case-id="select_group_by_without_grouped_column" parameters="1, 2, 9, 10">
<table name="t_order" alias="o" start-index="36" stop-index="42" />
<table name="t_order_item" alias="i" start-index="51" stop-index="62" />
<projections start-index="7" stop-index="29">
<aggregation-projection type="COUNT" inner-expression-start-index="12" alias="items_count" start-index="7" stop-index="14" />
</projections>
<where parameters-count="4" start-index="119" stop-index="174" literal-stop-index="175">
<and-predicate>
<predicate start-index="125" stop-index="143">
<column-left-value name="user_id" start-index="125" stop-index="133">
<owner name="o" start-index="125" stop-index="125" />
</column-left-value>
<in-right-value>
<parameter-marker-expression value="0" />
<parameter-marker-expression value="1" />
<literal-expression value="1" />
<literal-expression value="2" />
</in-right-value>
</predicate>
<predicate start-index="149" stop-index="174" literal-stop-index="175">
<column-left-value name="order_id" start-index="149" stop-index="158">
<owner name="o" start-index="149" stop-index="149" />
</column-left-value>
<between-right-value>
<between-parameter-marker-expression value="2" />
<between-literal-expression value="9" />
<and-parameter-marker-expression value="3" />
<and-literal-expression value="10" />
</between-right-value>
</predicate>
</and-predicate>
</where>
<group-by>
<column-item name="user_id">
<owner name="o" start-index="185" stop-index="185" literal-start-index="186" literal-stop-index="186" />
</column-item>
</group-by>
</select>
<select sql-case-id="select_group_by_with_limit" parameters="5">
<table name="t_order" start-index="20" stop-index="26" />
<projections start-index="7" stop-index="13">
<column-projection name="user_id" start-index="7" stop-index="13" />
</projections>
<group-by>
<column-item name="user_id" />
</group-by>
<order-by>
<column-item name="user_id" />
</order-by>
<limit start-index="62" stop-index="68">
<row-count value="5" parameter-index="0" start-index="68" stop-index="68" />
</limit>
</select>
<select sql-case-id="select_group_by_with_order_by_and_limit" parameters="5">
<table name="t_order" start-index="49" stop-index="55" />
<projections start-index="7" stop-index="42">
<column-projection name="user_id" start-index="7" stop-index="13" />
<aggregation-projection type="SUM" inner-expression-start-index="19" alias="orders_sum" start-index="16" stop-index="28" />
</projections>
<group-by>
<column-item name="user_id" />
</group-by>
<order-by>
<expression-item expression="SUM(order_id)" />
</order-by>
<limit start-index="97" stop-index="103">
<row-count value="5" parameter-index="0" start-index="103" stop-index="103" />
</limit>
</select>
<select sql-case-id="select_with_item_alias_match_order_by_and_group_by_items">
<table name="t_order" alias="o" start-index="26" stop-index="32" />
<projections start-index="7" stop-index="19">
<column-projection name="user_id" alias="uid" start-index="7" stop-index="15">
<owner name="o" start-index="7" stop-index="7" />
</column-projection>
</projections>
<group-by>
<column-item name="user_id">
<owner name="o" start-index="45" stop-index="45" />
</column-item>
</group-by>
<order-by>
<column-item name="user_id">
<owner name="o" start-index="64" stop-index="64" />
</column-item>
</order-by>
</select>
<select sql-case-id="select_group_by_with_date_function" parameters="1000, 1100">
<table name="t_order_item" start-delimiter="`" end-delimiter="`" start-index="91" stop-index="104" />
<projections start-index="7" stop-index="84">
<expression-projection alias="creation_date" start-index="7" stop-index="45" />
<aggregation-projection type="COUNT" inner-expression-start-index="70" alias="c_number" start-index="65" stop-index="72" />
</projections>
<where parameters-count="2" start-index="106" stop-index="130" literal-stop-index="135">
<and-predicate>
<predicate start-index="112" stop-index="129" literal-stop-index="135">
<column-left-value name="order_id" start-index="112" stop-index="119" />
<in-right-value>
<parameter-marker-expression value="0" />
<parameter-marker-expression value="1" />
<literal-expression value="1000" />
<literal-expression value="1100" />
</in-right-value>
</predicate>
</and-predicate>
</where>
<group-by>
<expression-item expression="date_format(creation_date,'%y-%m-%d')" start-index="140" stop-index="177" literal-start-index="146" literal-stop-index="183" />
</group-by>
</select>
<select sql-case-id="select_group_by_with_keyword_alias">
<table name="t_order" start-index="58" stop-index="64" />
<projections start-index="7" stop-index="51">
<aggregation-projection type="SUM" inner-expression-start-index="10" alias="orders_sum" start-index="7" stop-index="19" />
<column-projection name="user_id" alias="key" start-index="36" stop-index="42" />
</projections>
<group-by>
<column-item name="key" start-delimiter="`" end-delimiter="`" />
</group-by>
</select>
<select sql-case-id="select_group_by_with_count_without_column_name">
<table name="t_order" start-index="53" stop-index="59" />
<projections start-index="7" stop-index="46">
<aggregation-projection inner-expression-start-index="12" type="COUNT" alias="orders_count" start-index="7" stop-index="21" />
<column-projection name="user_id" start-index="40" stop-index="46" />
</projections>
<group-by>
<index-item index="2" start-index="70" stop-index="70" />
</group-by>
<order-by>
<index-item index="2" />
</order-by>
</select>
</sql-parser-test-cases>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册