Skip to content

Commit

Permalink
refactor window segment (#30001)
Browse files Browse the repository at this point in the history
  • Loading branch information
tuichenchuxin authored Feb 5, 2024
1 parent 7d73d49 commit da2d7cb
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,16 @@
import lombok.NoArgsConstructor;
import org.apache.calcite.sql.SqlIdentifier;
import org.apache.calcite.sql.SqlLiteral;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.SqlNodeList;
import org.apache.calcite.sql.SqlWindow;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.WindowItemSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.WindowSegment;
import org.apache.shardingsphere.sqlfederation.optimizer.converter.segment.expression.ExpressionConverter;

import java.util.Collections;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Optional;

/**
Expand All @@ -43,11 +46,17 @@ public final class WindowConverter {
* @return sql node list
*/
public static Optional<SqlNodeList> convert(final WindowSegment segment) {
SqlIdentifier sqlIdentifier = new SqlIdentifier(segment.getIdentifierValue().getValue(), SqlParserPos.ZERO);
SqlNodeList partitionList = new SqlNodeList(Collections.singletonList(ExpressionConverter.convert(segment.getPartitionListSegments().iterator().next()).get()), SqlParserPos.ZERO);
SqlNodeList orderList = new SqlNodeList(SqlParserPos.ZERO);
SqlWindow sqlWindow = new SqlWindow(SqlParserPos.ZERO, sqlIdentifier, null, partitionList, orderList, SqlLiteral.createBoolean(false, SqlParserPos.ZERO), null, null, null);
SqlNodeList result = new SqlNodeList(Collections.singletonList(sqlWindow), SqlParserPos.ZERO);
Collection<SqlWindow> sqlWindows = new LinkedList<>();
for (WindowItemSegment each : segment.getItemSegments()) {
SqlIdentifier sqlIdentifier = null == each.getWindowName() ? new SqlIdentifier("", SqlParserPos.ZERO) : new SqlIdentifier(each.getWindowName().getValue(), SqlParserPos.ZERO);
Collection<SqlNode> partitionNodes = new LinkedList<>();
each.getPartitionListSegments().forEach(expressionSegment -> ExpressionConverter.convert(expressionSegment).ifPresent(partitionNodes::add));
SqlNodeList partitionList = new SqlNodeList(partitionNodes, SqlParserPos.ZERO);
SqlNodeList orderList = new SqlNodeList(SqlParserPos.ZERO);
SqlWindow sqlWindow = new SqlWindow(SqlParserPos.ZERO, sqlIdentifier, null, partitionList, orderList, SqlLiteral.createBoolean(false, SqlParserPos.ZERO), null, null, null);
sqlWindows.add(sqlWindow);
}
SqlNodeList result = new SqlNodeList(sqlWindows, SqlParserPos.ZERO);
return Optional.of(result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,7 @@
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ViewNamesContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.WeightStringFunctionContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.WhereClauseContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.WindowClauseContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.WindowFunctionContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.WindowItemContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.WithClauseContext;
import org.apache.shardingsphere.sql.parser.sql.common.enums.AggregationType;
import org.apache.shardingsphere.sql.parser.sql.common.enums.CombineType;
Expand Down Expand Up @@ -863,19 +861,6 @@ public ASTNode visitTableStatement(final TableStatementContext ctx) {
return result;
}

@Override
public ASTNode visitWindowClause(final WindowClauseContext ctx) {
if (null != ctx.windowItem()) {
return new WindowSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), getWindowItem(ctx.windowItem(0)),
getExpressions(ctx.windowItem(0).windowSpecification().expr()));
}
return new WindowSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex());
}

private IdentifierValue getWindowItem(final WindowItemContext ctx) {
return new IdentifierValue(ctx.identifier().getText());
}

@Override
public ASTNode visitHavingClause(final HavingClauseContext ctx) {
ExpressionSegment expr = (ExpressionSegment) visit(ctx.expr());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,24 @@
import org.apache.shardingsphere.sql.parser.api.visitor.statement.type.DMLStatementVisitor;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.CallContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.DoStatementContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ExprContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.HandlerStatementContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ImportStatementContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.IndexHintContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.LoadDataStatementContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.LoadStatementContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.LoadXmlStatementContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.WindowClauseContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.WindowItemContext;
import org.apache.shardingsphere.sql.parser.mysql.visitor.statement.MySQLStatementVisitor;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.complex.CommonExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.OrderBySegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.WindowItemSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.WindowSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.IndexHintSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dml.MySQLCallStatement;
import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dml.MySQLDoStatement;
import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dml.MySQLHandlerStatement;
Expand All @@ -40,6 +48,7 @@

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

Expand Down Expand Up @@ -114,4 +123,41 @@ public ASTNode visitIndexHint(final IndexHintContext ctx) {
}
return result;
}

@Override
public ASTNode visitWindowClause(final WindowClauseContext ctx) {
WindowSegment result = new WindowSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex());
for (WindowItemContext each : ctx.windowItem()) {
result.getItemSegments().add((WindowItemSegment) visit(each));
}
return result;
}

@Override
public ASTNode visitWindowItem(final WindowItemContext ctx) {
WindowItemSegment result = new WindowItemSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex());
result.setWindowName(new IdentifierValue(ctx.identifier().getText()));
if (null != ctx.windowSpecification().PARTITION()) {
result.setPartitionListSegments(getExpressions(ctx.windowSpecification().expr()));
}
if (null != ctx.windowSpecification().orderByClause()) {
result.setOrderBySegment((OrderBySegment) visit(ctx.windowSpecification().orderByClause()));
}
if (null != ctx.windowSpecification().frameClause()) {
result.setFrameClause(new CommonExpressionSegment(ctx.windowSpecification().frameClause().start.getStartIndex(), ctx.windowSpecification().frameClause().stop.getStopIndex(),
ctx.windowSpecification().frameClause().getText()));
}
return result;
}

private Collection<ExpressionSegment> getExpressions(final List<ExprContext> exprList) {
if (null == exprList) {
return Collections.emptyList();
}
Collection<ExpressionSegment> result = new ArrayList<>(exprList.size());
for (ExprContext each : exprList) {
result.add((ExpressionSegment) visit(each));
}
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@
import org.apache.shardingsphere.sql.parser.autogen.OpenGaussStatementParser.WhereOrCurrentClauseContext;
import org.apache.shardingsphere.sql.parser.autogen.OpenGaussStatementParser.WindowClauseContext;
import org.apache.shardingsphere.sql.parser.autogen.OpenGaussStatementParser.WindowDefinitionContext;
import org.apache.shardingsphere.sql.parser.autogen.OpenGaussStatementParser.WindowSpecificationContext;
import org.apache.shardingsphere.sql.parser.autogen.OpenGaussStatementParser.WindowDefinitionListContext;
import org.apache.shardingsphere.sql.parser.autogen.OpenGaussStatementParser.IntoClauseContext;
import org.apache.shardingsphere.sql.parser.sql.common.enums.AggregationType;
import org.apache.shardingsphere.sql.parser.sql.common.enums.CombineType;
Expand Down Expand Up @@ -177,6 +177,7 @@
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.NameSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.OwnerSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.ParameterMarkerSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.WindowItemSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.WindowSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.JoinTableSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
Expand Down Expand Up @@ -1038,19 +1039,38 @@ public ASTNode visitHavingClause(final HavingClauseContext ctx) {

@Override
public ASTNode visitWindowClause(final WindowClauseContext ctx) {
if (null != ctx.windowDefinitionList()) {
return new WindowSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), getWindowItem(ctx.windowDefinitionList().windowDefinition()),
getWindowSpecification(ctx.windowDefinitionList().windowDefinition().windowSpecification()));
}
return new WindowSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex());
WindowSegment result = new WindowSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex());
appendWindowItems(ctx.windowDefinitionList(), result.getItemSegments());
return result;
}

private IdentifierValue getWindowItem(final WindowDefinitionContext ctx) {
return new IdentifierValue(ctx.colId().identifier().getText());
private void appendWindowItems(final WindowDefinitionListContext ctx, final Collection<WindowItemSegment> windowItems) {
if (null != ctx.windowDefinitionList()) {
appendWindowItems(ctx.windowDefinitionList(), windowItems);
windowItems.add((WindowItemSegment) visit(ctx.windowDefinition()));
return;
}
windowItems.add((WindowItemSegment) visit(ctx.windowDefinition()));
}

private Collection<ExpressionSegment> getWindowSpecification(final WindowSpecificationContext ctx) {
return createInsertValuesSegments(ctx.partitionClause().exprList());
@SuppressWarnings("unchecked")
@Override
public ASTNode visitWindowDefinition(final WindowDefinitionContext ctx) {
WindowItemSegment result = new WindowItemSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex());
result.setWindowName(new IdentifierValue(ctx.colId().getText()));
if (null != ctx.windowSpecification().partitionClause()) {
CollectionValue<ExpressionSegment> value = (CollectionValue<ExpressionSegment>) visit(ctx.windowSpecification().partitionClause().exprList());
result.setPartitionListSegments(value.getValue());
}
if (null != ctx.windowSpecification().sortClause()) {
OrderBySegment orderBySegment = (OrderBySegment) visit(ctx.windowSpecification().sortClause());
result.setOrderBySegment(orderBySegment);
}
if (null != ctx.windowSpecification().frameClause()) {
result.setFrameClause(new CommonExpressionSegment(ctx.windowSpecification().frameClause().start.getStartIndex(), ctx.windowSpecification().frameClause().stop.getStopIndex(),
ctx.windowSpecification().frameClause().getText()));
}
return result;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.WhereOrCurrentClauseContext;
import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.WindowClauseContext;
import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.WindowDefinitionContext;
import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.WindowSpecificationContext;
import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.WindowDefinitionListContext;
import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParser.IntoClauseContext;
import org.apache.shardingsphere.sql.parser.autogen.PostgreSQLStatementParserBaseVisitor;
import org.apache.shardingsphere.sql.parser.sql.common.enums.AggregationType;
Expand Down Expand Up @@ -172,6 +172,7 @@
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.NameSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.OwnerSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.ParameterMarkerSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.WindowItemSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.WindowSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.JoinTableSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
Expand Down Expand Up @@ -1004,19 +1005,38 @@ public ASTNode visitHavingClause(final HavingClauseContext ctx) {

@Override
public ASTNode visitWindowClause(final WindowClauseContext ctx) {
if (null != ctx.windowDefinitionList()) {
return new WindowSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), getWindowItem(ctx.windowDefinitionList().windowDefinition()),
getWindowSpecification(ctx.windowDefinitionList().windowDefinition().windowSpecification()));
}
return new WindowSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex());
WindowSegment result = new WindowSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex());
appendWindowItems(ctx.windowDefinitionList(), result.getItemSegments());
return result;
}

private IdentifierValue getWindowItem(final WindowDefinitionContext ctx) {
return new IdentifierValue(ctx.colId().identifier().getText());
private void appendWindowItems(final WindowDefinitionListContext ctx, final Collection<WindowItemSegment> windowItems) {
if (null != ctx.windowDefinitionList()) {
appendWindowItems(ctx.windowDefinitionList(), windowItems);
windowItems.add((WindowItemSegment) visit(ctx.windowDefinition()));
return;
}
windowItems.add((WindowItemSegment) visit(ctx.windowDefinition()));
}

private Collection<ExpressionSegment> getWindowSpecification(final WindowSpecificationContext ctx) {
return createInsertValuesSegments(ctx.partitionClause().exprList());
@SuppressWarnings("unchecked")
@Override
public ASTNode visitWindowDefinition(final WindowDefinitionContext ctx) {
WindowItemSegment result = new WindowItemSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex());
result.setWindowName(new IdentifierValue(ctx.colId().getText()));
if (null != ctx.windowSpecification().partitionClause()) {
CollectionValue<ExpressionSegment> value = (CollectionValue<ExpressionSegment>) visit(ctx.windowSpecification().partitionClause().exprList());
result.setPartitionListSegments(value.getValue());
}
if (null != ctx.windowSpecification().sortClause()) {
OrderBySegment orderBySegment = (OrderBySegment) visit(ctx.windowSpecification().sortClause());
result.setOrderBySegment(orderBySegment);
}
if (null != ctx.windowSpecification().frameClause()) {
result.setFrameClause(new CommonExpressionSegment(ctx.windowSpecification().frameClause().start.getStartIndex(), ctx.windowSpecification().frameClause().stop.getStopIndex(),
ctx.windowSpecification().frameClause().getText()));
}
return result;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* 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 org.apache.shardingsphere.sql.parser.sql.common.segment.generic;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import org.apache.shardingsphere.sql.parser.sql.common.segment.SQLSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.OrderBySegment;
import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;

import java.util.Collection;

@RequiredArgsConstructor
@Getter
@Setter
public class WindowItemSegment implements SQLSegment {

private final int startIndex;

private final int stopIndex;

private IdentifierValue windowName;

private Collection<ExpressionSegment> partitionListSegments;

private OrderBySegment orderBySegment;

private ExpressionSegment frameClause;
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.sql.parser.sql.common.segment.SQLSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;

import java.util.Collection;
import java.util.LinkedList;

/**
* Window segment.
Expand All @@ -36,14 +35,5 @@ public final class WindowSegment implements SQLSegment {

private final int stopIndex;

private IdentifierValue identifierValue;

private Collection<ExpressionSegment> partitionListSegments;

public WindowSegment(final int startIndex, final int stopIndex, final IdentifierValue identifierValue, final Collection<ExpressionSegment> partitionListSegments) {
this.startIndex = startIndex;
this.stopIndex = stopIndex;
this.identifierValue = identifierValue;
this.partitionListSegments = partitionListSegments;
}
private final Collection<WindowItemSegment> itemSegments = new LinkedList<>();
}

0 comments on commit da2d7cb

Please sign in to comment.