diff --git a/fastmodel-bom/pom.xml b/fastmodel-bom/pom.xml index 8671048..7ad3206 100644 --- a/fastmodel-bom/pom.xml +++ b/fastmodel-bom/pom.xml @@ -145,6 +145,12 @@ ${project.version} + + com.aliyun.fastmodel + fastmodel-transform-oceanbase + ${project.version} + + com.aliyun.fastmodel fastmodel-transform-api diff --git a/fastmodel-common/src/main/java/com/aliyun/fastmodel/common/parser/ParserHelper.java b/fastmodel-common/src/main/java/com/aliyun/fastmodel/common/parser/ParserHelper.java index 9009796..b625d8d 100644 --- a/fastmodel-common/src/main/java/com/aliyun/fastmodel/common/parser/ParserHelper.java +++ b/fastmodel-common/src/main/java/com/aliyun/fastmodel/common/parser/ParserHelper.java @@ -13,7 +13,12 @@ import java.util.Locale; import java.util.Objects; import java.util.Optional; +import java.util.function.Function; +import com.aliyun.fastmodel.common.parser.lexer.CaseChangingCharStream; +import com.aliyun.fastmodel.common.utils.StripUtils; +import com.aliyun.fastmodel.core.tree.ListNode; +import com.aliyun.fastmodel.core.tree.Node; import com.aliyun.fastmodel.core.tree.NodeLocation; import com.aliyun.fastmodel.core.tree.expr.Identifier; import com.aliyun.fastmodel.core.tree.expr.literal.BaseLiteral; @@ -21,9 +26,17 @@ import com.aliyun.fastmodel.core.tree.expr.literal.DoubleLiteral; import com.aliyun.fastmodel.core.tree.expr.literal.LongLiteral; import com.aliyun.fastmodel.core.tree.expr.literal.StringLiteral; +import com.google.common.collect.Lists; import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.CharStreams; +import org.antlr.v4.runtime.CodePointCharStream; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.Parser; import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.atn.PredictionMode; import org.antlr.v4.runtime.misc.Interval; import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor; import org.antlr.v4.runtime.tree.ParseTree; @@ -159,4 +172,64 @@ private static Identifier getIdentifier(String text, String regex, ParserRuleCon text = text.substring(1, text.length() - 1).replaceAll(regex, StringUtils.EMPTY); return new Identifier(getLocation(ctx), getOrigin(ctx), text, true); } + + public static ParserRuleContext getNode(String text, + Function lexerFunction, + Function parserFunction, + Function functionalInterface) { + + String code = StripUtils.appendSemicolon(text); + CodePointCharStream charStream = CharStreams.fromString(code); + CaseChangingCharStream caseChangingCharStream = new CaseChangingCharStream(charStream, true); + Lexer lexer = lexerFunction.apply(caseChangingCharStream); + lexer.removeErrorListeners(); + ThrowingErrorListener LISTENER = new ThrowingErrorListener(); + lexer.addErrorListener(LISTENER); + CommonTokenStream commonTokenStream = new CommonTokenStream(lexer); + Parser parser = parserFunction.apply(commonTokenStream); + parser.removeErrorListeners(); + parser.addErrorListener(LISTENER); + ParserRuleContext tree; + try { + parser.getInterpreter().setPredictionMode(PredictionMode.SLL); + tree = functionalInterface.apply(parser); + } catch (Throwable e) { + commonTokenStream.seek(0); + parser.getInterpreter().setPredictionMode(PredictionMode.LL); + tree = functionalInterface.apply(parser); + } + return tree; + } + + public static T getNode(ListNode node, Class clazz) { + List listNode = getListNode(node, clazz); + if (listNode == null || listNode.isEmpty()) { + return null; + } + return listNode.get(0); + } + + public static List getListNode(ListNode node, Class clazz) { + if (node == null || node.getChildren() == null || node.getChildren().isEmpty()) { + return null; + } + if (clazz == null) { + return null; + } + List list = Lists.newArrayList(); + List children = node.getChildren(); + for (Node node1 : children) { + if (node1.getClass().getName() == clazz.getName()) { + list.add((T)node1); + } + if (node1 instanceof ListNode) { + ListNode node2 = (ListNode)node1; + List listNode = getListNode(node2, clazz); + if (listNode != null) { + list.addAll(listNode); + } + } + } + return list; + } } diff --git a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/formatter/ExpressionFormatter.java b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/formatter/ExpressionFormatter.java index 668723e..ca1ef7a 100644 --- a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/formatter/ExpressionFormatter.java +++ b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/formatter/ExpressionFormatter.java @@ -1,30 +1,14 @@ /* - * Copyright 2021-2022 Alibaba Group Holding Ltd. - * - * Licensed 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. + * Copyright (c) 2020. Aliyun.com All right reserved. This software is the + * confidential and proprietary information of Aliyun.com ("Confidential + * Information"). You shall not disclose such Confidential Information and shall + * use it only in accordance with the terms of the license agreement you entered + * into with Aliyun.com. */ package com.aliyun.fastmodel.core.formatter; -import java.util.List; - -import com.aliyun.fastmodel.core.tree.QualifiedName; import com.aliyun.fastmodel.core.tree.expr.BaseExpression; -import com.aliyun.fastmodel.core.tree.statement.select.order.OrderBy; -import com.google.common.base.Joiner; - -import static java.lang.String.format; -import static java.util.stream.Collectors.joining; /** * 格式化处理 diff --git a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/formatter/ExpressionVisitor.java b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/formatter/ExpressionVisitor.java index ea543d8..3d92fc5 100644 --- a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/formatter/ExpressionVisitor.java +++ b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/formatter/ExpressionVisitor.java @@ -1,17 +1,9 @@ /* - * Copyright 2021-2022 Alibaba Group Holding Ltd. - * - * Licensed 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. + * Copyright (c) 2021. Aliyun.com All right reserved. This software is the + * confidential and proprietary information of Aliyun.com ("Confidential + * Information"). You shall not disclose such Confidential Information and shall + * use it only in accordance with the terms of the license agreement you entered + * into with Aliyun.com. */ package com.aliyun.fastmodel.core.formatter; @@ -250,7 +242,7 @@ public String visitSearchedCaseExpression(SearchedCaseExpression node, Void cont @Override public String visitNullLiteral(NullLiteral node, Void context) { - return "null"; + return "NULL"; } @Override diff --git a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/formatter/FastModelFormatter.java b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/formatter/FastModelFormatter.java index 83c4f7f..de23976 100644 --- a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/formatter/FastModelFormatter.java +++ b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/formatter/FastModelFormatter.java @@ -1,17 +1,9 @@ /* - * Copyright 2021-2022 Alibaba Group Holding Ltd. - * - * Licensed 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. + * Copyright (c) 2020. Aliyun.com All right reserved. This software is the + * confidential and proprietary information of Aliyun.com ("Confidential + * Information"). You shall not disclose such Confidential Information and shall + * use it only in accordance with the terms of the license agreement you entered + * into with Aliyun.com. */ package com.aliyun.fastmodel.core.formatter; diff --git a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/formatter/FastModelVisitor.java b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/formatter/FastModelVisitor.java index 6b0a99d..1c5c0f8 100644 --- a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/formatter/FastModelVisitor.java +++ b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/formatter/FastModelVisitor.java @@ -1,17 +1,9 @@ /* - * Copyright 2021-2022 Alibaba Group Holding Ltd. - * - * Licensed 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. + * Copyright (c) 2020. Aliyun.com All right reserved. This software is the + * confidential and proprietary information of Aliyun.com ("Confidential + * Information"). You shall not disclose such Confidential Information and shall + * use it only in accordance with the terms of the license agreement you entered + * into with Aliyun.com. */ package com.aliyun.fastmodel.core.formatter; @@ -148,6 +140,8 @@ import com.aliyun.fastmodel.core.tree.statement.table.constraint.TimePeriodConstraint; import com.aliyun.fastmodel.core.tree.statement.table.constraint.UniqueConstraint; import com.aliyun.fastmodel.core.tree.statement.table.index.IndexColumnName; +import com.aliyun.fastmodel.core.tree.statement.table.index.IndexExpr; +import com.aliyun.fastmodel.core.tree.statement.table.index.IndexSortKey; import com.aliyun.fastmodel.core.tree.statement.table.index.SortType; import com.aliyun.fastmodel.core.tree.statement.table.index.TableIndex; import com.aliyun.fastmodel.core.tree.statement.table.type.ITableDetailType; @@ -441,7 +435,8 @@ public Boolean visitCreateTable(CreateTable node, Integer indent) { String elementIndent = indentString(newIndent); builder.append(formatColumnList(node.getColumnDefines(), elementIndent)); if (!node.isConstraintEmpty()) { - Iterator iterator = node.getConstraintStatements().iterator(); + Iterator iterator = node.getConstraintStatements().stream() + .iterator(); while (iterator.hasNext()) { builder.append(",\n"); process(iterator.next(), newIndent); @@ -666,14 +661,36 @@ public Boolean visitTableIndex(TableIndex tableIndex, Integer ident) { return true; } - protected void appendTableIndex(List tableIndex) { + protected void appendTableIndex(List tableIndex) { builder.append(" ("); builder.append(tableIndex.stream().map( - this::formatIndexColumnName + index -> { + if (index instanceof IndexColumnName) { + IndexColumnName indexColumnName = (IndexColumnName)index; + return formatIndexColumnName(indexColumnName); + } + if (index instanceof IndexExpr) { + IndexExpr indexExpr = (IndexExpr)index; + return formatIndexExpr(indexExpr); + } + return StringUtils.EMPTY; + } ).collect(joining(","))); builder.append(")"); } + private String formatIndexExpr(IndexExpr indexExpr) { + StringBuilder stringBuilder = new StringBuilder("("); + String expression = formatExpression(indexExpr.getExpression()); + stringBuilder.append(expression); + stringBuilder.append(")"); + SortType sortType = indexExpr.getSortType(); + if (sortType != null) { + stringBuilder.append(" ").append(sortType.name()); + } + return stringBuilder.toString(); + } + @Override public Boolean visitDropIndex(DropIndex dropIndex, Integer context) { builder.append("DROP INDEX "); @@ -729,7 +746,7 @@ protected String formatPartitions(List partitionCol, boolean i } protected String formatColumnList(List list, - String elementIndent) { + String elementIndent) { OptionalInt max = list.stream().map(ColumnDefinition::getColName).mapToInt( x -> formatExpression(x).length() ).max(); @@ -1506,7 +1523,7 @@ public Boolean visitCreateDqcRule(CreateDqcRule createRules, Integer context) { } protected void appendPartition(StringBuilder builder, - List partitionSpecList, String split) { + List partitionSpecList, String split) { if (partitionSpecList == null || partitionSpecList.isEmpty()) { return; } @@ -1947,7 +1964,10 @@ private String formatWith(List properties, boolean isNewLine) { return stringBuilder.toString(); } - protected String indentString(int indent) { + protected String indentString(Integer indent) { + if (indent == null) { + return StringUtils.EMPTY; + } return Strings.repeat(INDENT, indent); } diff --git a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/parser/LanguageParser.java b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/parser/LanguageParser.java index d057b50..04198c5 100644 --- a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/parser/LanguageParser.java +++ b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/parser/LanguageParser.java @@ -46,12 +46,24 @@ default T parseNode(String text) throws ParseException { /** * parse data type * - * @param code + * @param text * @param context * @return {@link BaseDataType} * @throws ParseException */ - default BaseDataType parseDataType(String code, C context) throws ParseException { + default BaseDataType parseDataType(String text, C context) throws ParseException { + return null; + } + + /** + * 解析表达式,支持泛型, 不需要强转 + * + * @param text¬ 表达式 + * @param T + * @return T + * @throws ParseException 解析异常 + */ + default T parseExpression(String text) throws ParseException { return null; } } diff --git a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/IAstVisitor.java b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/IAstVisitor.java index 1c92b6f..f4dda20 100644 --- a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/IAstVisitor.java +++ b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/IAstVisitor.java @@ -110,6 +110,7 @@ import com.aliyun.fastmodel.core.tree.statement.show.ConditionElement; import com.aliyun.fastmodel.core.tree.statement.show.LikeCondition; import com.aliyun.fastmodel.core.tree.statement.show.WhereCondition; +import com.aliyun.fastmodel.core.tree.statement.table.index.IndexExpr; /** * AST visitor interface @@ -1354,4 +1355,8 @@ default R visitHexLiteral(HexLiteral hexLiteral, C context) { default R visitJsonDataType(JsonDataType jsonDataType, C context) { return visitRowDataType(jsonDataType, context); } + + default R visitIndexExpr(IndexExpr indexExpr, C context) { + return visitNode(indexExpr, context); + } } diff --git a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/expr/enums/BitOperator.java b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/expr/enums/BitOperator.java index 5f4d409..c68f0ce 100644 --- a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/expr/enums/BitOperator.java +++ b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/expr/enums/BitOperator.java @@ -43,6 +43,16 @@ public enum BitOperator { */ NOT_MARK("!"), + /** + * << + */ + SHIFT_LEFT("<<"), + + /** + * >> + */ + SHIFT_RIGHT(">>"), + /** * ^ */ diff --git a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/expr/enums/ComparisonOperator.java b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/expr/enums/ComparisonOperator.java index 808e941..d915eee 100644 --- a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/expr/enums/ComparisonOperator.java +++ b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/expr/enums/ComparisonOperator.java @@ -56,12 +56,13 @@ public enum ComparisonOperator { */ NOT_EQUAL_MS("!="), + NS_EQUAL("<=>"), + /** * is distinct from */ IS_DISTINCT_FROM("IS DISTINCT FROM"); - /** * code */ diff --git a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/expr/literal/EscapeStringLiteral.java b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/expr/literal/EscapeStringLiteral.java index 82179d1..4b1095b 100644 --- a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/expr/literal/EscapeStringLiteral.java +++ b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/expr/literal/EscapeStringLiteral.java @@ -9,7 +9,7 @@ package com.aliyun.fastmodel.core.tree.expr.literal; import com.aliyun.fastmodel.core.tree.IAstVisitor; -import lombok.Data; +import lombok.Getter; /** * escape string literal @@ -17,7 +17,7 @@ * @author panguanjing * @date 2022/6/10 */ -@Data +@Getter public class EscapeStringLiteral extends StringLiteral { /** * escape value diff --git a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/statement/table/CreateIndex.java b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/statement/table/CreateIndex.java index 089fef4..266773d 100644 --- a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/statement/table/CreateIndex.java +++ b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/statement/table/CreateIndex.java @@ -24,7 +24,7 @@ import com.aliyun.fastmodel.core.tree.QualifiedName; import com.aliyun.fastmodel.core.tree.statement.BaseOperatorStatement; import com.aliyun.fastmodel.core.tree.statement.constants.StatementType; -import com.aliyun.fastmodel.core.tree.statement.table.index.IndexColumnName; +import com.aliyun.fastmodel.core.tree.statement.table.index.IndexSortKey; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -40,13 +40,13 @@ public class CreateIndex extends BaseOperatorStatement { private final QualifiedName tableName; - private final List indexColumnNameList; + private final List indexColumnNameList; private final List propertyList; public CreateIndex(QualifiedName qualifiedName, QualifiedName tableName, - List indexColumnNameList, - List propertyList) { + List indexColumnNameList, + List propertyList) { super(qualifiedName); this.tableName = tableName; this.indexColumnNameList = indexColumnNameList; @@ -55,9 +55,9 @@ public CreateIndex(QualifiedName qualifiedName, QualifiedName tableName, } public CreateIndex(NodeLocation nodeLocation, String origin, - QualifiedName qualifiedName, QualifiedName tableName, - List indexColumnNameList, - List propertyList) { + QualifiedName qualifiedName, QualifiedName tableName, + List indexColumnNameList, + List propertyList) { super(nodeLocation, origin, qualifiedName); this.tableName = tableName; this.indexColumnNameList = indexColumnNameList; diff --git a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/statement/table/index/IndexColumnName.java b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/statement/table/index/IndexColumnName.java index b89a1f5..0dada33 100644 --- a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/statement/table/index/IndexColumnName.java +++ b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/statement/table/index/IndexColumnName.java @@ -1,24 +1,15 @@ /* - * Copyright 2021-2022 Alibaba Group Holding Ltd. - * - * Licensed 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. + * Copyright (c) 2021. Aliyun.com All right reserved. This software is the + * confidential and proprietary information of Aliyun.com ("Confidential + * Information"). You shall not disclose such Confidential Information and shall + * use it only in accordance with the terms of the license agreement you entered + * into with Aliyun.com. */ package com.aliyun.fastmodel.core.tree.statement.table.index; import java.util.List; -import com.aliyun.fastmodel.core.tree.AbstractFmlNode; import com.aliyun.fastmodel.core.tree.AstVisitor; import com.aliyun.fastmodel.core.tree.Node; import com.aliyun.fastmodel.core.tree.expr.Identifier; @@ -35,7 +26,7 @@ */ @Getter @EqualsAndHashCode(callSuper = false) -public class IndexColumnName extends AbstractFmlNode { +public class IndexColumnName extends IndexSortKey { private final Identifier columnName; diff --git a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/statement/table/index/IndexExpr.java b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/statement/table/index/IndexExpr.java new file mode 100644 index 0000000..f6ce498 --- /dev/null +++ b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/statement/table/index/IndexExpr.java @@ -0,0 +1,44 @@ +package com.aliyun.fastmodel.core.tree.statement.table.index; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.AstVisitor; +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.core.tree.Node; +import com.aliyun.fastmodel.core.tree.expr.BaseExpression; +import com.google.common.collect.ImmutableList; +import lombok.Getter; + +/** + * index expr + * + * @author panguanjing + * @date 2024/2/8 + */ +@Getter +public class IndexExpr extends IndexSortKey { + + private final BaseExpression expression; + + private final SortType sortType; + + public IndexExpr(BaseExpression expression, SortType sortType) { + this.expression = expression; + this.sortType = sortType; + } + + @Override + public R accept(IAstVisitor visitor, C context) { + return visitor.visitIndexExpr(this, context); + } + + @Override + public R accept(AstVisitor visitor, C context) { + return visitor.visitIndexExpr(this, context); + } + + @Override + public List getChildren() { + return ImmutableList.of(expression); + } +} diff --git a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/statement/table/index/IndexSortKey.java b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/statement/table/index/IndexSortKey.java new file mode 100644 index 0000000..c89b094 --- /dev/null +++ b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/statement/table/index/IndexSortKey.java @@ -0,0 +1,12 @@ +package com.aliyun.fastmodel.core.tree.statement.table.index; + +import com.aliyun.fastmodel.core.tree.AbstractFmlNode; + +/** + * index sort key + * + * @author panguanjing + * @date 2024/2/8 + */ +public abstract class IndexSortKey extends AbstractFmlNode { +} diff --git a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/statement/table/index/SortType.java b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/statement/table/index/SortType.java index f74c041..b8e78eb 100644 --- a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/statement/table/index/SortType.java +++ b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/statement/table/index/SortType.java @@ -1,17 +1,9 @@ /* - * Copyright 2021-2022 Alibaba Group Holding Ltd. - * - * Licensed 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. + * Copyright (c) 2021. Aliyun.com All right reserved. This software is the + * confidential and proprietary information of Aliyun.com ("Confidential + * Information"). You shall not disclose such Confidential Information and shall + * use it only in accordance with the terms of the license agreement you entered + * into with Aliyun.com. */ package com.aliyun.fastmodel.core.tree.statement.table.index; diff --git a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/statement/table/index/TableIndex.java b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/statement/table/index/TableIndex.java index e50953f..e171a8a 100644 --- a/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/statement/table/index/TableIndex.java +++ b/fastmodel-core/src/main/java/com/aliyun/fastmodel/core/tree/statement/table/index/TableIndex.java @@ -1,17 +1,9 @@ /* - * Copyright 2021-2022 Alibaba Group Holding Ltd. - * - * Licensed 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. + * Copyright (c) 2021. Aliyun.com All right reserved. This software is the + * confidential and proprietary information of Aliyun.com ("Confidential + * Information"). You shall not disclose such Confidential Information and shall + * use it only in accordance with the terms of the license agreement you entered + * into with Aliyun.com. */ package com.aliyun.fastmodel.core.tree.statement.table.index; @@ -22,8 +14,7 @@ import com.aliyun.fastmodel.core.tree.Node; import com.aliyun.fastmodel.core.tree.Property; import com.aliyun.fastmodel.core.tree.expr.Identifier; -import com.aliyun.fastmodel.core.tree.statement.constants.ConstraintType; -import com.aliyun.fastmodel.core.tree.statement.table.constraint.BaseConstraint; +import com.aliyun.fastmodel.core.tree.statement.table.TableElement; import com.google.common.collect.ImmutableList; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -36,18 +27,17 @@ */ @Getter @EqualsAndHashCode(callSuper = false) -public class TableIndex extends BaseConstraint { +public class TableIndex extends TableElement { private final Identifier indexName; - private final List indexColumnNames; + private final List indexColumnNames; private final List properties; public TableIndex(Identifier indexName, - List indexColumnNames, + List indexColumnNames, List properties) { - super(indexName, ConstraintType.INDEX); this.indexName = indexName; this.indexColumnNames = indexColumnNames; this.properties = properties; diff --git a/fastmodel-dependencies-bom/pom.xml b/fastmodel-dependencies-bom/pom.xml index 6b1e0bf..e00c67a 100644 --- a/fastmodel-dependencies-bom/pom.xml +++ b/fastmodel-dependencies-bom/pom.xml @@ -26,7 +26,7 @@ ${revision} - 0.5.10 + 0.5.11 1.1.0 3.17.1 4.13.1 @@ -44,7 +44,7 @@ jdk11 - 0.5.10 + 0.5.11 true @@ -62,7 +62,7 @@ jdk8 - 0.5.10-jdk8 + 0.5.11-jdk8 diff --git a/fastmodel-parser/src/main/java/com/aliyun/fastmodel/parser/visitor/TableVisitor.java b/fastmodel-parser/src/main/java/com/aliyun/fastmodel/parser/visitor/TableVisitor.java index 413b8a8..b5a0f2c 100644 --- a/fastmodel-parser/src/main/java/com/aliyun/fastmodel/parser/visitor/TableVisitor.java +++ b/fastmodel-parser/src/main/java/com/aliyun/fastmodel/parser/visitor/TableVisitor.java @@ -62,6 +62,7 @@ import com.aliyun.fastmodel.core.tree.statement.table.constraint.TimePeriodConstraint; import com.aliyun.fastmodel.core.tree.statement.table.constraint.UniqueConstraint; import com.aliyun.fastmodel.core.tree.statement.table.index.IndexColumnName; +import com.aliyun.fastmodel.core.tree.statement.table.index.IndexSortKey; import com.aliyun.fastmodel.core.tree.statement.table.index.SortType; import com.aliyun.fastmodel.core.tree.statement.table.index.TableIndex; import com.aliyun.fastmodel.core.tree.util.IdentifierUtil; @@ -234,7 +235,7 @@ public Node visitDropConstraint(DropConstraintContext ctx) { @Override public Node visitTableIndex(TableIndexContext ctx) { - List list = visit(ctx.indexColumnNames().indexColumnName(), IndexColumnName.class); + List list = visit(ctx.indexColumnNames().indexColumnName(), IndexSortKey.class); List indexProperties = ImmutableList.of(); if (ctx.indexOption() != null) { indexProperties = getProperties(ctx.indexOption().setProperties()); @@ -397,7 +398,7 @@ public Node visitCreateIndex(CreateIndexContext ctx) { return new CreateIndex( getQualifiedName(ctx.qualifiedName()), getQualifiedName(ctx.tableName()), - visit(ctx.indexColumnNames().indexColumnName(), IndexColumnName.class), + visit(ctx.indexColumnNames().indexColumnName(), IndexSortKey.class), list ); } diff --git a/fastmodel-parser/src/test/java/com/aliyun/fastmodel/parser/statement/QueryTest.java b/fastmodel-parser/src/test/java/com/aliyun/fastmodel/parser/statement/QueryTest.java index 56fcc5b..656c97c 100644 --- a/fastmodel-parser/src/test/java/com/aliyun/fastmodel/parser/statement/QueryTest.java +++ b/fastmodel-parser/src/test/java/com/aliyun/fastmodel/parser/statement/QueryTest.java @@ -32,7 +32,6 @@ import com.aliyun.fastmodel.core.tree.relation.Join; import com.aliyun.fastmodel.core.tree.relation.join.JoinOn; import com.aliyun.fastmodel.core.tree.relation.join.JoinToken; -import com.aliyun.fastmodel.core.tree.relation.querybody.BaseQueryBody; import com.aliyun.fastmodel.core.tree.relation.querybody.QuerySpecification; import com.aliyun.fastmodel.core.tree.relation.querybody.Table; import com.aliyun.fastmodel.core.tree.statement.select.Hint; @@ -76,40 +75,40 @@ public void testUnion() { + " pk1\n" + " , pk2\n" + " , pk3\n" - + " , null dim1\n" - + " , null dim2\n" - + " , null dim3\n" + + " , NULL dim1\n" + + " , NULL dim2\n" + + " , NULL dim3\n" + " , ind1\n" + " , ind2\n" - + " , null ind3\n" - + " , null ind4\n" - + " , null ind5\n" + + " , NULL ind3\n" + + " , NULL ind4\n" + + " , NULL ind5\n" + " FROM\n" + " t1\n" + "UNION ALL SELECT\n" + " pk1\n" + " , pk2\n" + " , pk3\n" - + " , null dim1\n" - + " , null dim2\n" - + " , null dim3\n" - + " , null ind1\n" - + " , null ind2\n" + + " , NULL dim1\n" + + " , NULL dim2\n" + + " , NULL dim3\n" + + " , NULL ind1\n" + + " , NULL ind2\n" + " , ind3\n" - + " , null ind4\n" - + " , null ind5\n" + + " , NULL ind4\n" + + " , NULL ind5\n" + " FROM\n" + " t2\n" + "UNION ALL SELECT\n" + " t2.pk1 pk1\n" + " , t2.pk2 pk2\n" + " , t2.pk3 pk3\n" - + " , null dim1\n" - + " , null dim2\n" + + " , NULL dim1\n" + + " , NULL dim2\n" + " , t2.dim3 dim3\n" - + " , null ind1\n" - + " , null ind2\n" - + " , null ind3\n" + + " , NULL ind1\n" + + " , NULL ind2\n" + + " , NULL ind3\n" + " , t2.ind4 ind4\n" + " , t2.ind5 ind5\n" + " FROM\n" diff --git a/fastmodel-transform/fastmodel-transform-api/pom.xml b/fastmodel-transform/fastmodel-transform-api/pom.xml index cf12fd9..8e53251 100644 --- a/fastmodel-transform/fastmodel-transform-api/pom.xml +++ b/fastmodel-transform/fastmodel-transform-api/pom.xml @@ -46,5 +46,9 @@ fastmodel-compare ${project.parent.version} + + com.alibaba + fastjson + \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/client/converter/BaseClientConverter.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/client/converter/BaseClientConverter.java index 1c0f881..db85ab2 100644 --- a/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/client/converter/BaseClientConverter.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/client/converter/BaseClientConverter.java @@ -18,6 +18,7 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; +import com.aliyun.fastmodel.core.parser.LanguageParser; import com.aliyun.fastmodel.core.tree.Comment; import com.aliyun.fastmodel.core.tree.Node; import com.aliyun.fastmodel.core.tree.Property; @@ -49,6 +50,10 @@ import com.aliyun.fastmodel.core.tree.statement.table.constraint.BaseConstraint; import com.aliyun.fastmodel.core.tree.statement.table.constraint.PrimaryConstraint; import com.aliyun.fastmodel.core.tree.statement.table.constraint.UniqueConstraint; +import com.aliyun.fastmodel.core.tree.statement.table.index.IndexColumnName; +import com.aliyun.fastmodel.core.tree.statement.table.index.IndexExpr; +import com.aliyun.fastmodel.core.tree.statement.table.index.IndexSortKey; +import com.aliyun.fastmodel.core.tree.statement.table.index.SortType; import com.aliyun.fastmodel.core.tree.statement.table.index.TableIndex; import com.aliyun.fastmodel.core.tree.util.IdentifierUtil; import com.aliyun.fastmodel.core.tree.util.StringLiteralUtil; @@ -57,6 +62,9 @@ import com.aliyun.fastmodel.transform.api.client.dto.constraint.Constraint; import com.aliyun.fastmodel.transform.api.client.dto.constraint.ConstraintType; import com.aliyun.fastmodel.transform.api.client.dto.constraint.OutlineConstraintType; +import com.aliyun.fastmodel.transform.api.client.dto.index.Index; +import com.aliyun.fastmodel.transform.api.client.dto.index.IndexKey; +import com.aliyun.fastmodel.transform.api.client.dto.index.IndexSortType; import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; import com.aliyun.fastmodel.transform.api.client.dto.table.Column; import com.aliyun.fastmodel.transform.api.client.dto.table.Table; @@ -64,6 +72,8 @@ import com.aliyun.fastmodel.transform.api.context.TransformContext; import com.aliyun.fastmodel.transform.api.datatype.simple.ISimpleDataTypeName; import com.aliyun.fastmodel.transform.api.datatype.simple.SimpleDataTypeName; +import com.aliyun.fastmodel.transform.api.extension.client.constraint.UniqueKeyExprClientConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.UniqueKeyExprConstraint; import com.aliyun.fastmodel.transform.api.util.StringJoinUtil; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; @@ -87,13 +97,20 @@ public abstract class BaseClientConverter implements public static final int FIRST_INDEX = 1; public static final int THIRD_INDEX = 3; + /** + * 获取语言解析器 + * + * @return + */ + public abstract LanguageParser getLanguageParser(); + /** * get DataType * * @param column * @return */ - protected abstract BaseDataType getDataType(Column column); + public abstract BaseDataType getDataType(Column column); /** * get property converter @@ -122,6 +139,10 @@ protected Boolean isExternal(CreateTable createTable) { return false; } + protected String formatExpression(BaseExpression baseExpression) { + return baseExpression.toString(); + } + /** * @param table * @return {@link Node} @@ -146,6 +167,7 @@ public Node covertToNode(Table table, TableConfig tableConfig) { .tableIndex(tableIndexList) .comment(comment) .constraints(constraints) + .tableIndex(tableIndexList) .properties(properties) .build(); } @@ -168,6 +190,7 @@ public Table convertToTable(Node table, T context) { List columns = toTableColumns(createTable); List constraints = toOutlineConstraint(createTable); List properties = toBaseClientProperty(createTable); + List indices = toIndex(createTable); return Table.builder() .ifNotExist(createTable.isNotExists()) .external(external) @@ -177,11 +200,113 @@ public Table convertToTable(Node table, T context) { .lifecycleSeconds(toLifeCycleSeconds(createTable)) .columns(columns) .constraints(constraints) + .indices(indices) .properties(properties) .build(); } + protected List toIndex(CreateTable createTable) { + if (createTable.isIndexEmpty()) { + return Collections.emptyList(); + } + List tableIndexList = createTable.getTableIndexList(); + List indices = Lists.newArrayList(); + for (TableIndex index : tableIndexList) { + List indexSortKeys = index.getIndexColumnNames(); + List collect = indexSortKeys.stream().map(i -> getIndexKey(i)).filter(Objects::nonNull).collect(Collectors.toList()); + List es = Lists.newArrayList(); + List properties = index.getProperties(); + if (properties != null) { + for (Property p : properties) { + BaseClientProperty baseClientProperty = getPropertyConverter().create(p.getName(), p.getValue()); + es.add(baseClientProperty); + } + } + Index constraint = Index.builder() + .name(index.getIndexName().getValue()) + .indexKeys(collect) + .properties(es) + .build(); + indices.add(constraint); + } + return indices; + } + + private IndexKey getIndexKey(IndexSortKey i) { + IndexKey indexKey = IndexKey.builder().build(); + if (i instanceof IndexColumnName) { + IndexColumnName indexColumnName = (IndexColumnName)i; + String column = indexColumnName.getColumnName().toString(); + indexKey.setColumn(column); + if (indexColumnName.getColumnLength() != null) { + indexKey.setLength(indexColumnName.getColumnLength().getValue()); + } + indexKey.setSortType(getIndexSortType(indexColumnName.getSortType())); + } + if (i instanceof IndexExpr) { + IndexExpr indexExpr = (IndexExpr)i; + BaseExpression expression = indexExpr.getExpression(); + String formatExpression = formatExpression(expression); + indexKey.setExpression(formatExpression); + indexKey.setSortType(getIndexSortType(indexExpr.getSortType())); + } + return indexKey; + } + + private IndexSortType getIndexSortType(SortType sortType) { + if (sortType == SortType.ASC) { + return IndexSortType.ASC; + } + if (sortType == SortType.DESC) { + return IndexSortType.DESC; + } + return null; + } + + protected List toTableIndex(Table table, List columns) { + if (table == null || CollectionUtils.isEmpty(table.getIndices())) { + return Collections.emptyList(); + } + return table.getIndices().stream().map(indexConstraint -> { + Identifier indexName = new Identifier(indexConstraint.getName()); + List indexSortKeys = null; + List indexKeys = indexConstraint.getIndexKeys(); + if (indexKeys != null) { + indexSortKeys = indexKeys.stream() + .map(indexKey -> getIndexSortKey(indexKey)).collect(Collectors.toList()); + } + + List properties = null; + if (CollectionUtils.isNotEmpty(indexConstraint.getProperties())) { + properties = indexConstraint.getProperties().stream().map(property -> { + return new Property(property.getKey(), (String)property.getValue()); + }).collect(Collectors.toList()); + } + return new TableIndex(indexName, indexSortKeys, properties); + }).collect(Collectors.toList()); + } + + private IndexSortKey getIndexSortKey(IndexKey indexKey) { + String column = indexKey.getColumn(); + if (StringUtils.isNotBlank(column)) { + LongLiteral length = indexKey.getLength() != null ? new LongLiteral(String.valueOf(indexKey.getLength())) : null; + return new IndexColumnName(new Identifier(column), length, getSortType(indexKey.getSortType())); + } else { + BaseExpression o = (BaseExpression)getLanguageParser().parseExpression(indexKey.getExpression()); + IndexExpr indexExpr = new IndexExpr(o, getSortType(indexKey.getSortType())); + return indexExpr; + } + } + private SortType getSortType(IndexSortType sortType) { + if (sortType == IndexSortType.ASC) { + return SortType.ASC; + } + if (sortType == IndexSortType.DESC) { + return SortType.DESC; + } + return null; + } protected String toSchema(CreateTable createTable, T transformContext) { QualifiedName qualifiedName = createTable.getQualifiedName(); @@ -199,6 +324,13 @@ protected String toSchema(CreateTable createTable, T transformContext) { return transformContext.getSchema(); } + /** + * get database + * + * @param createTable + * @param database + * @return + */ protected String toDatabase(CreateTable createTable, String database) { QualifiedName qualifiedName = createTable.getQualifiedName(); boolean isThirdSchema = qualifiedName.isJoinPath() && qualifiedName.getOriginalParts().size() == THIRD_INDEX; @@ -430,10 +562,6 @@ protected PartitionedBy toPartitionedBy(Table table, List columns) { return new PartitionedBy(collect); } - protected List toTableIndex(Table table, List columns) { - return Collections.emptyList(); - } - /** * to constraint * @@ -464,14 +592,47 @@ protected List toConstraint(List columns, List indexSortKeys = toIndexSortKey(u); + UniqueKeyExprConstraint keyExprConstraint = new UniqueKeyExprConstraint( + constraintName, null, indexSortKeys, null + ); + constraintList.add(keyExprConstraint); + } else { + UniqueConstraint primaryConstraint = new UniqueConstraint(constraintName, + c.getColumns().stream().map(Identifier::new).collect(Collectors.toList())); + constraintList.add(primaryConstraint); + } } } return constraintList; } + private List toIndexSortKey(UniqueKeyExprClientConstraint u) { + if (CollectionUtils.isNotEmpty(u.getExpression())) { + return u.getExpression().stream().map( + c -> { + BaseExpression baseExpression = (BaseExpression)getLanguageParser().parseExpression(c); + IndexExpr indexExpr = new IndexExpr(baseExpression, null); + return indexExpr; + } + ).collect(Collectors.toList()); + } + if (CollectionUtils.isNotEmpty(u.getColumns())) { + return u.getColumns().stream().map( + c -> { + IndexColumnName indexColumnName = new IndexColumnName( + new Identifier(c), + null, null + ); + return indexColumnName; + } + ).collect(Collectors.toList()); + } + return null; + } + protected BaseConstraint setPrimaryConstraintColumns(List columns) { if (CollectionUtils.isEmpty(columns)) { return null; @@ -498,7 +659,6 @@ protected Column getColumn(ColumnDefinition c, boolean partitionKey, Integer par .id(c.getColName().getValue()) .name(c.getColName().getValue()) .comment(c.getCommentValue()) - .id(c.getColName().getValue()) .dataType(dataType.getTypeName().getValue()) .nullable(BooleanUtils.isNotTrue(c.getNotNull())) .primaryKey(BooleanUtils.isTrue(c.getPrimary())) @@ -623,4 +783,4 @@ public final boolean contains(List list, ColumnDefinition columnDefiniti return list.stream().anyMatch(c -> Objects.equals(new Identifier(c.getName()), columnDefinition.getColName())); } -} +} \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/client/dto/index/Index.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/client/dto/index/Index.java new file mode 100644 index 0000000..a5ed675 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/client/dto/index/Index.java @@ -0,0 +1,38 @@ +package com.aliyun.fastmodel.transform.api.client.dto.index; + +import java.util.List; + +import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Index 索引 + * + * @author panguanjing + * @date 2024/2/19 + */ +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Data +public class Index { + /** + * 索引名称 + */ + private String name; + + /** + * 列 + */ + private List indexKeys; + + + /** + * client properties + */ + private List properties; + +} diff --git a/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/client/dto/index/IndexKey.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/client/dto/index/IndexKey.java new file mode 100644 index 0000000..1a8137b --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/client/dto/index/IndexKey.java @@ -0,0 +1,23 @@ +package com.aliyun.fastmodel.transform.api.client.dto.index; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Desc: + * + * @author panguanjing + * @date 2024/2/19 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class IndexKey { + private String column; + private String expression; + private Long length; + private IndexSortType sortType; +} diff --git a/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/client/dto/index/IndexSortType.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/client/dto/index/IndexSortType.java new file mode 100644 index 0000000..4e9e5c5 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/client/dto/index/IndexSortType.java @@ -0,0 +1,9 @@ +package com.aliyun.fastmodel.transform.api.client.dto.index; + +/** + * sort type + */ +public enum IndexSortType { + ASC, + DESC +} diff --git a/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/client/dto/table/Table.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/client/dto/table/Table.java index 55a0b43..7e52637 100644 --- a/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/client/dto/table/Table.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/client/dto/table/Table.java @@ -11,6 +11,7 @@ import java.util.List; import com.aliyun.fastmodel.transform.api.client.dto.constraint.Constraint; +import com.aliyun.fastmodel.transform.api.client.dto.index.Index; import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; import lombok.AllArgsConstructor; import lombok.Builder; @@ -23,6 +24,7 @@ * * @author panguanjing * @date 2022/6/6 + * @date 2024/2/19 add the index */ @Data @Builder @@ -71,6 +73,11 @@ public class Table { */ private List constraints; + /** + * 索引列表 + */ + private List indices; + /** * 生命周期, 单位秒 */ diff --git a/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/dialect/DialectMeta.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/dialect/DialectMeta.java index 6ebb51e..30beabc 100644 --- a/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/dialect/DialectMeta.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/dialect/DialectMeta.java @@ -48,6 +48,16 @@ public class DialectMeta { */ public static final DialectMeta DEFAULT_STARROCKS = createDefault(DialectName.STARROCKS); + /** + * starRocks + */ + public static final DialectMeta DEFAULT_DORIS = createDefault(DialectName.DORIS); + + /** + * oceanbase mysql + */ + public static final DialectMeta DEFAULT_OB_MYSQL = createDefault(DialectName.OB_MYSQL); + /** * 引擎的名字,唯一标示,大小写不敏感 */ diff --git a/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/dialect/DialectName.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/dialect/DialectName.java index 6d0bd2b..fc3caf7 100644 --- a/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/dialect/DialectName.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/dialect/DialectName.java @@ -117,9 +117,22 @@ public enum DialectName implements IDialectName { /** * StarRocks */ - STARROCKS(Constants.STARROCKS) + STARROCKS(Constants.STARROCKS), - ; + /** + * Doris + */ + DORIS(Constants.DORIS), + + /** + * ObMysql + */ + OB_MYSQL(Constants.OB_MYSQL), + + /** + * ObOracle + */ + OB_ORACLE(Constants.OB_ORACLE); @Getter private final String value; @@ -147,6 +160,9 @@ public static class Constants { public static final String SQLITE = "SQLITE"; public static final String JSON = "JSON"; public static final String STARROCKS = "STAR_ROCKS"; + public static final String DORIS = "DORIS"; + public static final String OB_MYSQL = "OB_MYSQL"; + public static final String OB_ORACLE = "OB_ORACLE"; } public static DialectName getByCode(String name) { diff --git a/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/domain/factory/DomainFactorys.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/domain/factory/DomainFactorySingleton.java similarity index 96% rename from fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/domain/factory/DomainFactorys.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/domain/factory/DomainFactorySingleton.java index aac3966..8c40c22 100644 --- a/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/domain/factory/DomainFactorys.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/domain/factory/DomainFactorySingleton.java @@ -26,7 +26,7 @@ * @author panguanjing * @date 2021/12/12 */ -public class DomainFactorys { +public class DomainFactorySingleton { private static final TableDomainFactory INSTANCE = new TableDomainFactory(); diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/constraint/StarRocksConstraintType.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/constraint/ClientConstraintType.java similarity index 66% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/constraint/StarRocksConstraintType.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/constraint/ClientConstraintType.java index 9de9b3d..de65d3d 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/constraint/StarRocksConstraintType.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/constraint/ClientConstraintType.java @@ -1,4 +1,4 @@ -package com.aliyun.fastmodel.transform.starrocks.client.constraint; +package com.aliyun.fastmodel.transform.api.extension.client.constraint; import com.aliyun.fastmodel.transform.api.client.dto.constraint.ConstraintType; import lombok.Getter; @@ -10,7 +10,7 @@ * @date 2023/12/13 */ @Getter -public enum StarRocksConstraintType implements ConstraintType { +public enum ClientConstraintType implements ConstraintType { AGGREGATE_KEY("aggregate_key"), @@ -24,10 +24,6 @@ public enum StarRocksConstraintType implements ConstraintType { */ PRIMARY_KEY(com.aliyun.fastmodel.core.tree.statement.constants.ConstraintType.PRIMARY_KEY.getCode()), - /** - * index - */ - INDEX(com.aliyun.fastmodel.core.tree.statement.constants.ConstraintType.INDEX.getCode()), /** * order by */ @@ -40,15 +36,15 @@ public enum StarRocksConstraintType implements ConstraintType { private final String code; - StarRocksConstraintType(String code) {this.code = code;} + ClientConstraintType(String code) {this.code = code;} @Override public String getCode() { return code; } - public static StarRocksConstraintType getByValue(String value) { - for (StarRocksConstraintType starRocksConstraintType : StarRocksConstraintType.values()) { + public static ClientConstraintType getByValue(String value) { + for (ClientConstraintType starRocksConstraintType : ClientConstraintType.values()) { if (starRocksConstraintType.code.equalsIgnoreCase(value)) { return starRocksConstraintType; } diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/constraint/StarRocksDistributeConstraint.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/constraint/DistributeClientConstraint.java similarity index 62% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/constraint/StarRocksDistributeConstraint.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/constraint/DistributeClientConstraint.java index 8c84afc..39a8cb4 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/constraint/StarRocksDistributeConstraint.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/constraint/DistributeClientConstraint.java @@ -1,4 +1,4 @@ -package com.aliyun.fastmodel.transform.starrocks.client.constraint; +package com.aliyun.fastmodel.transform.api.extension.client.constraint; import com.aliyun.fastmodel.transform.api.client.dto.constraint.Constraint; import lombok.Data; @@ -12,7 +12,7 @@ */ @EqualsAndHashCode(callSuper = true) @Data -public class StarRocksDistributeConstraint extends Constraint { +public class DistributeClientConstraint extends Constraint { /** * 是否random */ @@ -23,7 +23,7 @@ public class StarRocksDistributeConstraint extends Constraint { */ private Integer bucket; - public StarRocksDistributeConstraint() { - this.setType(StarRocksConstraintType.DISTRIBUTE); + public DistributeClientConstraint() { + this.setType(ClientConstraintType.DISTRIBUTE); } } diff --git a/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/constraint/UniqueKeyExprClientConstraint.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/constraint/UniqueKeyExprClientConstraint.java new file mode 100644 index 0000000..3bd0b06 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/constraint/UniqueKeyExprClientConstraint.java @@ -0,0 +1,22 @@ +package com.aliyun.fastmodel.transform.api.extension.client.constraint; + +import java.util.List; + +import com.aliyun.fastmodel.transform.api.client.dto.constraint.Constraint; +import lombok.Data; + +/** + * unique key expr constraint + * + * @author panguanjing + * @date 2024/2/19 + */ +@Data +public class UniqueKeyExprClientConstraint extends Constraint { + + private List expression; + + public UniqueKeyExprClientConstraint() { + this.setType(ClientConstraintType.UNIQUE_KEY); + } +} diff --git a/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/converter/ExtensionClientConverter.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/converter/ExtensionClientConverter.java new file mode 100644 index 0000000..cd5d587 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/converter/ExtensionClientConverter.java @@ -0,0 +1,684 @@ +package com.aliyun.fastmodel.transform.api.extension.client.converter; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import com.aliyun.fastmodel.core.tree.Node; +import com.aliyun.fastmodel.core.tree.Property; +import com.aliyun.fastmodel.core.tree.QualifiedName; +import com.aliyun.fastmodel.core.tree.datatype.BaseDataType; +import com.aliyun.fastmodel.core.tree.datatype.IDataTypeName; +import com.aliyun.fastmodel.core.tree.datatype.IDataTypeName.Dimension; +import com.aliyun.fastmodel.core.tree.expr.BaseExpression; +import com.aliyun.fastmodel.core.tree.expr.Identifier; +import com.aliyun.fastmodel.core.tree.expr.atom.FunctionCall; +import com.aliyun.fastmodel.core.tree.expr.enums.DateTimeEnum; +import com.aliyun.fastmodel.core.tree.expr.literal.IntervalLiteral; +import com.aliyun.fastmodel.core.tree.expr.literal.ListStringLiteral; +import com.aliyun.fastmodel.core.tree.expr.literal.LongLiteral; +import com.aliyun.fastmodel.core.tree.expr.literal.StringLiteral; +import com.aliyun.fastmodel.core.tree.statement.table.ColumnDefinition; +import com.aliyun.fastmodel.core.tree.statement.table.CreateTable; +import com.aliyun.fastmodel.core.tree.statement.table.PartitionedBy; +import com.aliyun.fastmodel.core.tree.statement.table.constraint.BaseConstraint; +import com.aliyun.fastmodel.core.tree.util.IdentifierUtil; +import com.aliyun.fastmodel.core.tree.util.StringLiteralUtil; +import com.aliyun.fastmodel.transform.api.client.converter.BaseClientConverter; +import com.aliyun.fastmodel.transform.api.client.dto.constraint.Constraint; +import com.aliyun.fastmodel.transform.api.client.dto.constraint.ConstraintType; +import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; +import com.aliyun.fastmodel.transform.api.client.dto.property.StringProperty; +import com.aliyun.fastmodel.transform.api.client.dto.table.Column; +import com.aliyun.fastmodel.transform.api.client.dto.table.Table; +import com.aliyun.fastmodel.transform.api.context.ReverseContext; +import com.aliyun.fastmodel.transform.api.context.TransformContext; +import com.aliyun.fastmodel.transform.api.datatype.simple.ISimpleDataTypeName; +import com.aliyun.fastmodel.transform.api.datatype.simple.SimpleDataTypeName; +import com.aliyun.fastmodel.transform.api.extension.client.constraint.ClientConstraintType; +import com.aliyun.fastmodel.transform.api.extension.client.constraint.DistributeClientConstraint; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.ColumnExpressionPartitionProperty; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.ListPartitionProperty; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.MultiRangePartitionProperty; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.SingleRangePartitionProperty; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.TablePartitionRaw; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.TimeExpressionPartitionProperty; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.ArrayClientPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.BaseClientPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.ColumnExpressionClientPartition; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.LessThanClientPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.ListClientPartition; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.MultiRangeClientPartition; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.PartitionClientValue; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.SingleRangeClientPartition; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.TimeExpressionClientPartition; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.AggregateKeyConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.DuplicateKeyConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.DistributeConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.OrderByConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.ExpressionPartitionBy; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.ListPartitionedBy; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.RangePartitionedBy; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.MultiItemListPartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.MultiRangePartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.PartitionDesc; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.SingleItemListPartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.SingleRangePartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.ArrayPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.LessThanPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.ListPartitionValue; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.PartitionKey; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.PartitionValue; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; + +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_EXPRESSION_PARTITION; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_LIST_PARTITION; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_PARTITION_RAW; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_RANGE_PARTITION; + +/** + * ExtensionClientConverter + * + * @author panguanjing + * @date 2024/1/21 + */ +public abstract class ExtensionClientConverter extends BaseClientConverter { + + public static final String UUID = "uuid"; + public static final String UUID_NUMERIC = "uuid_numeric"; + public static final String SUFFIX = "()"; + + /** + * 根据dataTypeName返回类型定义 + * + * @param dataTypeName + * @return + */ + public abstract IDataTypeName getDataTypeName(String dataTypeName); + + /** + * 根据节点返回文本信息 + * + * @param node + * @return + */ + public abstract String getRaw(Node node); + + @Override + public List toBaseClientProperty(CreateTable createTable) { + List propertyList = Lists.newArrayList(); + if (!createTable.isPropertyEmpty()) { + List properties = createTable.getProperties(); + for (Property property : properties) { + BaseClientProperty baseClientProperty = getPropertyConverter().create(property.getName(), property.getValue()); + propertyList.add(baseClientProperty); + } + } + PartitionedBy partitionedBy = createTable.getPartitionedBy(); + if (partitionedBy instanceof RangePartitionedBy) { + processRangePartition((RangePartitionedBy)partitionedBy, propertyList); + } + + if (partitionedBy instanceof ListPartitionedBy) { + processListPartition((ListPartitionedBy)partitionedBy, propertyList); + } + + if (partitionedBy instanceof ExpressionPartitionBy) { + processExpressionPartition((ExpressionPartitionBy)partitionedBy, propertyList); + } + + return propertyList; + } + + private void processRangePartition(RangePartitionedBy rangePartitionedBy, List propertyList) { + List rangePartitions = rangePartitionedBy.getRangePartitions(); + List list = Lists.newArrayList(); + //结构化的返回 + if (rangePartitions != null) { + for (PartitionDesc partitionDesc : rangePartitions) { + BaseClientProperty baseClientProperty = parseRangePartition(partitionDesc); + if (baseClientProperty != null) { + list.add(baseClientProperty); + } + } + } + //如果解析不了,那么使用visitor的方式进行解析 + if (list.isEmpty()) { + TablePartitionRaw baseClientProperty = new TablePartitionRaw(); + baseClientProperty.setKey(TABLE_PARTITION_RAW.getValue()); + String raw = getRaw(rangePartitionedBy); + baseClientProperty.setValueString(raw); + propertyList.add(baseClientProperty); + } else { + propertyList.addAll(list); + } + } + + private void processListPartition(ListPartitionedBy listPartitionedBy, List propertyList) { + List listPartitions = listPartitionedBy.getListPartitions(); + //结构化的返回 + List list = Lists.newArrayList(); + if (listPartitions != null) { + for (PartitionDesc partitionDesc : listPartitions) { + BaseClientProperty baseClientProperty = parseListPartition(partitionDesc); + if (baseClientProperty != null) { + list.add(baseClientProperty); + } + } + } + + //如果解析不了,那么使用visitor的方式进行解析 + if (list.isEmpty()) { + String raw = getRaw(listPartitionedBy); + StringProperty baseClientProperty = new StringProperty(); + baseClientProperty.setKey(TABLE_PARTITION_RAW.getValue()); + baseClientProperty.setValueString(raw); + propertyList.add(baseClientProperty); + } else { + propertyList.addAll(list); + } + } + + private void processExpressionPartition(ExpressionPartitionBy expressionPartitionBy, + List propertyList) { + FunctionCall functionCall = expressionPartitionBy.getFunctionCall(); + if (functionCall == null) { + // 列表达式 + ColumnExpressionClientPartition partition = new ColumnExpressionClientPartition(); + List columnNameList = expressionPartitionBy.getColumnDefinitions().stream() + .map(columnDefinition -> columnDefinition.getColName().getValue()) + .collect(Collectors.toList()); + partition.setColumnNameList(columnNameList); + + ColumnExpressionPartitionProperty columnExpressionPartitionProperty = new ColumnExpressionPartitionProperty(); + columnExpressionPartitionProperty.setValue(partition); + propertyList.add(columnExpressionPartitionProperty); + } else { + // 时间函数表达式 + TimeExpressionClientPartition timeExpressionClientPartition = new TimeExpressionClientPartition(); + timeExpressionClientPartition.setFuncName(functionCall.getFuncName().getFirst()); + if (expressionPartitionBy.getTimeUnitArg() != null) { + timeExpressionClientPartition.setTimeUnit(StringLiteralUtil.strip(expressionPartitionBy.getTimeUnitArg().getOrigin())); + } + if (expressionPartitionBy.getIntervalLiteralArg() != null) { + timeExpressionClientPartition.setInterval(expressionPartitionBy.getIntervalLiteralArg()); + } + + //property + TimeExpressionPartitionProperty timeExpressionPartitionProperty = new TimeExpressionPartitionProperty(); + timeExpressionPartitionProperty.setValue(timeExpressionClientPartition); + propertyList.add(timeExpressionPartitionProperty); + } + } + + /** + * 将partition desc转为 baseClientProperty + * + * @param partitionDesc + */ + private BaseClientProperty parseRangePartition(PartitionDesc partitionDesc) { + if (partitionDesc instanceof SingleRangePartition) { + SingleRangePartition singleRangePartition = (SingleRangePartition)partitionDesc; + SingleRangeClientPartition rangePartitionValue = new SingleRangeClientPartition(); + rangePartitionValue.setName(singleRangePartition.getName().getValue()); + rangePartitionValue.setIfNotExists(singleRangePartition.isIfNotExists()); + List propertyList = singleRangePartition.getPropertyList(); + if (propertyList != null && !propertyList.isEmpty()) { + LinkedHashMap linkedHashMap = Maps.newLinkedHashMap(); + for (Property p : propertyList) { + linkedHashMap.put(p.getName(), p.getValue()); + } + rangePartitionValue.setProperties(linkedHashMap); + } + BaseClientPartitionKey partitionKey = toClientPartitionKey(singleRangePartition.getPartitionKey()); + rangePartitionValue.setPartitionKey(partitionKey); + + //property + SingleRangePartitionProperty singleRangePartitionProperty = new SingleRangePartitionProperty(); + singleRangePartitionProperty.setValue(rangePartitionValue); + return singleRangePartitionProperty; + + } else if (partitionDesc instanceof MultiRangePartition) { + MultiRangePartition multiRangePartition = (MultiRangePartition)partitionDesc; + MultiRangeClientPartition multiRangePartitionValue = new MultiRangeClientPartition(); + ListPartitionValue start = multiRangePartition.getStart(); + String startRaw = getRaw(start); + multiRangePartitionValue.setStart(StringLiteralUtil.strip(startRaw)); + ListPartitionValue end = multiRangePartition.getEnd(); + String endRaw = getRaw(end); + multiRangePartitionValue.setEnd(StringLiteralUtil.strip(endRaw)); + if (multiRangePartition.getLongLiteral() != null) { + LongLiteral longLiteral = multiRangePartition.getLongLiteral(); + multiRangePartitionValue.setInterval(longLiteral.getValue()); + } + IntervalLiteral intervalLiteral = multiRangePartition.getIntervalLiteral(); + if (intervalLiteral != null) { + DateTimeEnum fromDateTime = intervalLiteral.getFromDateTime(); + multiRangePartitionValue.setDateTimeEnum(fromDateTime); + LongLiteral value = (LongLiteral)intervalLiteral.getValue(); + multiRangePartitionValue.setInterval(value.getValue()); + } + //property + MultiRangePartitionProperty multiRangePartitionProperty = new MultiRangePartitionProperty(); + multiRangePartitionProperty.setValue(multiRangePartitionValue); + return multiRangePartitionProperty; + } + return null; + } + + private BaseClientProperty parseListPartition(PartitionDesc partitionDesc) { + if (partitionDesc instanceof SingleItemListPartition) { + SingleItemListPartition singleListPartition = (SingleItemListPartition)partitionDesc; + ListClientPartition listPartitionValue = new ListClientPartition(); + listPartitionValue.setName(singleListPartition.getName().getOrigin()); + List> partitionValue = singleListPartition.getListStringLiteral() + .getStringLiteralList().stream() + .map(stringLiteral -> { + PartitionClientValue partitionClientValue = PartitionClientValue.builder() + .value(StringLiteralUtil.strip(stringLiteral.getValue())).build(); + return Lists.newArrayList(partitionClientValue); + }).collect(Collectors.toList()); + ArrayClientPartitionKey arrayClientPartitionKey = ArrayClientPartitionKey.builder() + .partitionValue(partitionValue).build(); + listPartitionValue.setPartitionKey(arrayClientPartitionKey); + + //property + ListPartitionProperty listPartitionProperty = new ListPartitionProperty(); + listPartitionProperty.setValue(listPartitionValue); + return listPartitionProperty; + } else if (partitionDesc instanceof MultiItemListPartition) { + MultiItemListPartition multiItemListPartition = (MultiItemListPartition)partitionDesc; + ListClientPartition listPartitionValue = new ListClientPartition(); + listPartitionValue.setName(multiItemListPartition.getName().getOrigin()); + List> partitionValue = multiItemListPartition.getListStringLiterals().stream() + .map(listStringLiteral -> listStringLiteral.getStringLiteralList().stream() + .map(stringLiteral -> PartitionClientValue.builder() + .value(StringLiteralUtil.strip(stringLiteral.getValue())).build()) + .collect(Collectors.toList())).collect(Collectors.toList()); + ArrayClientPartitionKey arrayClientPartitionKey = ArrayClientPartitionKey.builder() + .partitionValue(partitionValue).build(); + listPartitionValue.setPartitionKey(arrayClientPartitionKey); + + //property + ListPartitionProperty listPartitionProperty = new ListPartitionProperty(); + listPartitionProperty.setValue(listPartitionValue); + return listPartitionProperty; + } + return null; + } + + public BaseClientPartitionKey toClientPartitionKey(PartitionKey partitionKey) { + if (partitionKey instanceof ArrayPartitionKey) { + ArrayPartitionKey arrayPartitionKey = (ArrayPartitionKey)partitionKey; + List partitionValues1 = arrayPartitionKey.getPartitionValues(); + ArrayClientPartitionKey arrayClientPartitionKey = new ArrayClientPartitionKey(); + List> partitionValues = partitionValues1.stream().map(x -> { + List partitionValueList = x.getPartitionValueList(); + return partitionValueList.stream().map(p -> { + PartitionClientValue partitionClientValue = new PartitionClientValue(); + partitionClientValue.setMaxValue(p.isMaxValue()); + if (p.getStringLiteral() != null) { + StringLiteral stringLiteral = (StringLiteral)p.getStringLiteral(); + partitionClientValue.setValue(stringLiteral.getValue()); + } + return partitionClientValue; + }).collect(Collectors.toList()); + }).collect(Collectors.toList()); + arrayClientPartitionKey.setPartitionValue(partitionValues); + return arrayClientPartitionKey; + } else if (partitionKey instanceof LessThanPartitionKey) { + LessThanPartitionKey lessThanPartitionKey = (LessThanPartitionKey)partitionKey; + LessThanClientPartitionKey lessThanClientPartitionKey = new LessThanClientPartitionKey(); + if (BooleanUtils.isTrue(lessThanPartitionKey.isMaxValue())) { + lessThanClientPartitionKey.setMaxValue(lessThanPartitionKey.isMaxValue()); + } else { + List list = getPartitionClientValues(lessThanPartitionKey); + lessThanClientPartitionKey.setPartitionValueList(list); + } + return lessThanClientPartitionKey; + } + return null; + } + + private List getPartitionClientValues(LessThanPartitionKey lessThanPartitionKey) { + ListPartitionValue partitionValues = lessThanPartitionKey.getPartitionValues(); + List list = partitionValues.getPartitionValueList().stream().map( + x -> { + PartitionClientValue partitionClientValue = new PartitionClientValue(); + partitionClientValue.setMaxValue(x.isMaxValue()); + if (x.getStringLiteral() != null) { + String raw = getRaw(x.getStringLiteral()); + partitionClientValue.setValue(StringLiteralUtil.strip(raw)); + } + return partitionClientValue; + } + ).collect(Collectors.toList()); + return list; + } + + @Override + protected PartitionedBy toPartitionedBy(Table table, List columns) { + List properties = table.getProperties(); + List list = columns.stream() + .filter(Column::isPartitionKey) + .sorted(Comparator.comparing(Column::getPartitionKeyIndex)) + .map(x -> { + List clientProperties = x.getProperties(); + return ColumnDefinition.builder().colName(new Identifier(x.getName())) + .properties(toProperty(table, clientProperties)) + .build(); + }) + .collect(Collectors.toList()); + return toPartition(list, properties); + } + + private PartitionedBy toPartition(List columnDefinitionList, List properties) { + if (properties == null || properties.isEmpty()) { + return null; + } + + // range partition + List rangePartitionProperties = properties.stream().filter(property -> + StringUtils.equalsIgnoreCase(property.getKey(), TABLE_RANGE_PARTITION.getValue())) + .collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(rangePartitionProperties)) { + List list = Lists.newArrayList(); + rangePartitionProperties.forEach(property -> toRangePartition(list, property)); + return new RangePartitionedBy(columnDefinitionList, list); + } + + // list partition + List listPartitionProperties = properties.stream().filter(property -> + StringUtils.equalsIgnoreCase(property.getKey(), TABLE_LIST_PARTITION.getValue())) + .collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(listPartitionProperties)) { + List list = Lists.newArrayList(); + listPartitionProperties.forEach(property -> toListPartition(list, columnDefinitionList, property)); + return new ListPartitionedBy(columnDefinitionList, list); + } + + // expression partition + List expressionPartitionProperties = properties.stream().filter(property -> + StringUtils.equalsIgnoreCase(property.getKey(), TABLE_EXPRESSION_PARTITION.getValue())) + .collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(expressionPartitionProperties)) { + FunctionCall functionCall = buildFunctionCall(expressionPartitionProperties.get(0)); + return new ExpressionPartitionBy(columnDefinitionList, functionCall, null); + } + + return null; + } + + private void toRangePartition(List list, BaseClientProperty baseClientProperty) { + if (baseClientProperty instanceof SingleRangePartitionProperty) { + SingleRangePartitionProperty baseClientProperty1 = (SingleRangePartitionProperty)baseClientProperty; + PartitionDesc rangePartition = getPartitionDesc(baseClientProperty1.getValue()); + list.add(rangePartition); + } else if (baseClientProperty instanceof MultiRangePartitionProperty) { + MultiRangePartitionProperty multiRangePartitionProperty = (MultiRangePartitionProperty)baseClientProperty; + MultiRangeClientPartition value = multiRangePartitionProperty.getValue(); + LongLiteral longLiteral = new LongLiteral(String.valueOf(value.getInterval())); + PartitionDesc rangePartition = new MultiRangePartition( + new StringLiteral(value.getStart()), + new StringLiteral(value.getEnd()), + value.getDateTimeEnum() != null ? new IntervalLiteral(longLiteral, value.getDateTimeEnum()) : null, + value.getDateTimeEnum() == null ? longLiteral : null + ); + list.add(rangePartition); + } + } + + public PartitionDesc getPartitionDesc(SingleRangeClientPartition rangePartitionValue) { + BaseClientPartitionKey partitionKeyValue = rangePartitionValue.getPartitionKey(); + PartitionKey partitionKey = null; + if (partitionKeyValue instanceof LessThanClientPartitionKey) { + LessThanClientPartitionKey lessThanClientPartitionKey = (LessThanClientPartitionKey)partitionKeyValue; + List partitionValueList = Optional.ofNullable(lessThanClientPartitionKey.getPartitionValueList()).orElse( + Lists.newArrayList()); + List collect = partitionValueList + .stream().map(x -> { + return getPartitionValue(x); + }) + .collect(Collectors.toList()); + partitionKey = new LessThanPartitionKey( + lessThanClientPartitionKey.isMaxValue(), + new ListPartitionValue(collect) + ); + } else if (partitionKeyValue instanceof ArrayClientPartitionKey) { + ArrayClientPartitionKey arrayClientPartitionKey = (ArrayClientPartitionKey)partitionKeyValue; + List collect = arrayClientPartitionKey.getPartitionValue().stream().map( + x -> { + List partitionValueList = Lists.newArrayList(); + for (PartitionClientValue partitionClientValue : x) { + PartitionValue partitionValue = getPartitionValue(partitionClientValue); + partitionValueList.add(partitionValue); + } + return new ListPartitionValue(partitionValueList); + } + ).collect(Collectors.toList()); + partitionKey = new ArrayPartitionKey(collect); + } + return new SingleRangePartition( + new Identifier(rangePartitionValue.getName()), + rangePartitionValue.isIfNotExists(), + partitionKey, + null + ); + } + + protected PartitionValue getPartitionValue(PartitionClientValue partitionClientValue) { + StringLiteral stringLiteral = null; + if (partitionClientValue.getValue() != null) { + stringLiteral = new StringLiteral(partitionClientValue.getValue()); + } + PartitionValue partitionValue = new PartitionValue(partitionClientValue.isMaxValue(), stringLiteral); + return partitionValue; + } + + private void toListPartition(List list, List columnDefinitionList, + BaseClientProperty baseClientProperty) { + if (!(baseClientProperty instanceof ListPartitionProperty)) { + return; + } + boolean multiPartition = columnDefinitionList.size() > 1; + ListPartitionProperty listPartitionProperty = (ListPartitionProperty)baseClientProperty; + ListClientPartition listClientPartition = listPartitionProperty.getValue(); + BaseClientPartitionKey partitionKeyValue = listClientPartition.getPartitionKey(); + if (!(partitionKeyValue instanceof ArrayClientPartitionKey)) { + return; + } + ArrayClientPartitionKey arrayClientPartitionKey = (ArrayClientPartitionKey)partitionKeyValue; + if (multiPartition) { + List collect = arrayClientPartitionKey.getPartitionValue().stream().map( + x -> { + List partitionValueList = Lists.newArrayList(); + for (PartitionClientValue partitionClientValue : x) { + partitionValueList.add(new StringLiteral(partitionClientValue.getValue())); + } + return new ListStringLiteral(partitionValueList); + } + ).collect(Collectors.toList()); + MultiItemListPartition listPartition = new MultiItemListPartition( + new Identifier(listClientPartition.getName()), + false, + collect, + null + ); + list.add(listPartition); + } else { + List collect = arrayClientPartitionKey.getPartitionValue().stream().map( + x -> { + PartitionClientValue partitionClientValue = x.get(0); + return new StringLiteral(partitionClientValue.getValue()); + } + ).collect(Collectors.toList()); + ListStringLiteral partitionKey = new ListStringLiteral(collect); + SingleItemListPartition listPartition = new SingleItemListPartition( + new Identifier(listClientPartition.getName()), + false, + partitionKey, + null + ); + list.add(listPartition); + } + } + + private FunctionCall buildFunctionCall(BaseClientProperty baseClientProperty) { + if (!(baseClientProperty instanceof TimeExpressionPartitionProperty)) { + return null; + } + TimeExpressionPartitionProperty timeExpressionPartitionProperty = (TimeExpressionPartitionProperty)baseClientProperty; + TimeExpressionClientPartition timeExpressionClientPartition = timeExpressionPartitionProperty.getValue(); + List arguments = new ArrayList<>(); + if (StringUtils.isNotBlank(timeExpressionClientPartition.getTimeUnit())) { + arguments.add(new StringLiteral(timeExpressionClientPartition.getTimeUnit())); + } + if (timeExpressionClientPartition.getInterval() != null) { + arguments.add(timeExpressionClientPartition.getInterval()); + } + return new FunctionCall(QualifiedName.of(timeExpressionClientPartition.getFuncName()), + false, arguments); + + } + + @Override + public BaseDataType getDataType(Column column) { + String dataTypeName = column.getDataType(); + if (StringUtils.isBlank(dataTypeName)) { + throw new IllegalArgumentException("dataType name can't be null:" + column.getName()); + } + IDataTypeName byValue = getDataTypeName(dataTypeName); + Dimension dimension = byValue.getDimension(); + ReverseContext context = ReverseContext.builder().build(); + if (dimension == null || dimension == Dimension.ZERO) { + return getLanguageParser().parseDataType(dataTypeName, context); + } + if (dimension == Dimension.ONE) { + boolean isValidLength = column.getLength() != null && column.getLength() > 0; + if (isValidLength) { + String dt = String.format(ONE_DIMENSION, dataTypeName, column.getLength()); + return getLanguageParser().parseDataType(dt, context); + } + } + if (dimension == Dimension.TWO) { + if (column.getPrecision() != null) { + if (column.getScale() == null) { + return getLanguageParser().parseDataType(String.format(ONE_DIMENSION, dataTypeName, column.getPrecision()), context); + } + return getLanguageParser().parseDataType(String.format(TWO_DIMENSION, dataTypeName, column.getPrecision(), column.getScale()), + context); + } + } + return getLanguageParser().parseDataType(dataTypeName, context); + } + + @Override + protected List toConstraint(List columns, List constraints) { + List baseConstraints = super.toConstraint(columns, constraints); + if (constraints == null) { + return baseConstraints; + } + for (Constraint constraint : constraints) { + ConstraintType type = constraint.getType(); + if (type == ClientConstraintType.DISTRIBUTE) { + DistributeConstraint distributeConstraint = toDistributeConstraint(constraint); + if (distributeConstraint == null) { + continue; + } + baseConstraints.add(distributeConstraint); + } + if (type == ClientConstraintType.ORDER_BY) { + OrderByConstraint orderByConstraint = toOrderByConstraint(constraint); + baseConstraints.add(orderByConstraint); + } + + if (type == ClientConstraintType.DUPLICATE_KEY) { + DuplicateKeyConstraint duplicateKeyConstraint = toDuplicateKeyConstraint(constraint); + baseConstraints.add(duplicateKeyConstraint); + } + + if (type == ClientConstraintType.AGGREGATE_KEY) { + AggregateKeyConstraint aggregateKeyConstraint = toAggregateKeyConstraint(constraint); + baseConstraints.add(aggregateKeyConstraint); + } + } + return baseConstraints; + } + + protected BaseExpression toDefaultValueExpression(BaseDataType baseDataType, String defaultValue) { + if (defaultValue == null) { + return null; + } + IDataTypeName typeName = baseDataType.getTypeName(); + if (StringUtils.equalsIgnoreCase(defaultValue, UUID + SUFFIX)) { + return new FunctionCall(QualifiedName.of(UUID), false, Lists.newArrayList()); + } + if (StringUtils.equalsIgnoreCase(defaultValue, UUID_NUMERIC + SUFFIX)) { + return new FunctionCall(QualifiedName.of(UUID_NUMERIC), false, Lists.newArrayList()); + } + if (typeName instanceof ISimpleDataTypeName) { + //starRocks 数字也是用字符标识 + ISimpleDataTypeName simpleDataTypeName = (ISimpleDataTypeName)typeName; + if (simpleDataTypeName.getSimpleDataTypeName() == SimpleDataTypeName.NUMBER) { + return new StringLiteral(defaultValue); + } + } + return super.toDefaultValueExpression(baseDataType, defaultValue); + } + + private AggregateKeyConstraint toAggregateKeyConstraint(Constraint constraint) { + return new AggregateKeyConstraint( + IdentifierUtil.sysIdentifier(), + constraint.getColumns().stream().map(Identifier::new).collect(Collectors.toList()) + ); + } + + private DuplicateKeyConstraint toDuplicateKeyConstraint(Constraint constraint) { + return new DuplicateKeyConstraint( + IdentifierUtil.sysIdentifier(), + constraint.getColumns().stream().map(Identifier::new).collect(Collectors.toList()), + true + ); + } + + private OrderByConstraint toOrderByConstraint(Constraint constraint) { + String name = constraint.getName(); + Identifier nameIdentifier = null; + if (StringUtils.isBlank(name)) { + nameIdentifier = IdentifierUtil.sysIdentifier(); + } else { + nameIdentifier = new Identifier(name); + } + List collect = constraint.getColumns().stream().map(Identifier::new).collect(Collectors.toList()); + return new OrderByConstraint(nameIdentifier, collect); + } + + private DistributeConstraint toDistributeConstraint(Constraint constraint) { + if (constraint instanceof DistributeClientConstraint) { + DistributeClientConstraint clientConstraint = (DistributeClientConstraint)constraint; + List list = null; + if (CollectionUtils.isNotEmpty(constraint.getColumns())) { + list = constraint.getColumns().stream().map(Identifier::new).collect(Collectors.toList()); + return new DistributeConstraint(list, clientConstraint.getBucket()); + } else { + if (BooleanUtils.isTrue(clientConstraint.getRandom())) { + return new DistributeConstraint(clientConstraint.getRandom(), clientConstraint.getBucket()); + } + } + } + List list = null; + if (CollectionUtils.isNotEmpty(constraint.getColumns())) { + list = constraint.getColumns().stream().map(Identifier::new).collect(Collectors.toList()); + return new DistributeConstraint(list, null); + } + return null; + } + +} diff --git a/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/ExtensionPropertyKey.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/ExtensionPropertyKey.java new file mode 100644 index 0000000..6cb06fb --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/ExtensionPropertyKey.java @@ -0,0 +1,112 @@ +package com.aliyun.fastmodel.transform.api.extension.client.property; + +import com.aliyun.fastmodel.transform.api.format.PropertyKey; +import org.apache.commons.lang3.StringUtils; + +/** + * Desc: + * + * @author panguanjing + * @date 2024/1/22 + */ +public enum ExtensionPropertyKey implements PropertyKey { + + /** + * engine + */ + TABLE_ENGINE("engine"), + + /** + * distribute hash + */ + TABLE_DISTRIBUTED_HASH("distributed_hash"), + + /** + * distribute buckets + */ + TABLE_DISTRIBUTED_BUCKETS("distributed_buckets"), + + COLUMN_KEY("column_key"), + + /** + * 自增列信息 + */ + COLUMN_AUTO_INCREMENT("column_auto_increment"), + + /** + * column agg desc + */ + COLUMN_AGG_DESC("column_agg_desc"), + + /** + * index type + */ + TABLE_INDEX_TYPE("index_type"), + /** + * index comment + */ + TABLE_INDEX_COMMENT("index_comment"), + + /** + * range partition + */ + TABLE_RANGE_PARTITION("range_partition"), + + /** + * table range partition raw + */ + TABLE_PARTITION_RAW("range_partition_raw"), + + /** + * list partition + */ + TABLE_LIST_PARTITION("list_partition"), + + /** + * expression partition + */ + TABLE_EXPRESSION_PARTITION("expression_partition"), + + /** + * REPLICATION_NUM + */ + TABLE_REPLICATION_NUM("replication_num", true), + + /** + * 保留最近多少数量的分区 + */ + PARTITION_LIVE_NUMBER("partition_live_number", true); + + private final String value; + + private final boolean supportPrint; + + ExtensionPropertyKey(String value) { + this(value, false); + } + + ExtensionPropertyKey(String value, boolean supportPrint) { + this.value = value; + this.supportPrint = supportPrint; + } + + @Override + public String getValue() { + return value; + } + + @Override + public boolean isSupportPrint() { + return supportPrint; + } + + public static ExtensionPropertyKey getByValue(String value) { + ExtensionPropertyKey[] extensionPropertyKeys = ExtensionPropertyKey.values(); + for (ExtensionPropertyKey e : extensionPropertyKeys) { + if (StringUtils.equalsIgnoreCase(e.getValue(), value)) { + return e; + } + } + return null; + } +} diff --git a/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/column/AggrColumnProperty.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/column/AggrColumnProperty.java new file mode 100644 index 0000000..f038660 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/column/AggrColumnProperty.java @@ -0,0 +1,31 @@ +package com.aliyun.fastmodel.transform.api.extension.client.property.column; + +import java.util.Locale; + +import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; +import com.aliyun.fastmodel.transform.api.extension.tree.column.AggregateDesc; + +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.COLUMN_AGG_DESC; + +/** + * aggr column property + * + * @author panguanjing + * @date 2023/9/17 + */ +public class AggrColumnProperty extends BaseClientProperty { + + public AggrColumnProperty() { + this.setKey(COLUMN_AGG_DESC.getValue()); + } + + @Override + public String valueString() { + return value.name(); + } + + @Override + public void setValueString(String value) { + this.value = AggregateDesc.valueOf(value.toUpperCase(Locale.ROOT)); + } +} diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/index/IndexCommentProperty.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/index/IndexCommentProperty.java similarity index 65% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/index/IndexCommentProperty.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/index/IndexCommentProperty.java index 75ae7b5..81c89af 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/index/IndexCommentProperty.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/index/IndexCommentProperty.java @@ -1,7 +1,8 @@ -package com.aliyun.fastmodel.transform.starrocks.client.property.index; +package com.aliyun.fastmodel.transform.api.extension.client.property.index; import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; -import com.aliyun.fastmodel.transform.starrocks.format.StarRocksProperty; + +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_INDEX_COMMENT; /** * 索引描述信息属性 @@ -12,7 +13,7 @@ public class IndexCommentProperty extends BaseClientProperty { public IndexCommentProperty() { - setKey(StarRocksProperty.TABLE_INDEX_COMMENT.getValue()); + setKey(TABLE_INDEX_COMMENT.getValue()); } @Override diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/index/IndexTypeProperty.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/index/IndexTypeProperty.java similarity index 65% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/index/IndexTypeProperty.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/index/IndexTypeProperty.java index a91184c..6398d4d 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/index/IndexTypeProperty.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/index/IndexTypeProperty.java @@ -1,7 +1,8 @@ -package com.aliyun.fastmodel.transform.starrocks.client.property.index; +package com.aliyun.fastmodel.transform.api.extension.client.property.index; import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; -import com.aliyun.fastmodel.transform.starrocks.format.StarRocksProperty; + +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_INDEX_TYPE; /** * 索引描述信息属性 @@ -12,7 +13,7 @@ public class IndexTypeProperty extends BaseClientProperty { public IndexTypeProperty() { - setKey(StarRocksProperty.TABLE_INDEX_TYPE.getValue()); + setKey(TABLE_INDEX_TYPE.getValue()); } @Override diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/ColumnExpressionPartitionProperty.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/ColumnExpressionPartitionProperty.java similarity index 64% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/ColumnExpressionPartitionProperty.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/ColumnExpressionPartitionProperty.java index ea8ebd6..e3ac46a 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/ColumnExpressionPartitionProperty.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/ColumnExpressionPartitionProperty.java @@ -1,18 +1,20 @@ -package com.aliyun.fastmodel.transform.starrocks.client.property.table; +package com.aliyun.fastmodel.transform.api.extension.client.property.table; import com.alibaba.fastjson.JSON; + import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.ColumnExpressionClientPartition; -import com.aliyun.fastmodel.transform.starrocks.format.StarRocksProperty; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.ColumnExpressionClientPartition; import org.apache.commons.lang3.StringUtils; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_EXPRESSION_PARTITION; + /** * @author 子梁 * @date 2023/12/26 */ public class ColumnExpressionPartitionProperty extends BaseClientProperty { public ColumnExpressionPartitionProperty() { - this.setKey(StarRocksProperty.TABLE_EXPRESSION_PARTITION.getValue()); + this.setKey(TABLE_EXPRESSION_PARTITION.getValue()); } @Override diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/DistributeBucketsNum.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/DistributeBucketsNum.java similarity index 70% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/DistributeBucketsNum.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/DistributeBucketsNum.java index ea09eb5..b914646 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/DistributeBucketsNum.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/DistributeBucketsNum.java @@ -1,9 +1,10 @@ -package com.aliyun.fastmodel.transform.starrocks.client.property.table; +package com.aliyun.fastmodel.transform.api.extension.client.property.table; import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; -import com.aliyun.fastmodel.transform.starrocks.format.StarRocksProperty; import org.apache.commons.lang3.StringUtils; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_DISTRIBUTED_BUCKETS; + /** * 分桶列的个数 * @@ -12,7 +13,7 @@ */ public class DistributeBucketsNum extends BaseClientProperty { public DistributeBucketsNum() { - setKey(StarRocksProperty.TABLE_DISTRIBUTED_BUCKETS.getValue()); + setKey(TABLE_DISTRIBUTED_BUCKETS.getValue()); } @Override diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/DistributeHash.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/DistributeHash.java similarity index 65% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/DistributeHash.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/DistributeHash.java index 524a6e9..20fb88f 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/DistributeHash.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/DistributeHash.java @@ -1,12 +1,13 @@ -package com.aliyun.fastmodel.transform.starrocks.client.property.table; +package com.aliyun.fastmodel.transform.api.extension.client.property.table; import java.util.List; import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; -import com.aliyun.fastmodel.transform.starrocks.format.StarRocksProperty; import com.google.common.collect.Lists; import org.apache.commons.lang3.StringUtils; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_DISTRIBUTED_HASH; + /** * 分桶列的个数 * @@ -16,7 +17,7 @@ public class DistributeHash extends BaseClientProperty> { public DistributeHash() { - setKey(StarRocksProperty.TABLE_DISTRIBUTED_HASH.getValue()); + setKey(TABLE_DISTRIBUTED_HASH.getValue()); } @Override @@ -29,6 +30,6 @@ public void setValueString(String value) { if (StringUtils.isBlank(value)) { return; } - this.value = Lists.newArrayList(StringUtils.split(value, ",")); + this.value = Lists.newArrayList(StringUtils.split(value, ",")); } } diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/MultiRangePartitionProperty.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/MultiRangePartitionProperty.java similarity index 66% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/MultiRangePartitionProperty.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/MultiRangePartitionProperty.java index 00c7024..a467d42 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/MultiRangePartitionProperty.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/MultiRangePartitionProperty.java @@ -1,12 +1,13 @@ -package com.aliyun.fastmodel.transform.starrocks.client.property.table; +package com.aliyun.fastmodel.transform.api.extension.client.property.table; import com.alibaba.fastjson.JSON; import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.MultiRangeClientPartition; -import com.aliyun.fastmodel.transform.starrocks.format.StarRocksProperty; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.MultiRangeClientPartition; import org.apache.commons.lang3.StringUtils; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_RANGE_PARTITION; + /** * multi range partition * @@ -16,7 +17,7 @@ public class MultiRangePartitionProperty extends BaseClientProperty { public MultiRangePartitionProperty() { - this.setKey(StarRocksProperty.TABLE_RANGE_PARTITION.getValue()); + this.setKey(TABLE_RANGE_PARTITION.getValue()); } @Override diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/PartitionLiveNumberProperty.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/PartitionLiveNumberProperty.java similarity index 70% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/PartitionLiveNumberProperty.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/PartitionLiveNumberProperty.java index a856056..2f01f8f 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/PartitionLiveNumberProperty.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/PartitionLiveNumberProperty.java @@ -1,9 +1,10 @@ -package com.aliyun.fastmodel.transform.starrocks.client.property.table; +package com.aliyun.fastmodel.transform.api.extension.client.property.table; import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; -import com.aliyun.fastmodel.transform.starrocks.format.StarRocksProperty; import org.apache.commons.lang3.StringUtils; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.PARTITION_LIVE_NUMBER; + /** * @author 子梁 * @date 2024/1/5 @@ -11,7 +12,7 @@ public class PartitionLiveNumberProperty extends BaseClientProperty { public PartitionLiveNumberProperty() { - setKey(StarRocksProperty.PARTITION_LIVE_NUMBER.getValue()); + setKey(PARTITION_LIVE_NUMBER.getValue()); } @Override diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/ReplicationNum.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/ReplicationNum.java similarity index 70% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/ReplicationNum.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/ReplicationNum.java index 8e2f4f0..84cebfc 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/ReplicationNum.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/ReplicationNum.java @@ -1,9 +1,10 @@ -package com.aliyun.fastmodel.transform.starrocks.client.property.table; +package com.aliyun.fastmodel.transform.api.extension.client.property.table; import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; -import com.aliyun.fastmodel.transform.starrocks.format.StarRocksProperty; import org.apache.commons.lang3.StringUtils; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_REPLICATION_NUM; + /** * ReplicationNum * @@ -12,7 +13,7 @@ */ public class ReplicationNum extends BaseClientProperty { public ReplicationNum() { - setKey(StarRocksProperty.TABLE_REPLICATION_NUM.getValue()); + setKey(TABLE_REPLICATION_NUM.getValue()); } @Override diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/SingleRangePartitionProperty.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/SingleRangePartitionProperty.java similarity index 66% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/SingleRangePartitionProperty.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/SingleRangePartitionProperty.java index 891e8c0..cf09638 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/SingleRangePartitionProperty.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/SingleRangePartitionProperty.java @@ -1,12 +1,13 @@ -package com.aliyun.fastmodel.transform.starrocks.client.property.table; +package com.aliyun.fastmodel.transform.api.extension.client.property.table; import com.alibaba.fastjson.JSON; import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.SingleRangeClientPartition; -import com.aliyun.fastmodel.transform.starrocks.format.StarRocksProperty; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.SingleRangeClientPartition; import org.apache.commons.lang3.StringUtils; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_RANGE_PARTITION; + /** * single range partition * @@ -16,7 +17,7 @@ public class SingleRangePartitionProperty extends BaseClientProperty { public SingleRangePartitionProperty() { - this.setKey(StarRocksProperty.TABLE_RANGE_PARTITION.getValue()); + this.setKey(TABLE_RANGE_PARTITION.getValue()); } @Override diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/TablePartitionRaw.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/TablePartitionRaw.java similarity index 65% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/TablePartitionRaw.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/TablePartitionRaw.java index 311ad7d..d3c6ec8 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/TablePartitionRaw.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/TablePartitionRaw.java @@ -1,7 +1,8 @@ -package com.aliyun.fastmodel.transform.starrocks.client.property.table; +package com.aliyun.fastmodel.transform.api.extension.client.property.table; import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; -import com.aliyun.fastmodel.transform.starrocks.format.StarRocksProperty; + +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_PARTITION_RAW; /** * 分区定义的文本化描述 @@ -12,7 +13,7 @@ public class TablePartitionRaw extends BaseClientProperty { public TablePartitionRaw() { - this.setKey(StarRocksProperty.TABLE_PARTITION_RAW.getValue()); + this.setKey(TABLE_PARTITION_RAW.getValue()); } @Override diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/TimeExpressionPartitionProperty.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/TimeExpressionPartitionProperty.java similarity index 64% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/TimeExpressionPartitionProperty.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/TimeExpressionPartitionProperty.java index 62af158..bc45a9c 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/TimeExpressionPartitionProperty.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/TimeExpressionPartitionProperty.java @@ -1,11 +1,13 @@ -package com.aliyun.fastmodel.transform.starrocks.client.property.table; +package com.aliyun.fastmodel.transform.api.extension.client.property.table; import com.alibaba.fastjson.JSON; + import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.TimeExpressionClientPartition; -import com.aliyun.fastmodel.transform.starrocks.format.StarRocksProperty; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.TimeExpressionClientPartition; import org.apache.commons.lang3.StringUtils; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_EXPRESSION_PARTITION; + /** * @author 子梁 * @date 2023/12/26 @@ -13,7 +15,7 @@ public class TimeExpressionPartitionProperty extends BaseClientProperty { public TimeExpressionPartitionProperty() { - this.setKey(StarRocksProperty.TABLE_EXPRESSION_PARTITION.getValue()); + this.setKey(TABLE_EXPRESSION_PARTITION.getValue()); } @Override diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/ArrayClientPartitionKey.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/ArrayClientPartitionKey.java similarity index 84% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/ArrayClientPartitionKey.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/ArrayClientPartitionKey.java index e8e758b..e0a1696 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/ArrayClientPartitionKey.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/ArrayClientPartitionKey.java @@ -1,4 +1,4 @@ -package com.aliyun.fastmodel.transform.starrocks.client.property.table.partition; +package com.aliyun.fastmodel.transform.api.extension.client.property.table.partition; import java.util.List; diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/BaseClientPartitionKey.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/BaseClientPartitionKey.java similarity index 58% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/BaseClientPartitionKey.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/BaseClientPartitionKey.java index c18f729..9cb993c 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/BaseClientPartitionKey.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/BaseClientPartitionKey.java @@ -1,4 +1,4 @@ -package com.aliyun.fastmodel.transform.starrocks.client.property.table.partition; +package com.aliyun.fastmodel.transform.api.extension.client.property.table.partition; /** * partition key diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/ColumnExpressionClientPartition.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/ColumnExpressionClientPartition.java similarity index 80% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/ColumnExpressionClientPartition.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/ColumnExpressionClientPartition.java index 0dd98e0..d9067c0 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/ColumnExpressionClientPartition.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/ColumnExpressionClientPartition.java @@ -1,12 +1,12 @@ -package com.aliyun.fastmodel.transform.starrocks.client.property.table.partition; +package com.aliyun.fastmodel.transform.api.extension.client.property.table.partition; + +import java.util.List; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import java.util.List; - /** * @author 子梁 * @date 2023/12/26 diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/LessThanClientPartitionKey.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/LessThanClientPartitionKey.java similarity index 83% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/LessThanClientPartitionKey.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/LessThanClientPartitionKey.java index bf69170..911478b 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/LessThanClientPartitionKey.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/LessThanClientPartitionKey.java @@ -1,4 +1,4 @@ -package com.aliyun.fastmodel.transform.starrocks.client.property.table.partition; +package com.aliyun.fastmodel.transform.api.extension.client.property.table.partition; import java.util.List; @@ -19,7 +19,7 @@ @Builder @NoArgsConstructor @AllArgsConstructor -public class LessThanClientPartitionKey extends BaseClientPartitionKey{ +public class LessThanClientPartitionKey extends BaseClientPartitionKey { private boolean maxValue; diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/ListClientPartition.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/ListClientPartition.java similarity index 83% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/ListClientPartition.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/ListClientPartition.java index 899c48a..0b85421 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/ListClientPartition.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/ListClientPartition.java @@ -1,4 +1,4 @@ -package com.aliyun.fastmodel.transform.starrocks.client.property.table.partition; +package com.aliyun.fastmodel.transform.api.extension.client.property.table.partition; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/MultiRangeClientPartition.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/MultiRangeClientPartition.java similarity index 86% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/MultiRangeClientPartition.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/MultiRangeClientPartition.java index 016f616..61a8ffd 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/MultiRangeClientPartition.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/MultiRangeClientPartition.java @@ -1,4 +1,4 @@ -package com.aliyun.fastmodel.transform.starrocks.client.property.table.partition; +package com.aliyun.fastmodel.transform.api.extension.client.property.table.partition; import com.aliyun.fastmodel.core.tree.expr.enums.DateTimeEnum; import lombok.AllArgsConstructor; diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/PartitionClientValue.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/PartitionClientValue.java similarity index 81% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/PartitionClientValue.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/PartitionClientValue.java index 85b3d50..ffe10b5 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/PartitionClientValue.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/PartitionClientValue.java @@ -1,4 +1,4 @@ -package com.aliyun.fastmodel.transform.starrocks.client.property.table.partition; +package com.aliyun.fastmodel.transform.api.extension.client.property.table.partition; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/SingleRangeClientPartition.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/SingleRangeClientPartition.java similarity index 87% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/SingleRangeClientPartition.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/SingleRangeClientPartition.java index c8e4315..d46e7ea 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/SingleRangeClientPartition.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/SingleRangeClientPartition.java @@ -1,4 +1,4 @@ -package com.aliyun.fastmodel.transform.starrocks.client.property.table.partition; +package com.aliyun.fastmodel.transform.api.extension.client.property.table.partition; import java.util.LinkedHashMap; @@ -34,6 +34,4 @@ public class SingleRangeClientPartition { */ private LinkedHashMap properties; - - } diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/TimeExpressionClientPartition.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/TimeExpressionClientPartition.java similarity index 86% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/TimeExpressionClientPartition.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/TimeExpressionClientPartition.java index 92e3e4e..890ebb8 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/partition/TimeExpressionClientPartition.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/client/property/table/partition/TimeExpressionClientPartition.java @@ -1,4 +1,4 @@ -package com.aliyun.fastmodel.transform.starrocks.client.property.table.partition; +package com.aliyun.fastmodel.transform.api.extension.client.property.table.partition; import com.aliyun.fastmodel.core.tree.expr.literal.IntervalLiteral; import lombok.AllArgsConstructor; diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/AggDesc.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/column/AggregateDesc.java similarity index 83% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/AggDesc.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/column/AggregateDesc.java index aee2cab..d221418 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/AggDesc.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/column/AggregateDesc.java @@ -1,4 +1,4 @@ -package com.aliyun.fastmodel.transform.starrocks.parser.tree; +package com.aliyun.fastmodel.transform.api.extension.tree.column; /** * column agg desc @@ -6,7 +6,7 @@ * @author panguanjing * @date 2023/9/16 */ -public enum AggDesc { +public enum AggregateDesc { /** * sum */ diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/constraint/AggregateKeyConstraint.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/AggregateKeyConstraint.java similarity index 76% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/constraint/AggregateKeyConstraint.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/AggregateKeyConstraint.java index 57298aa..d7b5394 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/constraint/AggregateKeyConstraint.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/AggregateKeyConstraint.java @@ -1,4 +1,4 @@ -package com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint; +package com.aliyun.fastmodel.transform.api.extension.tree.constraint; import java.util.List; @@ -6,7 +6,7 @@ import com.aliyun.fastmodel.core.tree.Node; import com.aliyun.fastmodel.core.tree.expr.Identifier; import com.aliyun.fastmodel.core.tree.statement.table.constraint.CustomConstraint; -import com.aliyun.fastmodel.transform.starrocks.parser.visitor.StarRocksAstVisitor; +import com.aliyun.fastmodel.transform.api.extension.visitor.ExtensionAstVisitor; import lombok.Getter; /** @@ -33,8 +33,8 @@ public AggregateKeyConstraint(Identifier constraintName, List column @Override public R accept(AstVisitor visitor, C context) { - StarRocksAstVisitor starRocksAstVisitor = (StarRocksAstVisitor)visitor; - return starRocksAstVisitor.visitAggregateConstraint(this, context); + ExtensionAstVisitor extensionVisitor = (ExtensionAstVisitor)visitor; + return extensionVisitor.visitAggregateConstraint(this, context); } @Override diff --git a/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/Algorithm.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/Algorithm.java new file mode 100644 index 0000000..9a86e91 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/Algorithm.java @@ -0,0 +1,12 @@ +package com.aliyun.fastmodel.transform.api.extension.tree.constraint; + +/** + * Desc: + * + * @author panguanjing + * @date 2024/2/19 + */ +public enum Algorithm { + BTREE, + HASH +} diff --git a/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/CheckExpressionConstraint.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/CheckExpressionConstraint.java new file mode 100644 index 0000000..681e803 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/CheckExpressionConstraint.java @@ -0,0 +1,40 @@ +package com.aliyun.fastmodel.transform.api.extension.tree.constraint; + +import com.aliyun.fastmodel.core.tree.AstVisitor; +import com.aliyun.fastmodel.core.tree.expr.BaseExpression; +import com.aliyun.fastmodel.core.tree.expr.Identifier; +import com.aliyun.fastmodel.core.tree.statement.table.constraint.CustomConstraint; +import com.aliyun.fastmodel.transform.api.extension.visitor.ExtensionAstVisitor; +import lombok.Getter; + +/** + * check expression constraint + * + * @author panguanjing + * @date 2024/2/17 + */ +@Getter +public class CheckExpressionConstraint extends CustomConstraint { + + public static final String CHECK = "CHECK"; + + private final BaseExpression expression; + + private final Boolean enforced; + + public CheckExpressionConstraint(Identifier constraintName, Boolean enable, String customType, BaseExpression expression, Boolean enforced) { + super(constraintName, enable, customType); + this.expression = expression; + this.enforced = enforced; + } + + public CheckExpressionConstraint(Identifier constraintName, BaseExpression expression, Boolean enforced) { + this(constraintName, true, CHECK, expression, enforced); + } + + @Override + public R accept(AstVisitor visitor, C context) { + ExtensionAstVisitor extensionVisitor = (ExtensionAstVisitor)visitor; + return extensionVisitor.visitCheckExpressionConstraint(this, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/constraint/DuplicateKeyConstraint.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/DuplicateKeyConstraint.java similarity index 76% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/constraint/DuplicateKeyConstraint.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/DuplicateKeyConstraint.java index a8269a8..9246a93 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/constraint/DuplicateKeyConstraint.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/DuplicateKeyConstraint.java @@ -1,4 +1,4 @@ -package com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint; +package com.aliyun.fastmodel.transform.api.extension.tree.constraint; import java.util.List; @@ -6,7 +6,7 @@ import com.aliyun.fastmodel.core.tree.Node; import com.aliyun.fastmodel.core.tree.expr.Identifier; import com.aliyun.fastmodel.core.tree.statement.table.constraint.CustomConstraint; -import com.aliyun.fastmodel.transform.starrocks.parser.visitor.StarRocksAstVisitor; +import com.aliyun.fastmodel.transform.api.extension.visitor.ExtensionAstVisitor; import lombok.Getter; /** @@ -33,8 +33,8 @@ public DuplicateKeyConstraint(Identifier constraintName, List column @Override public R accept(IAstVisitor visitor, C context) { - StarRocksAstVisitor starRocksAstVisitor = (StarRocksAstVisitor)visitor; - return starRocksAstVisitor.visitDuplicateConstraint(this, context); + ExtensionAstVisitor extensionVisitor = (ExtensionAstVisitor)visitor; + return extensionVisitor.visitDuplicateConstraint(this, context); } @Override diff --git a/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/ForeignKeyConstraint.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/ForeignKeyConstraint.java new file mode 100644 index 0000000..1b54616 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/ForeignKeyConstraint.java @@ -0,0 +1,74 @@ +package com.aliyun.fastmodel.transform.api.extension.tree.constraint; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.core.tree.QualifiedName; +import com.aliyun.fastmodel.core.tree.expr.Identifier; +import com.aliyun.fastmodel.core.tree.statement.table.constraint.CustomConstraint; +import com.aliyun.fastmodel.transform.api.extension.visitor.ExtensionAstVisitor; +import lombok.Getter; + +/** + * foreign key constraint + * + * @author panguanjing + * @date 2024/2/18 + */ +@Getter +public class ForeignKeyConstraint extends CustomConstraint { + + public enum MatchAction { + SIMPLE, + FULL, + PARTIAL + } + + public enum ReferenceAction { + RESTRICT("RESTRICT"), + CASCADE("CASCADE"), + SET_NULL("SET NULL"), + NO_ACTION("NO ACTION"), + SET_DEFAULT("SET DEFAULT"); + @Getter + private final String value; + + ReferenceAction(String value) {this.value = value;} + } + + public enum ReferenceOperator { + DELETE, + UPDATE + } + + private final Identifier indexName; + private final List colNames; + + private final QualifiedName referenceTable; + + private final List referenceColNames; + + private final MatchAction matchAction; + + private final ReferenceOperator referenceOperator; + + private final ReferenceAction referenceAction; + + public ForeignKeyConstraint(Identifier constraintName, Identifier indexName, List colNames, QualifiedName referenceTable, + List referenceColNames, MatchAction matchAction, ReferenceOperator referenceOperator, ReferenceAction referenceAction) { + super(constraintName, true, "FOREIGN_KEY"); + this.indexName = indexName; + this.colNames = colNames; + this.referenceTable = referenceTable; + this.referenceColNames = referenceColNames; + this.matchAction = matchAction; + this.referenceOperator = referenceOperator; + this.referenceAction = referenceAction; + } + + @Override + public R accept(IAstVisitor visitor, C context) { + ExtensionAstVisitor extensionVisitor = (ExtensionAstVisitor)visitor; + return extensionVisitor.visitForeignKeyConstraint(this, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/UniqueKeyExprConstraint.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/UniqueKeyExprConstraint.java new file mode 100644 index 0000000..86ff9ec --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/UniqueKeyExprConstraint.java @@ -0,0 +1,39 @@ +package com.aliyun.fastmodel.transform.api.extension.tree.constraint; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.core.tree.expr.Identifier; +import com.aliyun.fastmodel.core.tree.statement.table.constraint.CustomConstraint; +import com.aliyun.fastmodel.core.tree.statement.table.index.IndexSortKey; +import com.aliyun.fastmodel.transform.api.extension.visitor.ExtensionAstVisitor; +import lombok.Getter; + +/** + * UniqueKeyExprConstraint + * + * @author panguanjing + * @date 2024/2/19 + */ +@Getter +public class UniqueKeyExprConstraint extends CustomConstraint { + + private final List indexSortKeys; + + private final Algorithm algorithm; + + private final Identifier indexName; + + public UniqueKeyExprConstraint(Identifier constraintName, Identifier indexName, List indexSortKeys, Algorithm algorithm) { + super(constraintName, true, "UniqueKeyExpr"); + this.indexSortKeys = indexSortKeys; + this.algorithm = algorithm; + this.indexName = indexName; + } + + @Override + public R accept(IAstVisitor visitor, C context) { + ExtensionAstVisitor extensionVisitor = (ExtensionAstVisitor)visitor; + return extensionVisitor.visitUniqueKeyExprConstraint(this, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/desc/ClusterKeyConstraint.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/desc/ClusterKeyConstraint.java new file mode 100644 index 0000000..acb2987 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/desc/ClusterKeyConstraint.java @@ -0,0 +1,37 @@ +package com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.AstVisitor; +import com.aliyun.fastmodel.core.tree.expr.Identifier; +import com.aliyun.fastmodel.core.tree.util.IdentifierUtil; +import com.aliyun.fastmodel.transform.api.extension.visitor.ExtensionAstVisitor; + +/** + * cluster by constraint + * + * @author panguanjing + * @date 2024/1/21 + */ +public class ClusterKeyConstraint extends NonKeyConstraint { + + public static final String TYPE = "Cluster"; + + private final List columns; + + public ClusterKeyConstraint(Identifier constraintName, Boolean enable, List columns) { + super(constraintName, enable, TYPE); + this.columns = columns; + } + + public ClusterKeyConstraint(List columns) { + super(IdentifierUtil.sysIdentifier(), true, TYPE); + this.columns = columns; + } + + @Override + public R accept(AstVisitor visitor, C context) { + ExtensionAstVisitor extensionVisitor = (ExtensionAstVisitor)visitor; + return extensionVisitor.visitClusterKeyConstraint(this, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/constraint/desc/DistributeConstraint.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/desc/DistributeConstraint.java similarity index 76% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/constraint/desc/DistributeConstraint.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/desc/DistributeConstraint.java index 7c5b827..b29c439 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/constraint/desc/DistributeConstraint.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/desc/DistributeConstraint.java @@ -1,11 +1,11 @@ -package com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.desc; +package com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc; import java.util.List; import com.aliyun.fastmodel.core.tree.AstVisitor; import com.aliyun.fastmodel.core.tree.expr.Identifier; import com.aliyun.fastmodel.core.tree.util.IdentifierUtil; -import com.aliyun.fastmodel.transform.starrocks.parser.visitor.StarRocksAstVisitor; +import com.aliyun.fastmodel.transform.api.extension.visitor.ExtensionAstVisitor; import lombok.Getter; /** @@ -42,7 +42,7 @@ public DistributeConstraint(boolean random, Integer bucket) { @Override public R accept(AstVisitor visitor, C context) { - StarRocksAstVisitor starRocksAstVisitor = (StarRocksAstVisitor)visitor; - return starRocksAstVisitor.visitDistributeKeyConstraint(this, context); + ExtensionAstVisitor extensionVisitor = (ExtensionAstVisitor)visitor; + return extensionVisitor.visitDistributeKeyConstraint(this, context); } } diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/constraint/desc/NonKeyConstraint.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/desc/NonKeyConstraint.java similarity index 85% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/constraint/desc/NonKeyConstraint.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/desc/NonKeyConstraint.java index 454fdee..592ff99 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/constraint/desc/NonKeyConstraint.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/desc/NonKeyConstraint.java @@ -1,4 +1,4 @@ -package com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.desc; +package com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc; import com.aliyun.fastmodel.core.tree.expr.Identifier; import com.aliyun.fastmodel.core.tree.statement.table.constraint.CustomConstraint; diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/constraint/desc/OrderByConstraint.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/desc/OrderByConstraint.java similarity index 74% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/constraint/desc/OrderByConstraint.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/desc/OrderByConstraint.java index efc1459..9006a33 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/constraint/desc/OrderByConstraint.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/desc/OrderByConstraint.java @@ -1,11 +1,11 @@ -package com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.desc; +package com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc; import java.util.List; import com.aliyun.fastmodel.core.tree.IAstVisitor; import com.aliyun.fastmodel.core.tree.Node; import com.aliyun.fastmodel.core.tree.expr.Identifier; -import com.aliyun.fastmodel.transform.starrocks.parser.visitor.StarRocksAstVisitor; +import com.aliyun.fastmodel.transform.api.extension.visitor.ExtensionAstVisitor; import lombok.Getter; /** @@ -33,8 +33,8 @@ public OrderByConstraint(Identifier constraintName, List columns) { @Override public R accept(IAstVisitor visitor, C context) { - StarRocksAstVisitor starRocksAstVisitor = (StarRocksAstVisitor)visitor; - return starRocksAstVisitor.visitOrderByConstraint(this, context); + ExtensionAstVisitor extensionVisitor = (ExtensionAstVisitor)visitor; + return extensionVisitor.visitOrderByConstraint(this, context); } @Override diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/constraint/desc/RollupConstraint.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/desc/RollupConstraint.java similarity index 77% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/constraint/desc/RollupConstraint.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/desc/RollupConstraint.java index de937b1..47e2a28 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/constraint/desc/RollupConstraint.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/desc/RollupConstraint.java @@ -1,10 +1,10 @@ -package com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.desc; +package com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc; import java.util.List; import com.aliyun.fastmodel.core.tree.IAstVisitor; import com.aliyun.fastmodel.core.tree.util.IdentifierUtil; -import com.aliyun.fastmodel.transform.starrocks.parser.visitor.StarRocksAstVisitor; +import com.aliyun.fastmodel.transform.api.extension.visitor.ExtensionAstVisitor; import lombok.Getter; /** @@ -30,7 +30,7 @@ public RollupConstraint(List rollupItemList) { @Override public R accept(IAstVisitor visitor, C context) { - StarRocksAstVisitor starRocksAstVisitor = (StarRocksAstVisitor)visitor; + ExtensionAstVisitor starRocksAstVisitor = (ExtensionAstVisitor)visitor; return starRocksAstVisitor.visitRollupConstraint(this, context); } } diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/constraint/desc/RollupItem.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/desc/RollupItem.java similarity index 84% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/constraint/desc/RollupItem.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/desc/RollupItem.java index 9011f1b..f956fc6 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/constraint/desc/RollupItem.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/constraint/desc/RollupItem.java @@ -1,4 +1,4 @@ -package com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.desc; +package com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc; import java.util.List; @@ -7,7 +7,7 @@ import com.aliyun.fastmodel.core.tree.Node; import com.aliyun.fastmodel.core.tree.Property; import com.aliyun.fastmodel.core.tree.expr.Identifier; -import com.aliyun.fastmodel.transform.starrocks.parser.visitor.StarRocksAstVisitor; +import com.aliyun.fastmodel.transform.api.extension.visitor.ExtensionAstVisitor; import com.google.common.collect.ImmutableList; import lombok.Getter; @@ -62,7 +62,7 @@ public List getChildren() { @Override public R accept(IAstVisitor visitor, C context) { - StarRocksAstVisitor starRocksAstVisitor = (StarRocksAstVisitor)visitor; - return starRocksAstVisitor.visitRollupItem(this, context); + ExtensionAstVisitor extensionVisitor = (ExtensionAstVisitor)visitor; + return extensionVisitor.visitRollupItem(this, context); } } diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/ExpressionPartitionBy.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/ExpressionPartitionBy.java similarity index 78% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/ExpressionPartitionBy.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/ExpressionPartitionBy.java index 2d8449e..cf57931 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/ExpressionPartitionBy.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/ExpressionPartitionBy.java @@ -1,4 +1,6 @@ -package com.aliyun.fastmodel.transform.starrocks.parser.tree.partition; +package com.aliyun.fastmodel.transform.api.extension.tree.partition; + +import java.util.List; import com.aliyun.fastmodel.core.tree.IAstVisitor; import com.aliyun.fastmodel.core.tree.expr.BaseExpression; @@ -7,16 +9,16 @@ import com.aliyun.fastmodel.core.tree.expr.literal.StringLiteral; import com.aliyun.fastmodel.core.tree.statement.table.ColumnDefinition; import com.aliyun.fastmodel.core.tree.statement.table.PartitionedBy; -import com.aliyun.fastmodel.transform.starrocks.parser.visitor.StarRocksAstVisitor; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.PartitionDesc; +import com.aliyun.fastmodel.transform.api.extension.visitor.ExtensionAstVisitor; import lombok.Getter; import org.apache.commons.collections.CollectionUtils; -import java.util.List; - /** - * StarRocksPartitionedBy + * ExpressionPartitionedBy * * @author 子梁 + * @author panguanjing 为支持扩展移动到api * @date 2023/12/26 */ @Getter @@ -33,8 +35,8 @@ public class ExpressionPartitionBy extends PartitionedBy { private final List rangePartitions; public ExpressionPartitionBy(List columnDefinitions, - FunctionCall functionCall, - List rangePartitions) { + FunctionCall functionCall, + List rangePartitions) { super(columnDefinitions); this.functionCall = functionCall; this.rangePartitions = rangePartitions; @@ -42,8 +44,8 @@ public ExpressionPartitionBy(List columnDefinitions, @Override public R accept(IAstVisitor visitor, C context) { - StarRocksAstVisitor starRocksVisitor = (StarRocksAstVisitor)visitor; - return starRocksVisitor.visitExpressionPartitionedBy(this, context); + ExtensionAstVisitor extensionVisitor = (ExtensionAstVisitor)visitor; + return extensionVisitor.visitExpressionPartitionedBy(this, context); } public StringLiteral getTimeUnitArg() { diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/ListPartitionedBy.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/ListPartitionedBy.java similarity index 68% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/ListPartitionedBy.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/ListPartitionedBy.java index 1f01bd4..03914be 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/ListPartitionedBy.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/ListPartitionedBy.java @@ -1,11 +1,12 @@ -package com.aliyun.fastmodel.transform.starrocks.parser.tree.partition; +package com.aliyun.fastmodel.transform.api.extension.tree.partition; import java.util.List; import com.aliyun.fastmodel.core.tree.IAstVisitor; import com.aliyun.fastmodel.core.tree.statement.table.ColumnDefinition; import com.aliyun.fastmodel.core.tree.statement.table.PartitionedBy; -import com.aliyun.fastmodel.transform.starrocks.parser.visitor.StarRocksAstVisitor; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.PartitionDesc; +import com.aliyun.fastmodel.transform.api.extension.visitor.ExtensionAstVisitor; import lombok.Getter; /** @@ -30,7 +31,7 @@ public ListPartitionedBy(List columnDefinitions, @Override public R accept(IAstVisitor visitor, C context) { - StarRocksAstVisitor starRocksVisitor = (StarRocksAstVisitor)visitor; - return starRocksVisitor.visitListPartitionedBy(this, context); + ExtensionAstVisitor extensionVisitor = (ExtensionAstVisitor)visitor; + return extensionVisitor.visitListPartitionedBy(this, context); } } diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/RangePartitionedBy.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/RangePartitionedBy.java similarity index 66% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/RangePartitionedBy.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/RangePartitionedBy.java index ba175f4..97b9db4 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/RangePartitionedBy.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/RangePartitionedBy.java @@ -1,15 +1,16 @@ -package com.aliyun.fastmodel.transform.starrocks.parser.tree.partition; +package com.aliyun.fastmodel.transform.api.extension.tree.partition; import java.util.List; import com.aliyun.fastmodel.core.tree.IAstVisitor; import com.aliyun.fastmodel.core.tree.statement.table.ColumnDefinition; import com.aliyun.fastmodel.core.tree.statement.table.PartitionedBy; -import com.aliyun.fastmodel.transform.starrocks.parser.visitor.StarRocksAstVisitor; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.PartitionDesc; +import com.aliyun.fastmodel.transform.api.extension.visitor.ExtensionAstVisitor; import lombok.Getter; /** - * StarRocksPartitionedBy + * RangePartitionedBy * * @author panguanjing * @date 2023/9/13 @@ -30,7 +31,7 @@ public RangePartitionedBy(List columnDefinitions, @Override public R accept(IAstVisitor visitor, C context) { - StarRocksAstVisitor starRocksVisitor = (StarRocksAstVisitor)visitor; - return starRocksVisitor.visitRangePartitionedBy(this, context); + ExtensionAstVisitor extensionVisitor = (ExtensionAstVisitor)visitor; + return extensionVisitor.visitRangePartitionedBy(this, context); } } diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/MultiItemListPartition.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/desc/MultiItemListPartition.java similarity index 85% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/MultiItemListPartition.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/desc/MultiItemListPartition.java index 202b3b3..f1eaccf 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/MultiItemListPartition.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/desc/MultiItemListPartition.java @@ -1,4 +1,4 @@ -package com.aliyun.fastmodel.transform.starrocks.parser.tree.partition; +package com.aliyun.fastmodel.transform.api.extension.tree.partition.desc; import java.util.List; @@ -7,7 +7,7 @@ import com.aliyun.fastmodel.core.tree.Property; import com.aliyun.fastmodel.core.tree.expr.Identifier; import com.aliyun.fastmodel.core.tree.expr.literal.ListStringLiteral; -import com.aliyun.fastmodel.transform.starrocks.parser.visitor.StarRocksAstVisitor; +import com.aliyun.fastmodel.transform.api.extension.visitor.ExtensionAstVisitor; import com.google.common.collect.ImmutableList; import lombok.Getter; @@ -53,7 +53,7 @@ public List getChildren() { @Override public R accept(IAstVisitor visitor, C context) { - StarRocksAstVisitor starRocksVisitor = (StarRocksAstVisitor)visitor; - return starRocksVisitor.visitMultiItemListPartition(this, context); + ExtensionAstVisitor extensionVisitor = (ExtensionAstVisitor)visitor; + return extensionVisitor.visitMultiItemListPartition(this, context); } } diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/MultiRangePartition.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/desc/MultiRangePartition.java similarity index 59% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/MultiRangePartition.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/desc/MultiRangePartition.java index a7cfc31..ecdd00b 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/MultiRangePartition.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/desc/MultiRangePartition.java @@ -1,4 +1,4 @@ -package com.aliyun.fastmodel.transform.starrocks.parser.tree.partition; +package com.aliyun.fastmodel.transform.api.extension.tree.partition.desc; import java.util.List; @@ -7,8 +7,11 @@ import com.aliyun.fastmodel.core.tree.expr.literal.IntervalLiteral; import com.aliyun.fastmodel.core.tree.expr.literal.LongLiteral; import com.aliyun.fastmodel.core.tree.expr.literal.StringLiteral; -import com.aliyun.fastmodel.transform.starrocks.parser.visitor.StarRocksAstVisitor; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.ListPartitionValue; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.PartitionValue; +import com.aliyun.fastmodel.transform.api.extension.visitor.ExtensionAstVisitor; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; import lombok.Getter; /** @@ -19,12 +22,12 @@ */ @Getter public class MultiRangePartition extends PartitionDesc { - private final StringLiteral start; - private final StringLiteral end; + private final ListPartitionValue start; + private final ListPartitionValue end; private final IntervalLiteral intervalLiteral; private final LongLiteral longLiteral; - public MultiRangePartition(StringLiteral start, StringLiteral end, IntervalLiteral intervalLiteral, + public MultiRangePartition(ListPartitionValue start, ListPartitionValue end, IntervalLiteral intervalLiteral, LongLiteral longLiteral) { this.start = start; this.end = end; @@ -32,6 +35,14 @@ public MultiRangePartition(StringLiteral start, StringLiteral end, IntervalLiter this.longLiteral = longLiteral; } + public MultiRangePartition(StringLiteral start, StringLiteral end, IntervalLiteral intervalLiteral, + LongLiteral longLiteral) { + this.start = new ListPartitionValue(Lists.newArrayList(new PartitionValue(start))); + this.end = new ListPartitionValue(Lists.newArrayList(new PartitionValue(end))); + this.intervalLiteral = intervalLiteral; + this.longLiteral = longLiteral; + } + @Override public List getChildren() { ImmutableList.Builder builder = ImmutableList.builder(); @@ -52,7 +63,7 @@ public List getChildren() { @Override public R accept(IAstVisitor visitor, C context) { - StarRocksAstVisitor starRocksVisitor = (StarRocksAstVisitor)visitor; - return starRocksVisitor.visitMultiRangePartition(this, context); + ExtensionAstVisitor extensionVisitor = (ExtensionAstVisitor)visitor; + return extensionVisitor.visitMultiRangePartition(this, context); } } diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/PartitionDesc.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/desc/PartitionDesc.java similarity index 55% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/PartitionDesc.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/desc/PartitionDesc.java index d1d5029..a83d126 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/PartitionDesc.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/desc/PartitionDesc.java @@ -1,8 +1,8 @@ -package com.aliyun.fastmodel.transform.starrocks.parser.tree.partition; +package com.aliyun.fastmodel.transform.api.extension.tree.partition.desc; import com.aliyun.fastmodel.core.tree.AbstractNode; import com.aliyun.fastmodel.core.tree.IAstVisitor; -import com.aliyun.fastmodel.transform.starrocks.parser.visitor.StarRocksAstVisitor; +import com.aliyun.fastmodel.transform.api.extension.visitor.ExtensionAstVisitor; /** * RangePartition @@ -14,7 +14,7 @@ public abstract class PartitionDesc extends AbstractNode { @Override public R accept(IAstVisitor visitor, C context) { - StarRocksAstVisitor starRocksVisitor = (StarRocksAstVisitor)visitor; - return starRocksVisitor.visitPartitionDesc(this, context); + ExtensionAstVisitor extensionVisitor = (ExtensionAstVisitor)visitor; + return extensionVisitor.visitPartitionDesc(this, context); } } diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/SingleItemListPartition.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/desc/SingleItemListPartition.java similarity index 85% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/SingleItemListPartition.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/desc/SingleItemListPartition.java index fa631ad..b5aa045 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/SingleItemListPartition.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/desc/SingleItemListPartition.java @@ -1,4 +1,4 @@ -package com.aliyun.fastmodel.transform.starrocks.parser.tree.partition; +package com.aliyun.fastmodel.transform.api.extension.tree.partition.desc; import java.util.List; @@ -7,7 +7,7 @@ import com.aliyun.fastmodel.core.tree.Property; import com.aliyun.fastmodel.core.tree.expr.Identifier; import com.aliyun.fastmodel.core.tree.expr.literal.ListStringLiteral; -import com.aliyun.fastmodel.transform.starrocks.parser.visitor.StarRocksAstVisitor; +import com.aliyun.fastmodel.transform.api.extension.visitor.ExtensionAstVisitor; import com.google.common.collect.ImmutableList; import lombok.Getter; @@ -35,8 +35,8 @@ public SingleItemListPartition(Identifier name, boolean ifNotExists, @Override public R accept(IAstVisitor visitor, C context) { - StarRocksAstVisitor starRocksVisitor = (StarRocksAstVisitor)visitor; - return starRocksVisitor.visitSingleItemListPartition(this, context); + ExtensionAstVisitor extensionVisitor = (ExtensionAstVisitor)visitor; + return extensionVisitor.visitSingleItemListPartition(this, context); } @Override diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/SingleRangePartition.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/desc/SingleRangePartition.java similarity index 79% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/SingleRangePartition.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/desc/SingleRangePartition.java index 7cde507..59145b2 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/SingleRangePartition.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/desc/SingleRangePartition.java @@ -1,4 +1,4 @@ -package com.aliyun.fastmodel.transform.starrocks.parser.tree.partition; +package com.aliyun.fastmodel.transform.api.extension.tree.partition.desc; import java.util.List; @@ -6,7 +6,8 @@ import com.aliyun.fastmodel.core.tree.Node; import com.aliyun.fastmodel.core.tree.Property; import com.aliyun.fastmodel.core.tree.expr.Identifier; -import com.aliyun.fastmodel.transform.starrocks.parser.visitor.StarRocksAstVisitor; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.PartitionKey; +import com.aliyun.fastmodel.transform.api.extension.visitor.ExtensionAstVisitor; import com.google.common.collect.ImmutableList; import lombok.Getter; @@ -47,7 +48,7 @@ public List getChildren() { @Override public R accept(IAstVisitor visitor, C context) { - StarRocksAstVisitor starRocksVisitor = (StarRocksAstVisitor)visitor; - return starRocksVisitor.visitSingleRangePartition(this, context); + ExtensionAstVisitor extensionVisitor = (ExtensionAstVisitor)visitor; + return extensionVisitor.visitSingleRangePartition(this, context); } } diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/ArrayPartitionKey.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/keyvalue/ArrayPartitionKey.java similarity index 70% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/ArrayPartitionKey.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/keyvalue/ArrayPartitionKey.java index c34b8ed..e71bc73 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/ArrayPartitionKey.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/keyvalue/ArrayPartitionKey.java @@ -1,10 +1,10 @@ -package com.aliyun.fastmodel.transform.starrocks.parser.tree.partition; +package com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue; import java.util.List; import com.aliyun.fastmodel.core.tree.IAstVisitor; import com.aliyun.fastmodel.core.tree.Node; -import com.aliyun.fastmodel.transform.starrocks.parser.visitor.StarRocksAstVisitor; +import com.aliyun.fastmodel.transform.api.extension.visitor.ExtensionAstVisitor; import lombok.Getter; /** @@ -27,7 +27,7 @@ public List getChildren() { @Override public R accept(IAstVisitor visitor, C context) { - StarRocksAstVisitor starRocksVisitor = (StarRocksAstVisitor)visitor; - return starRocksVisitor.visitArrayPartitionKey(this, context); + ExtensionAstVisitor extensionVisitor = (ExtensionAstVisitor)visitor; + return extensionVisitor.visitArrayPartitionKey(this, context); } } diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/LessThanPartitionKey.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/keyvalue/LessThanPartitionKey.java similarity index 73% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/LessThanPartitionKey.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/keyvalue/LessThanPartitionKey.java index 909f6b5..782d9d2 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/LessThanPartitionKey.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/keyvalue/LessThanPartitionKey.java @@ -1,11 +1,10 @@ -package com.aliyun.fastmodel.transform.starrocks.parser.tree.partition; +package com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue; import java.util.List; import com.aliyun.fastmodel.core.tree.IAstVisitor; import com.aliyun.fastmodel.core.tree.Node; -import com.aliyun.fastmodel.core.tree.expr.literal.StringLiteral; -import com.aliyun.fastmodel.transform.starrocks.parser.visitor.StarRocksAstVisitor; +import com.aliyun.fastmodel.transform.api.extension.visitor.ExtensionAstVisitor; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import lombok.Getter; @@ -30,7 +29,7 @@ public LessThanPartitionKey(boolean maxValue, ListPartitionValue partitionValues public LessThanPartitionKey(ListPartitionValue partitionValues) { this.partitionValues = partitionValues; - this.maxValue =false; + this.maxValue = false; } @Override @@ -43,7 +42,7 @@ public List getChildren() { @Override public R accept(IAstVisitor visitor, C context) { - StarRocksAstVisitor starRocksVisitor = (StarRocksAstVisitor)visitor; - return starRocksVisitor.visitLessThanPartitionKey(this, context); + ExtensionAstVisitor extensionVisitor = (ExtensionAstVisitor)visitor; + return extensionVisitor.visitLessThanPartitionKey(this, context); } } diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/ListPartitionValue.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/keyvalue/ListPartitionValue.java similarity index 77% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/ListPartitionValue.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/keyvalue/ListPartitionValue.java index ec9bbc7..77ab4ee 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/ListPartitionValue.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/keyvalue/ListPartitionValue.java @@ -1,4 +1,4 @@ -package com.aliyun.fastmodel.transform.starrocks.parser.tree.partition; +package com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue; import java.util.List; @@ -6,7 +6,7 @@ import com.aliyun.fastmodel.core.tree.IAstVisitor; import com.aliyun.fastmodel.core.tree.Node; import com.aliyun.fastmodel.core.tree.NodeLocation; -import com.aliyun.fastmodel.transform.starrocks.parser.visitor.StarRocksAstVisitor; +import com.aliyun.fastmodel.transform.api.extension.visitor.ExtensionAstVisitor; import lombok.Getter; /** @@ -35,7 +35,7 @@ public List getChildren() { @Override public R accept(IAstVisitor visitor, C context) { - StarRocksAstVisitor starRocksVisitor = (StarRocksAstVisitor)visitor; - return starRocksVisitor.visitListPartitionValue(this, context); + ExtensionAstVisitor extensionVisitor = (ExtensionAstVisitor)visitor; + return extensionVisitor.visitListPartitionValue(this, context); } } diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/PartitionKey.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/keyvalue/PartitionKey.java similarity index 54% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/PartitionKey.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/keyvalue/PartitionKey.java index e46ce38..255da59 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/PartitionKey.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/keyvalue/PartitionKey.java @@ -1,8 +1,8 @@ -package com.aliyun.fastmodel.transform.starrocks.parser.tree.partition; +package com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue; import com.aliyun.fastmodel.core.tree.AbstractNode; import com.aliyun.fastmodel.core.tree.IAstVisitor; -import com.aliyun.fastmodel.transform.starrocks.parser.visitor.StarRocksAstVisitor; +import com.aliyun.fastmodel.transform.api.extension.visitor.ExtensionAstVisitor; /** * partition key @@ -14,7 +14,7 @@ public abstract class PartitionKey extends AbstractNode { @Override public R accept(IAstVisitor visitor, C context) { - StarRocksAstVisitor starRocksVisitor = (StarRocksAstVisitor)visitor; - return starRocksVisitor.visitPartitionKey(this, context); + ExtensionAstVisitor extensionVisitor = (ExtensionAstVisitor)visitor; + return extensionVisitor.visitPartitionKey(this, context); } } diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/PartitionValue.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/keyvalue/PartitionValue.java similarity index 54% rename from fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/PartitionValue.java rename to fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/keyvalue/PartitionValue.java index 2516ce8..4d3b79e 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/partition/PartitionValue.java +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/tree/partition/keyvalue/PartitionValue.java @@ -1,12 +1,12 @@ -package com.aliyun.fastmodel.transform.starrocks.parser.tree.partition; +package com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue; import java.util.List; import com.aliyun.fastmodel.core.tree.AbstractNode; import com.aliyun.fastmodel.core.tree.IAstVisitor; import com.aliyun.fastmodel.core.tree.Node; -import com.aliyun.fastmodel.core.tree.expr.literal.StringLiteral; -import com.aliyun.fastmodel.transform.starrocks.parser.visitor.StarRocksAstVisitor; +import com.aliyun.fastmodel.core.tree.expr.BaseExpression; +import com.aliyun.fastmodel.transform.api.extension.visitor.ExtensionAstVisitor; import com.google.common.collect.ImmutableList; import lombok.Getter; @@ -21,14 +21,13 @@ public class PartitionValue extends AbstractNode { private final boolean maxValue; - private final StringLiteral stringLiteral; + private final BaseExpression stringLiteral; - public PartitionValue(StringLiteral stringLiteral) { - this.stringLiteral = stringLiteral; - this.maxValue = false; + public PartitionValue(BaseExpression stringLiteral) { + this(false, stringLiteral); } - public PartitionValue(boolean maxValue, StringLiteral stringLiteral) { + public PartitionValue(boolean maxValue, BaseExpression stringLiteral) { this.maxValue = maxValue; this.stringLiteral = stringLiteral; } @@ -40,7 +39,7 @@ public List getChildren() { @Override public R accept(IAstVisitor visitor, C context) { - StarRocksAstVisitor starRocksVisitor = (StarRocksAstVisitor)visitor; - return starRocksVisitor.visitPartitionValue(this, context); + ExtensionAstVisitor extensionVisitor = (ExtensionAstVisitor)visitor; + return extensionVisitor.visitPartitionValue(this, context); } } diff --git a/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/visitor/ExtensionAstVisitor.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/visitor/ExtensionAstVisitor.java new file mode 100644 index 0000000..48e78e5 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/extension/visitor/ExtensionAstVisitor.java @@ -0,0 +1,231 @@ +package com.aliyun.fastmodel.transform.api.extension.visitor; + +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.AggregateKeyConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.CheckExpressionConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.DuplicateKeyConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.ForeignKeyConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.UniqueKeyExprConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.ClusterKeyConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.DistributeConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.OrderByConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.RollupConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.RollupItem; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.ExpressionPartitionBy; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.ListPartitionedBy; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.RangePartitionedBy; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.MultiItemListPartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.MultiRangePartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.PartitionDesc; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.SingleItemListPartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.SingleRangePartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.ArrayPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.LessThanPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.ListPartitionValue; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.PartitionKey; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.PartitionValue; + +/** + * 扩展的visitor + * + * @author panguanjing + * @date 2024/1/21 + */ +public interface ExtensionAstVisitor extends IAstVisitor { + /** + * visit array partition key + * + * @param arrayPartitionKey arrayPartitionKey + * @param context context + * @return + */ + default R visitArrayPartitionKey(ArrayPartitionKey arrayPartitionKey, C context) { + return visitPartitionKey(arrayPartitionKey, context); + } + + /** + * visit partition key + * + * @param partitionKey + * @param context + * @return + */ + default R visitPartitionKey(PartitionKey partitionKey, C context) { + return visitNode(partitionKey, context); + } + + /** + * visitExpressionPartitionBy + * + * @param expressionPartitionedBy + * @param context + * @return + */ + default R visitExpressionPartitionedBy(ExpressionPartitionBy expressionPartitionedBy, C context) { + return visitNode(expressionPartitionedBy, context); + } + + /** + * single range partition + * + * @param singleRangePartition + * @param context + * @return + */ + default R visitSingleRangePartition(SingleRangePartition singleRangePartition, C context) { + return visitNode(singleRangePartition, context); + } + + /** + * multi range partition + * + * @param multiRangePartition + * @param context + * @return + */ + default R visitMultiRangePartition(MultiRangePartition multiRangePartition, C context) { + return visitNode(multiRangePartition, context); + } + + /** + * visit less than partition key + * + * @param lessThanPartitionKey + * @param context + * @return + */ + default R visitLessThanPartitionKey(LessThanPartitionKey lessThanPartitionKey, C context) { + return visitPartitionKey(lessThanPartitionKey, context); + } + + /** + * visit single item partition + * + * @param singleItemListPartition + * @param context + * @return + */ + default R visitSingleItemListPartition(SingleItemListPartition singleItemListPartition, C context) { + return visitNode(singleItemListPartition, context); + } + + /** + * visitListPartitionedBy + * + * @param listPartitionedBy + * @param context + * @return + */ + default R visitListPartitionedBy(ListPartitionedBy listPartitionedBy, C context) { + return visitNode(listPartitionedBy, context); + } + + /** + * visit list partition value + * + * @param listPartitionValue + * @param context + * @return + */ + default R visitListPartitionValue(ListPartitionValue listPartitionValue, C context) { + return visitNode(listPartitionValue, context); + } + + /** + * visit multiItemListPartition + * + * @param multiItemListPartition + * @param context + * @return + */ + default R visitMultiItemListPartition(MultiItemListPartition multiItemListPartition, C context) { + return visitNode(multiItemListPartition, context); + } + + /** + * visit partition desc + * + * @param partitionDesc + * @param context + * @return + */ + default R visitPartitionDesc(PartitionDesc partitionDesc, C context) { + return visitNode(partitionDesc, context); + } + + /** + * visit partition value + * + * @param partitionValue + * @param context + * @return + */ + default R visitPartitionValue(PartitionValue partitionValue, C context) { + return visitNode(partitionValue, context); + } + + /** + * visit starRocks partitioned by + * + * @param starRocksPartitionedBy + * @param context + * @return + */ + default R visitRangePartitionedBy(RangePartitionedBy starRocksPartitionedBy, C context) { + return visitNode(starRocksPartitionedBy, context); + } + + /** + * visitAggregateConstraint + * + * @param aggregateConstraint + * @param context + * @return + */ + default R visitAggregateConstraint(AggregateKeyConstraint aggregateConstraint, C context) { + return visitNode(aggregateConstraint, context); + } + + /** + * visit duplicate constraint + * + * @param duplicateConstraint + * @param context + * @return + */ + default R visitDuplicateConstraint(DuplicateKeyConstraint duplicateConstraint, C context) { + return visitNode(duplicateConstraint, context); + } + + default R visitOrderByConstraint(OrderByConstraint orderByConstraint, C context) { + return visitNode(orderByConstraint, context); + } + + default R visitDistributeKeyConstraint(DistributeConstraint distributeKeyConstraint, C context) { + return visitNode(distributeKeyConstraint, context); + } + + default R visitRollupItem(RollupItem rollupItem, C context) { + return visitNode(rollupItem, context); + } + + default R visitRollupConstraint(RollupConstraint rollupConstraint, C context) { + return visitNode(rollupConstraint, context); + } + + default R visitClusterKeyConstraint(ClusterKeyConstraint clusterKeyConstraint, C context) { + return visitNode(clusterKeyConstraint, context); + } + + default R visitCheckExpressionConstraint(CheckExpressionConstraint checkExpressionConstraint, C context) { + return visitNode(checkExpressionConstraint, context); + } + + default R visitForeignKeyConstraint(ForeignKeyConstraint foreignKeyConstraint, C context) { + return visitNode(foreignKeyConstraint, context); + } + + default R visitUniqueKeyExprConstraint(UniqueKeyExprConstraint uniqueKeyExprConstraint, C context) { + return visitNode(uniqueKeyExprConstraint, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/format/PropertyValueType.java b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/format/PropertyValueType.java new file mode 100644 index 0000000..1cfd90e --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-api/src/main/java/com/aliyun/fastmodel/transform/api/format/PropertyValueType.java @@ -0,0 +1,28 @@ +package com.aliyun.fastmodel.transform.api.format; + +/** + * OptionValueType + * + * @author panguanjing + * @date 2024/2/17 + */ +public enum PropertyValueType { + + /** + * EXPRESSION + */ + EXPRESSION, + /** + * identifier + */ + IDENTIFIER, + /** + * string literal + */ + STRING_LITERAL, + + /** + * number literal + */ + NUMBER_LITERAL; +} diff --git a/fastmodel-transform/fastmodel-transform-api/src/test/java/com/aliyun/fastmodel/transform/api/dialect/DialectNameTest.java b/fastmodel-transform/fastmodel-transform-api/src/test/java/com/aliyun/fastmodel/transform/api/dialect/DialectNameTest.java index c31f309..9b859ac 100644 --- a/fastmodel-transform/fastmodel-transform-api/src/test/java/com/aliyun/fastmodel/transform/api/dialect/DialectNameTest.java +++ b/fastmodel-transform/fastmodel-transform-api/src/test/java/com/aliyun/fastmodel/transform/api/dialect/DialectNameTest.java @@ -10,7 +10,7 @@ import org.junit.Test; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; /** * DialectNameTest @@ -28,4 +28,10 @@ public void getDialectName() { maxcompute = DialectName.getByCode("Max_compute"); assertEquals(maxcompute, DialectName.MAXCOMPUTE); } + + @Test + public void testDoris() { + DialectName dialectName = DialectName.getByCode("doris"); + assertEquals(dialectName, DialectName.DORIS); + } } \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-doris/pom.xml b/fastmodel-transform/fastmodel-transform-doris/pom.xml new file mode 100644 index 0000000..6f86471 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/pom.xml @@ -0,0 +1,37 @@ + + + 4.0.0 + + com.aliyun.fastmodel + fastmodel-transform + ${revision} + + + fastmodel-transform-doris + + + UTF-8 + + + + + com.aliyun.fastmodel + fastmodel-transform-api + ${project.version} + + + + com.aliyun.fastmodel + fastmodel-common + ${project.version} + + + + commons-io + commons-io + test + + + \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-doris/src/main/antlr4/com/aliyun/fastmodel/transform/doris/parser/DorisLexer.g4 b/fastmodel-transform/fastmodel-transform-doris/src/main/antlr4/com/aliyun/fastmodel/transform/doris/parser/DorisLexer.g4 new file mode 100644 index 0000000..488c8b8 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/main/antlr4/com/aliyun/fastmodel/transform/doris/parser/DorisLexer.g4 @@ -0,0 +1,671 @@ +// 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. + +// Copied from Apache Spark and modified for Apache Doris + +lexer grammar DorisLexer; + +@members { + /** + * When true, parser should throw ParseExcetion for unclosed bracketed comment. + */ + public boolean has_unclosed_bracketed_comment = false; + + /** + * Verify whether current token is a valid decimal token (which contains dot). + * Returns true if the character that follows the token is not a digit or letter or underscore. + * + * For example: + * For char stream "2.3", "2." is not a valid decimal token, because it is followed by digit '3'. + * For char stream "2.3_", "2.3" is not a valid decimal token, because it is followed by '_'. + * For char stream "2.3W", "2.3" is not a valid decimal token, because it is followed by 'W'. + * For char stream "12.0D 34.E2+0.12 " 12.0D is a valid decimal token because it is followed + * by a space. 34.E2 is a valid decimal token because it is followed by symbol '+' + * which is not a digit or letter or underscore. + */ + public boolean isValidDecimal() { + int nextChar = _input.LA(1); + if (nextChar >= 'A' && nextChar <= 'Z' || nextChar >= '0' && nextChar <= '9' || + nextChar == '_') { + return false; + } else { + return true; + } + } + + /** + * This method will be called when we see '/*' and try to match it as a bracketed comment. + * If the next character is '+', it should be parsed as hint later, and we cannot match + * it as a bracketed comment. + * + * Returns true if the next character is '+'. + */ + public boolean isHint() { + int nextChar = _input.LA(1); + if (nextChar == '+') { + return true; + } else { + return false; + } + } + + /** + * This method will be called when the character stream ends and try to find out the + * unclosed bracketed comment. + * If the method be called, it means the end of the entire character stream match, + * and we set the flag and fail later. + */ + public void markUnclosedComment() { + has_unclosed_bracketed_comment = true; + } +} + +SEMICOLON: ';'; + +LEFT_PAREN: '('; +RIGHT_PAREN: ')'; +COMMA: ','; +DOT: '.'; +LEFT_BRACKET: '['; +RIGHT_BRACKET: ']'; +LEFT_BRACE: '{'; +RIGHT_BRACE: '}'; + +// TODO: add a doc to list reserved words + +//============================ +// Start of the keywords list +//============================ +//--DORIS-KEYWORD-LIST-START +ACCOUNT_LOCK: 'ACCOUNT_LOCK'; +ACCOUNT_UNLOCK: 'ACCOUNT_UNLOCK'; +ADD: 'ADD'; +ADDDATE:'ADDDATE'; +ADMIN: 'ADMIN'; +AFTER: 'AFTER'; +AGG_STATE: 'AGG_STATE'; +AGGREGATE: 'AGGREGATE'; +ALIAS: 'ALIAS'; +ALL: 'ALL'; +ALTER: 'ALTER'; +ANALYZE: 'ANALYZE'; +ANALYZED: 'ANALYZED'; +AND: 'AND'; +ANTI: 'ANTI'; +APPEND: 'APPEND'; +ARRAY: 'ARRAY'; +AS: 'AS'; +ASC: 'ASC'; +AT: 'AT'; +AUTHORS: 'AUTHORS'; +AUTO: 'AUTO'; +AUTO_INCREMENT: 'AUTO_INCREMENT'; +BACKEND: 'BACKEND'; +BACKENDS: 'BACKENDS'; +BACKUP: 'BACKUP'; +BEGIN: 'BEGIN'; +BETWEEN: 'BETWEEN'; +BIGINT: 'BIGINT'; +BIN: 'BIN'; +BINARY: 'BINARY'; +BINLOG: 'BINLOG'; +BITAND: 'BITAND'; +BITMAP: 'BITMAP'; +BITMAP_UNION: 'BITMAP_UNION'; +BITOR: 'BITOR'; +BITXOR: 'BITXOR'; +BLOB: 'BLOB'; +BOOLEAN: 'BOOLEAN'; +BRIEF: 'BRIEF'; +BROKER: 'BROKER'; +BUCKETS: 'BUCKETS'; +BUILD: 'BUILD'; +BUILTIN: 'BUILTIN'; +BY: 'BY'; +CACHED: 'CACHED'; +CALL: 'CALL'; +CANCEL: 'CANCEL'; +CASE: 'CASE'; +CAST: 'CAST'; +CATALOG: 'CATALOG'; +CATALOGS: 'CATALOGS'; +CHAIN: 'CHAIN'; +CHAR: 'CHAR' | 'CHARACTER'; +CHARSET: 'CHARSET'; +CHECK: 'CHECK'; +CLEAN: 'CLEAN'; +CLUSTER: 'CLUSTER'; +CLUSTERS: 'CLUSTERS'; +COLLATE: 'COLLATE'; +COLLATION: 'COLLATION'; +COLUMN: 'COLUMN'; +COLUMNS: 'COLUMNS'; +COMMENT: 'COMMENT'; +COMMIT: 'COMMIT'; +COMMITTED: 'COMMITTED'; +COMPACT: 'COMPACT'; +COMPLETE: 'COMPLETE'; +CONFIG: 'CONFIG'; +CONNECTION: 'CONNECTION'; +CONNECTION_ID: 'CONNECTION_ID'; +CONSISTENT: 'CONSISTENT'; +CONSTRAINT: 'CONSTRAINT'; +CONVERT: 'CONVERT'; +COPY: 'COPY'; +COUNT: 'COUNT'; +CREATE: 'CREATE'; +CREATION: 'CREATION'; +CRON: 'CRON'; +CROSS: 'CROSS'; +CUBE: 'CUBE'; +CURRENT: 'CURRENT'; +CURRENT_CATALOG: 'CURRENT_CATALOG'; +CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'; +CURRENT_USER: 'CURRENT_USER'; +DATA: 'DATA'; +DATABASE: 'DATABASE'; +DATABASES: 'DATABASES'; +DATE: 'DATE'; +DATE_ADD: 'DATE_ADD'; +DATE_CEIL: 'DATE_CEIL'; +DATE_DIFF: 'DATE_DIFF'; +DATE_FLOOR: 'DATE_FLOOR'; +DATE_SUB: 'DATE_SUB'; +DATEADD: 'DATEADD'; +DATEDIFF: 'DATEDIFF'; +DATETIME: 'DATETIME'; +DATETIMEV2: 'DATETIMEV2'; +DATEV2: 'DATEV2'; +DATETIMEV1: 'DATETIMEV1'; +DATEV1: 'DATEV1'; +DAY: 'DAY'; +DAYS_ADD: 'DAYS_ADD'; +DAYS_SUB: 'DAYS_SUB'; +DECIMAL: 'DECIMAL'; +DECIMALV2: 'DECIMALV2'; +DECIMALV3: 'DECIMALV3'; +DECOMMISSION: 'DECOMMISSION'; +DEFAULT: 'DEFAULT'; +DEFERRED: 'DEFERRED'; +DELETE: 'DELETE'; +DEMAND: 'DEMAND'; +DESC: 'DESC'; +DESCRIBE: 'DESCRIBE'; +DIAGNOSE: 'DIAGNOSE'; +DISK: 'DISK'; +DISTINCT: 'DISTINCT'; +DISTINCTPC: 'DISTINCTPC'; +DISTINCTPCSA: 'DISTINCTPCSA'; +DISTRIBUTED: 'DISTRIBUTED'; +DISTRIBUTION: 'DISTRIBUTION'; +DIV: 'DIV'; +DO: 'DO'; +DORIS_INTERNAL_TABLE_ID: 'DORIS_INTERNAL_TABLE_ID'; +DOUBLE: 'DOUBLE'; +DROP: 'DROP'; +DROPP: 'DROPP'; +DUPLICATE: 'DUPLICATE'; +DYNAMIC: 'DYNAMIC'; +ELSE: 'ELSE'; +ENABLE: 'ENABLE'; +ENCRYPTKEY: 'ENCRYPTKEY'; +ENCRYPTKEYS: 'ENCRYPTKEYS'; +END: 'END'; +ENDS: 'ENDS'; +ENGINE: 'ENGINE'; +ENGINES: 'ENGINES'; +ENTER: 'ENTER'; +ERRORS: 'ERRORS'; +EVENTS: 'EVENTS'; +EVERY: 'EVERY'; +EXCEPT: 'EXCEPT'; +EXCLUDE: 'EXCLUDE'; +EXECUTE: 'EXECUTE'; +EXISTS: 'EXISTS'; +EXPIRED: 'EXPIRED'; +EXPLAIN: 'EXPLAIN'; +EXPORT: 'EXPORT'; +EXTENDED: 'EXTENDED'; +EXTERNAL: 'EXTERNAL'; +EXTRACT: 'EXTRACT'; +FAILED_LOGIN_ATTEMPTS: 'FAILED_LOGIN_ATTEMPTS'; +FALSE: 'FALSE'; +FAST: 'FAST'; +FEATURE: 'FEATURE'; +FIELDS: 'FIELDS'; +FILE: 'FILE'; +FILTER: 'FILTER'; +FIRST: 'FIRST'; +FLOAT: 'FLOAT'; +FOLLOWER: 'FOLLOWER'; +FOLLOWING: 'FOLLOWING'; +FOR: 'FOR'; +FOREIGN: 'FOREIGN'; +FORCE: 'FORCE'; +FORMAT: 'FORMAT'; +FREE: 'FREE'; +FROM: 'FROM'; +FRONTEND: 'FRONTEND'; +FRONTENDS: 'FRONTENDS'; +FULL: 'FULL'; +FUNCTION: 'FUNCTION'; +FUNCTIONS: 'FUNCTIONS'; +GLOBAL: 'GLOBAL'; +GRANT: 'GRANT'; +GRANTS: 'GRANTS'; +GRAPH: 'GRAPH'; +GROUP: 'GROUP'; +GROUPING: 'GROUPING'; +GROUPS: 'GROUPS'; +HASH: 'HASH'; +HAVING: 'HAVING'; +HDFS: 'HDFS'; +HELP: 'HELP'; +HISTOGRAM: 'HISTOGRAM'; +HLL: 'HLL'; +HLL_UNION: 'HLL_UNION'; +HOSTNAME: 'HOSTNAME'; +HOUR: 'HOUR'; +HUB: 'HUB'; +IDENTIFIED: 'IDENTIFIED'; +IF: 'IF'; +IGNORE: 'IGNORE'; +IMMEDIATE: 'IMMEDIATE'; +IN: 'IN'; +INCREMENTAL: 'INCREMENTAL'; +INDEX: 'INDEX'; +INDEXES: 'INDEXES'; +INFILE: 'INFILE'; +INNER: 'INNER'; +INSERT: 'INSERT'; +INSTALL: 'INSTALL'; +INT: 'INT'; +INTEGER: 'INTEGER'; +INTERMEDIATE: 'INTERMEDIATE'; +INTERSECT: 'INTERSECT'; +INTERVAL: 'INTERVAL'; +INTO: 'INTO'; +INVERTED: 'INVERTED'; +IPV4: 'IPV4'; +IPV6: 'IPV6'; +IS: 'IS'; +IS_NOT_NULL_PRED: 'IS_NOT_NULL_PRED'; +IS_NULL_PRED: 'IS_NULL_PRED'; +ISNULL: 'ISNULL'; +ISOLATION: 'ISOLATION'; +JOB: 'JOB'; +JOBS: 'JOBS'; +JOIN: 'JOIN'; +JSON: 'JSON'; +JSONB: 'JSONB'; +KEY: 'KEY'; +KEYS: 'KEYS'; +KILL: 'KILL'; +LABEL: 'LABEL'; +LARGEINT: 'LARGEINT'; +LAST: 'LAST'; +LATERAL: 'LATERAL'; +LDAP: 'LDAP'; +LDAP_ADMIN_PASSWORD: 'LDAP_ADMIN_PASSWORD'; +LEFT: 'LEFT'; +LESS: 'LESS'; +LEVEL: 'LEVEL'; +LIKE: 'LIKE'; +LIMIT: 'LIMIT'; +LINES: 'LINES'; +LINK: 'LINK'; +LIST: 'LIST'; +LOAD: 'LOAD'; +LOCAL: 'LOCAL'; +LOCATION: 'LOCATION'; +LOCK: 'LOCK'; +LOGICAL: 'LOGICAL'; +LOW_PRIORITY: 'LOW_PRIORITY'; +MANUAL: 'MANUAL'; +MAP: 'MAP'; +MATCH: 'MATCH'; +MATCH_ALL: 'MATCH_ALL'; +MATCH_ANY: 'MATCH_ANY'; +MATCH_ELEMENT_EQ: 'ELEMENT_EQ'; +MATCH_ELEMENT_GE: 'ELEMENT_GE'; +MATCH_ELEMENT_GT: 'ELEMENT_GT'; +MATCH_ELEMENT_LE: 'ELEMENT_LE'; +MATCH_ELEMENT_LT: 'ELEMENT_LT'; +MATCH_PHRASE: 'MATCH_PHRASE'; +MATCH_PHRASE_PREFIX: 'MATCH_PHRASE_PREFIX'; +MATCH_REGEXP: 'MATCH_REGEXP'; +MATERIALIZED: 'MATERIALIZED'; +MAX: 'MAX'; +MAXVALUE: 'MAXVALUE'; +MEMO:'MEMO'; +MERGE: 'MERGE'; +MIGRATE: 'MIGRATE'; +MIGRATIONS: 'MIGRATIONS'; +MIN: 'MIN'; +MINUS: 'MINUS'; +MINUTE: 'MINUTE'; +MODIFY: 'MODIFY'; +MONTH: 'MONTH'; +MTMV: 'MTMV'; +NAME: 'NAME'; +NAMES: 'NAMES'; +NATURAL: 'NATURAL'; +NEGATIVE: 'NEGATIVE'; +NEVER: 'NEVER'; +NEXT: 'NEXT'; +NGRAM_BF: 'NGRAM_BF'; +NO: 'NO'; +NON_NULLABLE: 'NON_NULLABLE'; +NOT: 'NOT'; +NULL: 'NULL'; +NULLS: 'NULLS'; +OBSERVER: 'OBSERVER'; +OF: 'OF'; +OFFSET: 'OFFSET'; +ON: 'ON'; +ONLY: 'ONLY'; +OPEN: 'OPEN'; +OPTIMIZED: 'OPTIMIZED'; +OR: 'OR'; +ORDER: 'ORDER'; +OUTER: 'OUTER'; +OUTFILE: 'OUTFILE'; +OVER: 'OVER'; +OVERWRITE: 'OVERWRITE'; +PARAMETER: 'PARAMETER'; +PARSED: 'PARSED'; +PARTITION: 'PARTITION'; +PARTITIONS: 'PARTITIONS'; +PASSWORD: 'PASSWORD'; +PASSWORD_EXPIRE: 'PASSWORD_EXPIRE'; +PASSWORD_HISTORY: 'PASSWORD_HISTORY'; +PASSWORD_LOCK_TIME: 'PASSWORD_LOCK_TIME'; +PASSWORD_REUSE: 'PASSWORD_REUSE'; +PATH: 'PATH'; +PAUSE: 'PAUSE'; +PERCENT: 'PERCENT'; +PERIOD: 'PERIOD'; +PERMISSIVE: 'PERMISSIVE'; +PHYSICAL: 'PHYSICAL'; +PLAN: 'PLAN'; +PLUGIN: 'PLUGIN'; +PLUGINS: 'PLUGINS'; +POLICY: 'POLICY'; +PRECEDING: 'PRECEDING'; +PREPARE: 'PREPARE'; +PRIMARY: 'PRIMARY'; +PROC: 'PROC'; +PROCEDURE: 'PROCEDURE'; +PROCESSLIST: 'PROCESSLIST'; +PROFILE: 'PROFILE'; +PROPERTIES: 'PROPERTIES'; +PROPERTY: 'PROPERTY'; +QUANTILE_STATE: 'QUANTILE_STATE'; +QUANTILE_UNION: 'QUANTILE_UNION'; +QUERY: 'QUERY'; +QUOTA: 'QUOTA'; +RANDOM: 'RANDOM'; +RANGE: 'RANGE'; +READ: 'READ'; +REAL: 'REAL'; +REBALANCE: 'REBALANCE'; +RECOVER: 'RECOVER'; +RECYCLE: 'RECYCLE'; +REFRESH: 'REFRESH'; +REFERENCES: 'REFERENCES'; +REGEXP: 'REGEXP'; +RELEASE: 'RELEASE'; +RENAME: 'RENAME'; +REPAIR: 'REPAIR'; +REPEATABLE: 'REPEATABLE'; +REPLACE: 'REPLACE'; +REPLACE_IF_NOT_NULL: 'REPLACE_IF_NOT_NULL'; +REPLICA: 'REPLICA'; +REPOSITORIES: 'REPOSITORIES'; +REPOSITORY: 'REPOSITORY'; +RESOURCE: 'RESOURCE'; +RESOURCES: 'RESOURCES'; +RESTORE: 'RESTORE'; +RESTRICTIVE: 'RESTRICTIVE'; +RESUME: 'RESUME'; +RETURNS: 'RETURNS'; +REVOKE: 'REVOKE'; +REWRITTEN: 'REWRITTEN'; +RIGHT: 'RIGHT'; +RLIKE: 'RLIKE'; +ROLE: 'ROLE'; +ROLES: 'ROLES'; +ROLLBACK: 'ROLLBACK'; +ROLLUP: 'ROLLUP'; +ROUTINE: 'ROUTINE'; +ROW: 'ROW'; +ROWS: 'ROWS'; +S3: 'S3'; +SAMPLE: 'SAMPLE'; +SCHEDULE: 'SCHEDULE'; +SCHEDULER: 'SCHEDULER'; +SCHEMA: 'SCHEMA'; +SCHEMAS: 'SCHEMAS'; +SECOND: 'SECOND'; +SELECT: 'SELECT'; +SEMI: 'SEMI'; +SERIALIZABLE: 'SERIALIZABLE'; +SESSION: 'SESSION'; +SET: 'SET'; +SETS: 'SETS'; +SHAPE: 'SHAPE'; +SHOW: 'SHOW'; +SIGNED: 'SIGNED'; +SKEW: 'SKEW'; +SMALLINT: 'SMALLINT'; +SNAPSHOT: 'SNAPSHOT'; +SONAME: 'SONAME'; +SPLIT: 'SPLIT'; +SQL_BLOCK_RULE: 'SQL_BLOCK_RULE'; +START: 'START'; +STARTS: 'STARTS'; +STATS: 'STATS'; +STATUS: 'STATUS'; +STOP: 'STOP'; +STORAGE: 'STORAGE'; +STREAM: 'STREAM'; +STREAMING: 'STREAMING'; +STRING: 'STRING'; +STRUCT: 'STRUCT'; +SUBDATE: 'SUBDATE'; +SUM: 'SUM'; +SUPERUSER: 'SUPERUSER'; +SWITCH: 'SWITCH'; +SYNC: 'SYNC'; +SYSTEM: 'SYSTEM'; +TABLE: 'TABLE'; +TABLES: 'TABLES'; +TABLESAMPLE: 'TABLESAMPLE'; +TABLET: 'TABLET'; +TABLETS: 'TABLETS'; +TASK: 'TASK'; +TASKS: 'TASKS'; +TEMPORARY: 'TEMPORARY'; +TERMINATED: 'TERMINATED'; +TEXT: 'TEXT'; +THAN: 'THAN'; +THEN: 'THEN'; +TIME: 'TIME'; +TIMESTAMP: 'TIMESTAMP'; +TIMESTAMPADD: 'TIMESTAMPADD'; +TIMESTAMPDIFF: 'TIMESTAMPDIFF'; +TINYINT: 'TINYINT'; +TO: 'TO'; +TRANSACTION: 'TRANSACTION'; +TRASH: 'TRASH'; +TREE: 'TREE'; +TRIGGERS: 'TRIGGERS'; +TRIM: 'TRIM'; +TRUE: 'TRUE'; +TRUNCATE: 'TRUNCATE'; +TYPE: 'TYPE'; +TYPECAST: 'TYPE_CAST'; +TYPES: 'TYPES'; +UNBOUNDED: 'UNBOUNDED'; +UNCOMMITTED: 'UNCOMMITTED'; +UNINSTALL: 'UNINSTALL'; +UNION: 'UNION'; +UNIQUE: 'UNIQUE'; +UNLOCK: 'UNLOCK'; +UNSIGNED: 'UNSIGNED'; +UPDATE: 'UPDATE'; +USE: 'USE'; +USER: 'USER'; +USING: 'USING'; +VALUE: 'VALUE'; +VALUES: 'VALUES'; +VARCHAR: 'VARCHAR'; +VARIABLES: 'VARIABLES'; +VERBOSE: 'VERBOSE'; +VERSION: 'VERSION'; +VIEW: 'VIEW'; +WARNINGS: 'WARNINGS'; +WEEK: 'WEEK'; +WHEN: 'WHEN'; +WHERE: 'WHERE'; +WHITELIST: 'WHITELIST'; +WITH: 'WITH'; +WORK: 'WORK'; +WORKLOAD: 'WORKLOAD'; +WRITE: 'WRITE'; +YEAR: 'YEAR'; +//--DORIS-KEYWORD-LIST-END +//============================ +// End of the keywords list +//============================ + +EQ : '=' | '=='; +NSEQ: '<=>'; +NEQ : '<>' | '!='; +LT : '<'; +LTE : '<=' | '!>'; +GT : '>'; +GTE : '>=' | '!<'; + +PLUS: '+'; +SUBTRACT: '-'; +ASTERISK: '*'; +SLASH: '/'; +MOD: '%'; +TILDE: '~'; +AMPERSAND: '&'; +LOGICALAND: '&&'; +LOGICALNOT: '!'; +PIPE: '|'; +DOUBLEPIPES: '||'; +HAT: '^'; +COLON: ':'; +ARROW: '->'; +HINT_START: '/*+'; +HINT_END: '*/'; +ATSIGN: '@'; +DOUBLEATSIGN: '@@'; + +STRING_LITERAL + : '\'' ('\\'. | '\'\'' | ~('\'' | '\\'))* '\'' + | '"' ( '\\'. | '""' | ~('"'| '\\') )* '"' + | 'R\'' (~'\'')* '\'' + | 'R"'(~'"')* '"' + ; + +LEADING_STRING + : LEFT_BRACE + | RIGHT_BRACE + | LEFT_BRACKET + | RIGHT_BRACKET + ; + +BIGINT_LITERAL + : DIGIT+ 'L' + ; + +SMALLINT_LITERAL + : DIGIT+ 'S' + ; + +TINYINT_LITERAL + : DIGIT+ 'Y' + ; + +INTEGER_VALUE + : DIGIT+ + ; + +EXPONENT_VALUE + : DIGIT+ EXPONENT + | DECIMAL_DIGITS EXPONENT {isValidDecimal()}? + ; + +DECIMAL_VALUE + : DECIMAL_DIGITS {isValidDecimal()}? + ; + +BIGDECIMAL_LITERAL + : DIGIT+ EXPONENT? 'BD' + | DECIMAL_DIGITS EXPONENT? 'BD' {isValidDecimal()}? + ; + +IDENTIFIER + : (LETTER | DIGIT | '_')+ + ; + +BACKQUOTED_IDENTIFIER + : '`' ( ~'`' | '``' )* '`' + ; + +fragment DECIMAL_DIGITS + : DIGIT+ '.' DIGIT* + | '.' DIGIT+ + ; + +fragment EXPONENT + : 'E' [+-]? DIGIT+ + ; + +fragment DIGIT + : [0-9] + ; + +fragment LETTER + : [a-zA-Z$_] // these are the "java letters" below 0x7F + | ~[\u0000-\u007F\uD800-\uDBFF] // covers all characters above 0x7F which are not a surrogate + | [\uD800-\uDBFF] [\uDC00-\uDFFF] // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF + ; + +SIMPLE_COMMENT + : '--' ('\\\n' | ~[\r\n])* '\r'? '\n'? -> channel(HIDDEN) + ; + +BRACKETED_COMMENT + : '/*' {!isHint()}? ( BRACKETED_COMMENT | . )*? ('*/' | {markUnclosedComment();} EOF) -> channel(HIDDEN) + ; + +WS + : [ \r\n\t]+ -> channel(HIDDEN) + ; + +// Catch-all for anything we can't recognize. +// We use this to be able to ignore and recover all the text +// when splitting statements with DelimiterLexer +UNRECOGNIZED + : . + ; diff --git a/fastmodel-transform/fastmodel-transform-doris/src/main/antlr4/com/aliyun/fastmodel/transform/doris/parser/DorisParser.g4 b/fastmodel-transform/fastmodel-transform-doris/src/main/antlr4/com/aliyun/fastmodel/transform/doris/parser/DorisParser.g4 new file mode 100644 index 0000000..7159350 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/main/antlr4/com/aliyun/fastmodel/transform/doris/parser/DorisParser.g4 @@ -0,0 +1,1167 @@ +// 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. + +// Copied from Apache Spark and modified for Apache Doris + +parser grammar DorisParser; + +options { tokenVocab = DorisLexer; } + +@members { + public boolean doris_legacy_SQL_syntax = true; +} + +multiStatements + : (statement SEMICOLON*)+ EOF + ; + +singleStatement + : statement SEMICOLON* EOF + ; + +statement + : explain? query outFileClause? #statementDefault + | CREATE ROW POLICY (IF NOT EXISTS)? name=identifier + ON table=multipartIdentifier + AS type=(RESTRICTIVE | PERMISSIVE) + TO (user=userIdentify | ROLE roleName=identifier) + USING LEFT_PAREN booleanExpression RIGHT_PAREN #createRowPolicy + | CREATE (EXTERNAL)? TABLE (IF NOT EXISTS)? name=multipartIdentifier + ((ctasCols=identifierList)? | (LEFT_PAREN columnDefs (COMMA indexDefs)? COMMA? RIGHT_PAREN)) + (ENGINE EQ engine=identifier)? + ((AGGREGATE | UNIQUE | DUPLICATE) KEY keys=identifierList (CLUSTER BY clusterKeys=identifierList)?)? + (COMMENT STRING_LITERAL)? + ((autoPartition=AUTO)? PARTITION BY (RANGE | LIST) (partitionKeys=identifierList | partitionExpr=functionCallExpression) + LEFT_PAREN (partitions=partitionsDef)? RIGHT_PAREN)? + (DISTRIBUTED BY (HASH hashKeys=identifierList | RANDOM) (BUCKETS (INTEGER_VALUE | autoBucket=AUTO))?)? + (ROLLUP LEFT_PAREN rollupDefs RIGHT_PAREN)? + properties=propertyClause? + (BROKER extProperties=propertyClause)? + (AS query)? #createTable + | explain? INSERT (INTO | OVERWRITE TABLE) + (tableName=multipartIdentifier | DORIS_INTERNAL_TABLE_ID LEFT_PAREN tableId=INTEGER_VALUE RIGHT_PAREN) + partitionSpec? // partition define + (WITH LABEL labelName=identifier)? cols=identifierList? // label and columns define + (LEFT_BRACKET hints=identifierSeq RIGHT_BRACKET)? // hint define + query #insertTable + | explain? cte? UPDATE tableName=multipartIdentifier tableAlias + SET updateAssignmentSeq + fromClause? + whereClause #update + | explain? cte? DELETE FROM tableName=multipartIdentifier + partitionSpec? tableAlias + (USING relation (COMMA relation)*)? + whereClause #delete + | LOAD LABEL lableName=identifier + LEFT_PAREN dataDescs+=dataDesc (COMMA dataDescs+=dataDesc)* RIGHT_PAREN + (withRemoteStorageSystem)? + (PROPERTIES LEFT_PAREN properties=propertyItemList RIGHT_PAREN)? + (commentSpec)? #load + | LOAD mysqlDataDesc + (PROPERTIES LEFT_PAREN properties=propertyItemList RIGHT_PAREN)? + (commentSpec)? #mysqlLoad + | EXPORT TABLE tableName=multipartIdentifier + (PARTITION partition=identifierList)? + (whereClause)? + TO filePath=STRING_LITERAL + (propertyClause)? + (withRemoteStorageSystem)? #export + | CREATE MATERIALIZED VIEW (IF NOT EXISTS)? mvName=multipartIdentifier + (LEFT_PAREN cols=simpleColumnDefs RIGHT_PAREN)? buildMode? + (REFRESH refreshMethod? refreshTrigger?)? + (KEY keys=identifierList)? + (COMMENT STRING_LITERAL)? + (PARTITION BY LEFT_PAREN partitionKey = identifier RIGHT_PAREN)? + (DISTRIBUTED BY (HASH hashKeys=identifierList | RANDOM) (BUCKETS (INTEGER_VALUE | AUTO))?)? + propertyClause? + AS query #createMTMV + | REFRESH MATERIALIZED VIEW mvName=multipartIdentifier (partitionSpec | COMPLETE)? #refreshMTMV + | ALTER MATERIALIZED VIEW mvName=multipartIdentifier ((RENAME newName=identifier) + | (REFRESH (refreshMethod | refreshTrigger | refreshMethod refreshTrigger)) + | (SET LEFT_PAREN fileProperties=propertyItemList RIGHT_PAREN)) #alterMTMV + | DROP MATERIALIZED VIEW (IF EXISTS)? mvName=multipartIdentifier #dropMTMV + | PAUSE MATERIALIZED VIEW JOB ON mvName=multipartIdentifier #pauseMTMV + | RESUME MATERIALIZED VIEW JOB ON mvName=multipartIdentifier #resumeMTMV + | CANCEL MATERIALIZED VIEW TASK taskId=INTEGER_VALUE ON mvName=multipartIdentifier #cancelMTMVTask + | ALTER TABLE table=relation + ADD CONSTRAINT constraintName=errorCapturingIdentifier + constraint #addConstraint + | ALTER TABLE table=relation + DROP CONSTRAINT constraintName=errorCapturingIdentifier #dropConstraint + | CALL functionName=identifier LEFT_PAREN (expression (COMMA expression)*)? RIGHT_PAREN #callProcedure + ; + +constraint + : PRIMARY KEY slots=identifierList + | UNIQUE slots=identifierList + | FOREIGN KEY slots=identifierList + REFERENCES referenceTable=multipartIdentifier + referencedSlots=identifierList + ; + +partitionSpec + : TEMPORARY? (PARTITION | PARTITIONS) partitions=identifierList + | TEMPORARY? PARTITION partition=errorCapturingIdentifier + // TODO: support analyze external table partition spec https://github.com/apache/doris/pull/24154 + // | PARTITIONS LEFT_PAREN ASTERISK RIGHT_PAREN + // | PARTITIONS WITH RECENT + ; + +dataDesc + : ((WITH)? mergeType)? DATA INFILE LEFT_PAREN filePaths+=STRING_LITERAL (COMMA filePath+=STRING_LITERAL)* RIGHT_PAREN + INTO TABLE tableName=multipartIdentifier + (PARTITION partition=identifierList)? + (COLUMNS TERMINATED BY comma=STRING_LITERAL)? + (LINES TERMINATED BY separator=STRING_LITERAL)? + (FORMAT AS format=identifierOrStringLiteral)? + (columns=identifierList)? + (columnsFromPath=colFromPath)? + (columnMapping=colMappingList)? + (preFilter=preFilterClause)? + (where=whereClause)? + (deleteOn=deleteOnClause)? + (sequenceColumn=sequenceColClause)? + (propertyClause)? + | ((WITH)? mergeType)? DATA FROM TABLE tableName=multipartIdentifier + INTO TABLE tableName=multipartIdentifier + (PARTITION partition=identifierList)? + (columnMapping=colMappingList)? + (where=whereClause)? + (deleteOn=deleteOnClause)? + (propertyClause)? + ; + +// -----------------Command accessories----------------- +buildMode + : BUILD (IMMEDIATE | DEFERRED) + ; + +refreshTrigger + : ON MANUAL + | ON SCHEDULE refreshSchedule + ; + +refreshSchedule + : EVERY INTEGER_VALUE refreshUnit = identifier (STARTS STRING_LITERAL)? + ; + +refreshMethod + : COMPLETE | AUTO + ; + +identifierOrStringLiteral + : identifier + | STRING_LITERAL + ; + +identifierOrText + : errorCapturingIdentifier + | STRING_LITERAL + | LEADING_STRING + ; + +userIdentify + : user=identifierOrText (AT (host=identifierOrText | LEFT_PAREN host=identifierOrText RIGHT_PAREN))? + ; + + +explain + : (EXPLAIN planType? | DESC | DESCRIBE) + level=(VERBOSE | TREE | GRAPH | PLAN)? + ; + +planType + : PARSED + | ANALYZED + | REWRITTEN | LOGICAL // same type + | OPTIMIZED | PHYSICAL // same type + | SHAPE + | MEMO + | ALL // default type + ; + +mergeType + : APPEND + | DELETE + | MERGE + ; + +preFilterClause + : PRECEDING FILTER expression + ; + +deleteOnClause + : DELETE ON expression + ; + +sequenceColClause + : ORDER BY identifier + ; + +colFromPath + : COLUMNS FROM PATH AS identifierList + ; + +colMappingList + : SET LEFT_PAREN mappingSet+=mappingExpr (COMMA mappingSet+=mappingExpr)* RIGHT_PAREN + ; + +mappingExpr + : (mappingCol=identifier EQ expression) + ; + +withRemoteStorageSystem + : resourceDesc + | WITH S3 LEFT_PAREN + brokerProperties=propertyItemList + RIGHT_PAREN + | WITH HDFS LEFT_PAREN + brokerProperties=propertyItemList + RIGHT_PAREN + | WITH LOCAL LEFT_PAREN + brokerProperties=propertyItemList + RIGHT_PAREN + | WITH BROKER brokerName=identifierOrText + (LEFT_PAREN + brokerProperties=propertyItemList + RIGHT_PAREN)? + ; + +resourceDesc + : WITH RESOURCE resourceName=identifierOrText (LEFT_PAREN propertyItemList RIGHT_PAREN)? + ; + +mysqlDataDesc + : DATA (LOCAL booleanValue)? + INFILE filePath=STRING_LITERAL + INTO TABLE tableName=multipartIdentifier + (PARTITION partition=identifierList)? + (COLUMNS TERMINATED BY comma=STRING_LITERAL)? + (LINES TERMINATED BY separator=STRING_LITERAL)? + (skipLines)? + (columns=identifierList)? + (colMappingList)? + (propertyClause)? + ; + +skipLines : IGNORE lines=INTEGER_VALUE LINES | IGNORE lines=INTEGER_VALUE ROWS ; + +// -----------------Query----------------- +// add queryOrganization for parse (q1) union (q2) union (q3) order by keys, otherwise 'order' will be recognized to be +// identifier. + +outFileClause + : INTO OUTFILE filePath=constant + (FORMAT AS format=identifier)? + (propertyClause)? + ; + +query + : cte? queryTerm queryOrganization + ; + +queryTerm + : queryPrimary #queryTermDefault + | left=queryTerm operator=(UNION | EXCEPT | INTERSECT) + setQuantifier? right=queryTerm #setOperation + ; + +setQuantifier + : DISTINCT + | ALL + ; + +queryPrimary + : querySpecification #queryPrimaryDefault + | LEFT_PAREN query RIGHT_PAREN #subquery + | inlineTable #valuesTable + ; + +querySpecification + : selectClause + fromClause? + whereClause? + aggClause? + havingClause? + {doris_legacy_SQL_syntax}? queryOrganization #regularQuerySpecification + ; + +cte + : WITH aliasQuery (COMMA aliasQuery)* + ; + +aliasQuery + : identifier columnAliases? AS LEFT_PAREN query RIGHT_PAREN + ; + +columnAliases + : LEFT_PAREN identifier (COMMA identifier)* RIGHT_PAREN + ; + +selectClause + : SELECT selectHint? DISTINCT? selectColumnClause + ; + +selectColumnClause + : namedExpressionSeq + | ASTERISK EXCEPT LEFT_PAREN namedExpressionSeq RIGHT_PAREN + ; + +whereClause + : WHERE booleanExpression + ; + +fromClause + : FROM relation (COMMA relation)* + ; + +relation + : relationPrimary joinRelation* + ; + +joinRelation + : (joinType) JOIN distributeType? right=relationPrimary joinCriteria? + ; + +// Just like `opt_plan_hints` in legacy CUP parser. +distributeType + : LEFT_BRACKET identifier RIGHT_BRACKET #bracketDistributeType + | HINT_START identifier HINT_END #commentDistributeType + ; + +relationHint + : LEFT_BRACKET identifier (COMMA identifier)* RIGHT_BRACKET #bracketRelationHint + | HINT_START identifier (COMMA identifier)* HINT_END #commentRelationHint + ; + +aggClause + : GROUP BY groupingElement? + ; + +groupingElement + : ROLLUP LEFT_PAREN (expression (COMMA expression)*)? RIGHT_PAREN + | CUBE LEFT_PAREN (expression (COMMA expression)*)? RIGHT_PAREN + | GROUPING SETS LEFT_PAREN groupingSet (COMMA groupingSet)* RIGHT_PAREN + | expression (COMMA expression)* + ; + +groupingSet + : LEFT_PAREN (expression (COMMA expression)*)? RIGHT_PAREN + ; + +havingClause + : HAVING booleanExpression + ; + +selectHint: HINT_START hintStatements+=hintStatement (COMMA? hintStatements+=hintStatement)* HINT_END; + +hintStatement + : hintName=identifier (LEFT_PAREN parameters+=hintAssignment (COMMA? parameters+=hintAssignment)* RIGHT_PAREN)? + ; + +hintAssignment + : key=identifierOrText (EQ (constantValue=constant | identifierValue=identifier))? + ; + +updateAssignment + : col=multipartIdentifier EQ (expression | DEFAULT) + ; + +updateAssignmentSeq + : assignments+=updateAssignment (COMMA assignments+=updateAssignment)* + ; + +lateralView + : LATERAL VIEW functionName=identifier LEFT_PAREN (expression (COMMA expression)*)? RIGHT_PAREN + tableName=identifier AS columnName=identifier + ; + +queryOrganization + : sortClause? limitClause? + ; + +sortClause + : ORDER BY sortItem (COMMA sortItem)* + ; + +sortItem + : expression ordering = (ASC | DESC)? (NULLS (FIRST | LAST))? + ; + +limitClause + : (LIMIT limit=INTEGER_VALUE) + | (LIMIT limit=INTEGER_VALUE OFFSET offset=INTEGER_VALUE) + | (LIMIT offset=INTEGER_VALUE COMMA limit=INTEGER_VALUE) + ; + +partitionClause + : PARTITION BY expression (COMMA expression)* + ; + +joinType + : INNER? + | CROSS + | LEFT OUTER? + | RIGHT OUTER? + | FULL OUTER? + | LEFT SEMI + | RIGHT SEMI + | LEFT ANTI + | RIGHT ANTI + ; + +joinCriteria + : ON booleanExpression + | USING identifierList + ; + +identifierList + : LEFT_PAREN identifierSeq RIGHT_PAREN + ; + +identifierSeq + : ident+=errorCapturingIdentifier (COMMA ident+=errorCapturingIdentifier)* + ; + +relationPrimary + : multipartIdentifier specifiedPartition? + tabletList? tableAlias sample? relationHint? lateralView* #tableName + | LEFT_PAREN query RIGHT_PAREN tableAlias lateralView* #aliasedQuery + | tvfName=identifier LEFT_PAREN + (properties=propertyItemList)? + RIGHT_PAREN tableAlias #tableValuedFunction + ; + +propertyClause + : PROPERTIES LEFT_PAREN fileProperties=propertyItemList RIGHT_PAREN + ; + +propertyItemList + : properties+=propertyItem (COMMA properties+=propertyItem)* + ; + +propertyItem + : key=propertyKey EQ value=propertyValue + ; + +propertyKey : identifier | constant ; + +propertyValue : identifier | constant ; + +tableAlias + : (AS? strictIdentifier identifierList?)? + ; + +multipartIdentifier + : parts+=errorCapturingIdentifier (DOT parts+=errorCapturingIdentifier)* + ; + +// ----------------Create Table Fields---------- +simpleColumnDefs + : cols+=simpleColumnDef (COMMA cols+=simpleColumnDef)* + ; + +simpleColumnDef + : colName=identifier (COMMENT comment=STRING_LITERAL)? + ; + +columnDefs + : cols+=columnDef (COMMA cols+=columnDef)* + ; + +columnDef + : colName=identifier type=dataType + KEY? (aggType=aggTypeDef)? ((NOT NULL) | NULL)? (AUTO_INCREMENT)? + (DEFAULT (nullValue=NULL | INTEGER_VALUE | stringValue=STRING_LITERAL + | CURRENT_TIMESTAMP (LEFT_PAREN defaultValuePrecision=number RIGHT_PAREN)?))? + (ON UPDATE CURRENT_TIMESTAMP (LEFT_PAREN onUpdateValuePrecision=number RIGHT_PAREN)?)? + (COMMENT comment=STRING_LITERAL)? + ; + +indexDefs + : indexes+=indexDef (COMMA indexes+=indexDef)* + ; + +indexDef + : INDEX indexName=identifier cols=identifierList (USING indexType=(BITMAP | INVERTED | NGRAM_BF))? (PROPERTIES LEFT_PAREN properties=propertyItemList RIGHT_PAREN)? (COMMENT comment=STRING_LITERAL)? + ; + +partitionsDef + : partitions+=partitionDef (COMMA partitions+=partitionDef)* + ; + +partitionDef + : (lessThanPartitionDef | fixedPartitionDef | stepPartitionDef | inPartitionDef) (LEFT_PAREN partitionProperties=propertyItemList RIGHT_PAREN)? + ; + +lessThanPartitionDef + : PARTITION (IF NOT EXISTS)? partitionName=identifier VALUES LESS THAN (MAXVALUE | constantSeq) + ; + +fixedPartitionDef + : PARTITION (IF NOT EXISTS)? partitionName=identifier VALUES LEFT_BRACKET lower=constantSeq COMMA upper=constantSeq RIGHT_PAREN + ; + +stepPartitionDef + : FROM from=constantSeq TO to=constantSeq INTERVAL unitsAmount=INTEGER_VALUE unit=datetimeUnit? + ; + +inPartitionDef + : PARTITION (IF NOT EXISTS)? partitionName=identifier (VALUES IN ((LEFT_PAREN constantSeqs+=constantSeq + (COMMA constantSeqs+=constantSeq)* RIGHT_PAREN) | constants=constantSeq))? + ; + +constantSeq + : LEFT_PAREN values+=partitionValueDef (COMMA values+=partitionValueDef)* RIGHT_PAREN + ; + +partitionValueDef + : INTEGER_VALUE | STRING_LITERAL | MAXVALUE + ; + +rollupDefs + : rollups+=rollupDef (COMMA rollups+=rollupDef)* + ; + +rollupDef + : rollupName=identifier rollupCols=identifierList (DUPLICATE KEY dupKeys=identifierList)? properties=propertyClause? + ; + +aggTypeDef + : MAX | MIN | SUM | REPLACE | REPLACE_IF_NOT_NULL | HLL_UNION | BITMAP_UNION | QUANTILE_UNION + ; + +tabletList + : TABLET LEFT_PAREN tabletIdList+=INTEGER_VALUE (COMMA tabletIdList+=INTEGER_VALUE)* RIGHT_PAREN + ; + + +inlineTable + : VALUES rowConstructor (COMMA rowConstructor)* + ; + +// -----------------Expression----------------- +namedExpression + : expression (AS? (identifierOrText))? + ; + +namedExpressionSeq + : namedExpression (COMMA namedExpression)* + ; + +expression + : booleanExpression + | lambdaExpression + ; + +lambdaExpression + : args+=errorCapturingIdentifier ARROW body=booleanExpression + | LEFT_PAREN + args+=errorCapturingIdentifier (COMMA args+=errorCapturingIdentifier)+ + RIGHT_PAREN + ARROW body=booleanExpression + ; + +booleanExpression + : (LOGICALNOT | NOT) booleanExpression #logicalNot + | EXISTS LEFT_PAREN query RIGHT_PAREN #exist + | (ISNULL | IS_NULL_PRED) LEFT_PAREN valueExpression RIGHT_PAREN #isnull + | IS_NOT_NULL_PRED LEFT_PAREN valueExpression RIGHT_PAREN #is_not_null_pred + | valueExpression predicate? #predicated + | left=booleanExpression operator=(AND | LOGICALAND) right=booleanExpression #logicalBinary + | left=booleanExpression operator=OR right=booleanExpression #logicalBinary + | left=booleanExpression operator=DOUBLEPIPES right=booleanExpression #doublePipes + ; + +rowConstructor + : LEFT_PAREN (rowConstructorItem (COMMA rowConstructorItem)*)? RIGHT_PAREN + ; + +rowConstructorItem + : namedExpression | DEFAULT + ; + +predicate + : NOT? kind=BETWEEN lower=valueExpression AND upper=valueExpression + | NOT? kind=(LIKE | REGEXP | RLIKE) pattern=valueExpression + | NOT? kind=(MATCH | MATCH_ANY | MATCH_ALL | MATCH_PHRASE | MATCH_PHRASE_PREFIX | MATCH_REGEXP) pattern=valueExpression + | NOT? kind=IN LEFT_PAREN query RIGHT_PAREN + | NOT? kind=IN LEFT_PAREN expression (COMMA expression)* RIGHT_PAREN + | IS NOT? kind=NULL + ; + +valueExpression + : primaryExpression #valueExpressionDefault + | operator=(SUBTRACT | PLUS | TILDE) valueExpression #arithmeticUnary + | left=valueExpression operator=(ASTERISK | SLASH | MOD) right=valueExpression #arithmeticBinary + | left=valueExpression operator=(PLUS | SUBTRACT | DIV | HAT | PIPE | AMPERSAND) + right=valueExpression #arithmeticBinary + | left=valueExpression comparisonOperator right=valueExpression #comparison + | operator=(BITAND | BITOR | BITXOR) LEFT_PAREN left = valueExpression + COMMA right = valueExpression RIGHT_PAREN #bitOperation + ; + +datetimeUnit + : YEAR | MONTH + | WEEK | DAY + | HOUR | MINUTE | SECOND + ; + +primaryExpression + : name=(TIMESTAMPDIFF | DATEDIFF) + LEFT_PAREN + unit=datetimeUnit COMMA + startTimestamp=valueExpression COMMA + endTimestamp=valueExpression + RIGHT_PAREN #timestampdiff + | name=(TIMESTAMPADD | DATEADD) + LEFT_PAREN + unit=datetimeUnit COMMA + startTimestamp=valueExpression COMMA + endTimestamp=valueExpression + RIGHT_PAREN #timestampadd + | name =(ADDDATE | DAYS_ADD | DATE_ADD) + LEFT_PAREN + timestamp=valueExpression COMMA + (INTERVAL unitsAmount=valueExpression unit=datetimeUnit + | unitsAmount=valueExpression) + RIGHT_PAREN #date_add + | name=(SUBDATE | DAYS_SUB | DATE_SUB) + LEFT_PAREN + timestamp=valueExpression COMMA + (INTERVAL unitsAmount=valueExpression unit=datetimeUnit + | unitsAmount=valueExpression) + RIGHT_PAREN #date_sub + | name=DATE_FLOOR + LEFT_PAREN + timestamp=valueExpression COMMA + (INTERVAL unitsAmount=valueExpression unit=datetimeUnit + | unitsAmount=valueExpression) + RIGHT_PAREN #dateFloor + | name=DATE_CEIL + LEFT_PAREN + timestamp=valueExpression COMMA + (INTERVAL unitsAmount=valueExpression unit=datetimeUnit + | unitsAmount=valueExpression) + RIGHT_PAREN #dateCeil + | CASE whenClause+ (ELSE elseExpression=expression)? END #searchedCase + | CASE value=expression whenClause+ (ELSE elseExpression=expression)? END #simpleCase + | name=CAST LEFT_PAREN expression AS dataType RIGHT_PAREN #cast + | constant #constantDefault + | interval #intervalLiteral + | ASTERISK #star + | qualifiedName DOT ASTERISK #star + | CHAR LEFT_PAREN + arguments+=expression (COMMA arguments+=expression)* + (USING charSet=identifierOrText)? + RIGHT_PAREN #charFunction + | CONVERT LEFT_PAREN argument=expression USING charSet=identifierOrText RIGHT_PAREN #convertCharSet + | CONVERT LEFT_PAREN argument=expression COMMA type=dataType RIGHT_PAREN #convertType + | functionCallExpression #functionCall + | value=primaryExpression LEFT_BRACKET index=valueExpression RIGHT_BRACKET #elementAt + | value=primaryExpression LEFT_BRACKET begin=valueExpression + COLON (end=valueExpression)? RIGHT_BRACKET #arraySlice + | LEFT_PAREN query RIGHT_PAREN #subqueryExpression + | ATSIGN identifierOrText #userVariable + | DOUBLEATSIGN (kind=(GLOBAL | SESSION) DOT)? identifier #systemVariable + | BINARY? identifier #columnReference + | base=primaryExpression DOT fieldName=identifier #dereference + | LEFT_PAREN expression RIGHT_PAREN #parenthesizedExpression + | KEY (dbName=identifier DOT)? keyName=identifier #encryptKey + | EXTRACT LEFT_PAREN field=identifier FROM (DATE | TIMESTAMP)? + source=valueExpression RIGHT_PAREN #extract + | primaryExpression COLLATE (identifier | STRING_LITERAL | DEFAULT) #collate + ; + +functionCallExpression + : functionIdentifier + LEFT_PAREN ( + (DISTINCT|ALL)? + arguments+=expression (COMMA arguments+=expression)* + (ORDER BY sortItem (COMMA sortItem)*)? + )? RIGHT_PAREN + (OVER windowSpec)? + ; + +functionIdentifier + : (dbName=identifier DOT)? functionNameIdentifier + ; + +functionNameIdentifier + : identifier + | ADD + | CONNECTION_ID + | CURRENT_CATALOG + | CURRENT_USER + | DATABASE + | IF + | LEFT + | LIKE + | PASSWORD + | REGEXP + | RIGHT + | SCHEMA + | TRIM + | USER + ; + +windowSpec + // todo: name for windowRef; we haven't support it + // : name=identifier + // | LEFT_PAREN name=identifier RIGHT_PAREN + : LEFT_PAREN + partitionClause? + sortClause? + windowFrame? + RIGHT_PAREN + ; + +windowFrame + : frameUnits start=frameBoundary + | frameUnits BETWEEN start=frameBoundary AND end=frameBoundary + ; + +frameUnits + : ROWS + | RANGE + ; + +frameBoundary + : UNBOUNDED boundType=(PRECEDING | FOLLOWING) + | boundType=CURRENT ROW + | expression boundType=(PRECEDING | FOLLOWING) + ; + +qualifiedName + : identifier (DOT identifier)* + ; + +specifiedPartition + : TEMPORARY? PARTITION (identifier | identifierList) + | TEMPORARY? PARTITIONS identifierList + ; + +constant + : NULL #nullLiteral + | type=(DATE | DATEV1 | DATEV2 | TIMESTAMP) STRING_LITERAL #typeConstructor + | number #numericLiteral + | booleanValue #booleanLiteral + | BINARY? STRING_LITERAL #stringLiteral + | LEFT_BRACKET (items+=constant)? (COMMA items+=constant)* RIGHT_BRACKET #arrayLiteral + | LEFT_BRACE (items+=constant COLON items+=constant)? + (COMMA items+=constant COLON items+=constant)* RIGHT_BRACE #mapLiteral + | LEFT_BRACE items+=constant (COMMA items+=constant)* RIGHT_BRACE #structLiteral + ; + +comparisonOperator + : EQ | NEQ | LT | LTE | GT | GTE | NSEQ + ; + +booleanValue + : TRUE | FALSE + ; + +whenClause + : WHEN condition=expression THEN result=expression + ; + +interval + : INTERVAL value=expression unit=unitIdentifier + ; + +unitIdentifier + : YEAR | MONTH | WEEK | DAY | HOUR | MINUTE | SECOND + ; + +dataType + : complex=ARRAY LT dataType GT #complexDataType + | complex=MAP LT dataType COMMA dataType GT #complexDataType + | complex=STRUCT LT complexColTypeList GT #complexDataType + | primitiveColType (LEFT_PAREN (INTEGER_VALUE | ASTERISK) + (COMMA INTEGER_VALUE)* RIGHT_PAREN)? #primitiveDataType + ; + +primitiveColType: + | type=TINYINT + | type=SMALLINT + | (SIGNED | UNSIGNED)? type=(INT | INTEGER) + | type=BIGINT + | type=LARGEINT + | type=BOOLEAN + | type=FLOAT + | type=DOUBLE + | type=DATE + | type=DATETIME + | type=TIME + | type=DATEV2 + | type=DATETIMEV2 + | type=DATEV1 + | type=DATETIMEV1 + | type=BITMAP + | type=QUANTILE_STATE + | type=HLL + | type=AGG_STATE + | type=STRING + | type=JSON + | type=JSONB + | type=TEXT + | type=VARCHAR + | type=CHAR + | type=DECIMAL + | type=DECIMALV2 + | type=DECIMALV3 + | type=IPV4 + | type=IPV6 + | type=ALL + ; + +complexColTypeList + : complexColType (COMMA complexColType)* + ; + +complexColType + : identifier COLON dataType commentSpec? + ; + +commentSpec + : COMMENT STRING_LITERAL + ; + +sample + : TABLESAMPLE LEFT_PAREN sampleMethod? RIGHT_PAREN (REPEATABLE seed=INTEGER_VALUE)? + ; + +sampleMethod + : percentage=INTEGER_VALUE PERCENT #sampleByPercentile + | INTEGER_VALUE ROWS #sampleByRows + ; + +// this rule is used for explicitly capturing wrong identifiers such as test-table, which should actually be `test-table` +// replace identifier with errorCapturingIdentifier where the immediate follow symbol is not an expression, otherwise +// valid expressions such as "a-b" can be recognized as an identifier +errorCapturingIdentifier + : identifier errorCapturingIdentifierExtra + ; + +// extra left-factoring grammar +errorCapturingIdentifierExtra + : (SUBTRACT identifier)+ #errorIdent + | #realIdent + ; + +identifier + : strictIdentifier + ; + +strictIdentifier + : IDENTIFIER #unquotedIdentifier + | quotedIdentifier #quotedIdentifierAlternative + | nonReserved #unquotedIdentifier + ; + +quotedIdentifier + : BACKQUOTED_IDENTIFIER + ; + +number + : SUBTRACT? INTEGER_VALUE #integerLiteral + | SUBTRACT? (EXPONENT_VALUE | DECIMAL_VALUE) #decimalLiteral + ; + +// there are 1 kinds of keywords in Doris. +// - Non-reserved keywords: +// normal version of non-reserved keywords. +// The non-reserved keywords are listed in `nonReserved`. +// TODO: need to stay consistent with the legacy +nonReserved +//--DEFAULT-NON-RESERVED-START + : ADDDATE + | AFTER + | AGG_STATE + | AGGREGATE + | ALIAS + | ANALYZED + | ARRAY + | AT + | AUTHORS + | AUTO_INCREMENT + | BACKENDS + | BACKUP + | BEGIN + | BIN + | BITAND + | BITMAP + | BITMAP_UNION + | BITOR + | BITXOR + | BLOB + | BOOLEAN + | BRIEF + | BROKER + | BUCKETS + | BUILD + | BUILTIN + | CACHED + | CALL + | CATALOG + | CATALOGS + | CHAIN + | CHAR + | CHARSET + | CHECK + | CLUSTER + | CLUSTERS + | COLLATION + | COLUMNS + | COMMENT + | COMMIT + | COMMITTED + | COMPACT + | COMPLETE + | CONFIG + | CONNECTION + | CONNECTION_ID + | CONSISTENT + | CONVERT + | COPY + | COUNT + | CREATION + | CRON + | CURRENT_CATALOG + | CURRENT_TIMESTAMP + | DATA + | DATE + | DATE_ADD + | DATE_CEIL + | DATE_DIFF + | DATE_FLOOR + | DATE_SUB + | DATEADD + | DATEDIFF + | DATETIME + | DATETIMEV2 + | DATEV2 + | DATETIMEV1 + | DATEV1 + | DAY + | DAYS_ADD + | DAYS_SUB + | DECIMAL + | DECIMALV2 + | DECIMALV3 + | DEFERRED + | DEMAND + | DIAGNOSE + | DISTINCTPC + | DISTINCTPCSA + | DO + | DORIS_INTERNAL_TABLE_ID + | DYNAMIC + | ENABLE + | ENCRYPTKEY + | ENCRYPTKEYS + | END + | ENDS + | ENGINE + | ENGINES + | ERRORS + | EVENTS + | EVERY + | EXCLUDE + | EXPIRED + | EXTERNAL + | FAILED_LOGIN_ATTEMPTS + | FAST + | FEATURE + | FIELDS + | FILE + | FILTER + | FIRST + | FORMAT + | FREE + | FRONTENDS + | FUNCTION + | GLOBAL + | GRAPH + | GROUPING + | GROUPS + | HASH + | HDFS + | HELP + | HISTOGRAM + | HLL_UNION + | HOSTNAME + | HOUR + | HUB + | IDENTIFIED + | IGNORE + | IMMEDIATE + | INCREMENTAL + | INDEXES + | INVERTED + | IS_NOT_NULL_PRED + | IS_NULL_PRED + | ISNULL + | ISOLATION + | JOB + | JOBS + | JSON + | JSONB + | LABEL + | LAST + | LDAP + | LDAP_ADMIN_PASSWORD + | LEFT_BRACE + | LESS + | LEVEL + | LINES + | LINK + | LOCAL + | LOCATION + | LOCK + | LOGICAL + | MANUAL + | MAP + | MATERIALIZED + | MAX + | MEMO + | MERGE + | MIGRATE + | MIGRATIONS + | MIN + | MINUTE + | MODIFY + | MONTH + | MTMV + | NAME + | NAMES + | NEGATIVE + | NEVER + | NEXT + | NGRAM_BF + | NO + | NON_NULLABLE + | NULLS + | OF + | OFFSET + | ONLY + | OPEN + | OPTIMIZED + | PARAMETER + | PARSED + | PASSWORD + | PASSWORD_EXPIRE + | PASSWORD_HISTORY + | PASSWORD_LOCK_TIME + | PASSWORD_REUSE + | PARTITIONS + | PATH + | PAUSE + | PERCENT + | PERIOD + | PERMISSIVE + | PHYSICAL + | PLAN + | PLUGIN + | PLUGINS + | POLICY + | PROC + | PROCESSLIST + | PROFILE + | PROPERTIES + | PROPERTY + | QUANTILE_STATE + | QUANTILE_UNION + | QUERY + | QUOTA + | RANDOM + | RECOVER + | RECYCLE + | REFRESH + | REPEATABLE + | REPLACE + | REPLACE_IF_NOT_NULL + | REPOSITORIES + | REPOSITORY + | RESOURCE + | RESOURCES + | RESTORE + | RESTRICTIVE + | RESUME + | RETURNS + | REWRITTEN + | RIGHT_BRACE + | RLIKE + | ROLLBACK + | ROLLUP + | ROUTINE + | S3 + | SAMPLE + | SCHEDULE + | SCHEDULER + | SCHEMA + | SECOND + | SERIALIZABLE + | SESSION + | SHAPE + | SKEW + | SNAPSHOT + | SONAME + | SPLIT + | START + | STARTS + | STATS + | STATUS + | STOP + | STORAGE + | STREAM + | STREAMING + | STRING + | STRUCT + | SUBDATE + | SUM + | TABLES + | TASK + | TASKS + | TEMPORARY + | TEXT + | THAN + | TIME + | TIMESTAMP + | TIMESTAMPADD + | TIMESTAMPDIFF + | TRANSACTION + | TREE + | TRIGGERS + | TRUNCATE + | TYPE + | TYPES + | UNCOMMITTED + | UNLOCK + | USER + | VALUE + | VARCHAR + | VARIABLES + | VERBOSE + | VERSION + | VIEW + | WARNINGS + | WEEK + | WORK + | YEAR +//--DEFAULT-NON-RESERVED-END + ; diff --git a/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/DorisTransformer.java b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/DorisTransformer.java new file mode 100644 index 0000000..f7b79e1 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/DorisTransformer.java @@ -0,0 +1,69 @@ +package com.aliyun.fastmodel.transform.doris; + +import com.aliyun.fastmodel.core.tree.BaseStatement; +import com.aliyun.fastmodel.core.tree.Node; +import com.aliyun.fastmodel.transform.api.Transformer; +import com.aliyun.fastmodel.transform.api.builder.BuilderFactory; +import com.aliyun.fastmodel.transform.api.builder.StatementBuilder; +import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; +import com.aliyun.fastmodel.transform.api.client.dto.table.Table; +import com.aliyun.fastmodel.transform.api.client.dto.table.TableConfig; +import com.aliyun.fastmodel.transform.api.context.ReverseContext; +import com.aliyun.fastmodel.transform.api.context.TransformContext; +import com.aliyun.fastmodel.transform.api.dialect.Dialect; +import com.aliyun.fastmodel.transform.api.dialect.DialectMeta; +import com.aliyun.fastmodel.transform.api.dialect.DialectName; +import com.aliyun.fastmodel.transform.api.dialect.DialectName.Constants; +import com.aliyun.fastmodel.transform.api.dialect.DialectNode; +import com.aliyun.fastmodel.transform.api.dialect.IVersion; +import com.aliyun.fastmodel.transform.doris.client.DorisClientConverter; +import com.aliyun.fastmodel.transform.doris.context.DorisContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisLanguageParser; +import com.google.auto.service.AutoService; + +/** + * doris transformer + * + * @author panguanjing + * @date 2024/1/20 + */ +@AutoService(Transformer.class) +@Dialect(value = Constants.DORIS) +public class DorisTransformer implements Transformer { + + private final DorisLanguageParser dorisLanguageParser = new DorisLanguageParser(); + + private final DorisClientConverter dorisClientConverter = new DorisClientConverter(); + + @Override + public BaseStatement reverse(DialectNode dialectNode, ReverseContext context) { + return (BaseStatement)dorisLanguageParser.parseNode(dialectNode.getNode(), context); + } + + @Override + public DialectNode transform(BaseStatement source, TransformContext context) { + DialectMeta dialectMeta = new DialectMeta(DialectName.DORIS, IVersion.getDefault()); + DorisContext starRocksContext = new DorisContext(context); + StatementBuilder builder = BuilderFactory.getInstance().getBuilder(source, dialectMeta, starRocksContext); + if (builder == null) { + throw new UnsupportedOperationException( + "UnSupported statement transform with target Dialect, source: " + source.getClass()); + } + return builder.build(source, starRocksContext); + } + + @Override + public Node reverseTable(Table table, ReverseContext context) { + return dorisClientConverter.covertToNode(table, TableConfig.builder().build()); + } + + @Override + public Table transformTable(Node table, TransformContext context) { + return dorisClientConverter.convertToTable(table, new DorisContext(context)); + } + + @Override + public BaseClientProperty create(String name, String value) { + return dorisClientConverter.getPropertyConverter().create(name, value); + } +} diff --git a/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/builder/DefaultBuilder.java b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/builder/DefaultBuilder.java new file mode 100644 index 0000000..50a5d3f --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/builder/DefaultBuilder.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021. Aliyun.com All right reserved. This software is the + * confidential and proprietary information of Aliyun.com ("Confidential + * Information"). You shall not disclose such Confidential Information and shall + * use it only in accordance with the terms of the license agreement you entered + * into with Aliyun.com. + */ + +package com.aliyun.fastmodel.transform.doris.builder; + +import com.aliyun.fastmodel.core.tree.BaseStatement; +import com.aliyun.fastmodel.transform.api.builder.BuilderAnnotation; +import com.aliyun.fastmodel.transform.api.builder.StatementBuilder; +import com.aliyun.fastmodel.transform.api.dialect.DialectName.Constants; +import com.aliyun.fastmodel.transform.api.dialect.DialectNode; +import com.aliyun.fastmodel.transform.doris.context.DorisContext; +import com.aliyun.fastmodel.transform.doris.format.DorisOutVisitor; +import com.google.auto.service.AutoService; + +/** + * 默认的builder实现 + * 支持doris的DDL输出 + * + * @author panguanjing + */ +@BuilderAnnotation(dialect = Constants.DORIS, values = {BaseStatement.class}) +@AutoService(StatementBuilder.class) +public class DefaultBuilder implements StatementBuilder { + + @Override + public DialectNode build(BaseStatement source, DorisContext context) { + DorisOutVisitor outVisitor = new DorisOutVisitor(context); + Boolean process = outVisitor.process(source, 0); + StringBuilder builder = outVisitor.getBuilder(); + return new DialectNode(builder.toString(), process); + } +} diff --git a/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/client/DorisClientConverter.java b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/client/DorisClientConverter.java new file mode 100644 index 0000000..cb0a2a5 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/client/DorisClientConverter.java @@ -0,0 +1,51 @@ +package com.aliyun.fastmodel.transform.doris.client; + +import com.aliyun.fastmodel.core.parser.LanguageParser; +import com.aliyun.fastmodel.core.tree.Node; +import com.aliyun.fastmodel.core.tree.datatype.IDataTypeName; +import com.aliyun.fastmodel.transform.api.client.PropertyConverter; +import com.aliyun.fastmodel.transform.api.extension.client.converter.ExtensionClientConverter; +import com.aliyun.fastmodel.transform.doris.context.DorisContext; +import com.aliyun.fastmodel.transform.doris.format.DorisOutVisitor; +import com.aliyun.fastmodel.transform.doris.parser.DorisLanguageParser; +import com.aliyun.fastmodel.transform.doris.parser.tree.DorisDataTypeName; + +/** + * DorisClientConverter + * + * @author panguanjing + * @date 2024/1/21 + */ +public class DorisClientConverter extends ExtensionClientConverter { + + private final DorisLanguageParser dorisLanguageParser; + + private final DorisPropertyConverter dorisPropertyConverter; + + public DorisClientConverter() { + dorisLanguageParser = new DorisLanguageParser(); + dorisPropertyConverter = new DorisPropertyConverter(); + } + + @Override + public IDataTypeName getDataTypeName(String dataTypeName) { + return DorisDataTypeName.getByValue(dataTypeName); + } + + @Override + public LanguageParser getLanguageParser() { + return this.dorisLanguageParser; + } + + @Override + public String getRaw(Node node) { + DorisOutVisitor dorisOutVisitor = new DorisOutVisitor(DorisContext.builder().build()); + node.accept(dorisOutVisitor, 0); + return dorisOutVisitor.getBuilder().toString(); + } + + @Override + public PropertyConverter getPropertyConverter() { + return dorisPropertyConverter; + } +} diff --git a/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/client/DorisPropertyConverter.java b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/client/DorisPropertyConverter.java new file mode 100644 index 0000000..6f5bde4 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/client/DorisPropertyConverter.java @@ -0,0 +1,32 @@ +package com.aliyun.fastmodel.transform.doris.client; + +import java.util.Map; +import java.util.function.Function; + +import com.aliyun.fastmodel.transform.api.client.converter.BasePropertyConverter; +import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; +import com.google.common.collect.Maps; + +/** + * doris property converter + * + * @author panguanjing + * @date 2024/1/21 + */ +public class DorisPropertyConverter extends BasePropertyConverter { + + private static Map> functionMap = Maps.newHashMap(); + + public DorisPropertyConverter() { + init(); + } + + private void init() { + + } + + @Override + protected Map> getFunctionMap() { + return functionMap; + } +} diff --git a/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/context/DorisContext.java b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/context/DorisContext.java new file mode 100644 index 0000000..3add3fb --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/context/DorisContext.java @@ -0,0 +1,31 @@ +package com.aliyun.fastmodel.transform.doris.context; + +import com.aliyun.fastmodel.transform.api.context.TransformContext; + +/** + * doris context + * + * @author panguanjing + * @date 2024/1/20 + */ +public class DorisContext extends TransformContext { + public DorisContext(TransformContext context) { + super(context); + } + + public DorisContext(Builder tBuilder) { + super(tBuilder); + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder extends TransformContext.Builder { + + @Override + public DorisContext build() { + return new DorisContext(this); + } + } +} diff --git a/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/format/DorisExpressionVisitor.java b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/format/DorisExpressionVisitor.java new file mode 100644 index 0000000..a4f79e0 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/format/DorisExpressionVisitor.java @@ -0,0 +1,52 @@ +package com.aliyun.fastmodel.transform.doris.format; + +import com.aliyun.fastmodel.common.utils.StripUtils; +import com.aliyun.fastmodel.core.tree.expr.Identifier; +import com.aliyun.fastmodel.transform.api.format.DefaultExpressionVisitor; +import com.aliyun.fastmodel.transform.doris.context.DorisContext; +import com.aliyun.fastmodel.transform.doris.parser.tree.DorisGenericDataType; +import com.aliyun.fastmodel.transform.doris.parser.util.DorisReservedWordUtil; +import com.aliyun.fastmodel.transform.doris.parser.visitor.DorisAstVisitor; +import org.apache.commons.lang3.StringUtils; + +/** + * DorisExpressionVisitor + * + * @author panguanjing + * @date 2024/1/20 + */ +public class DorisExpressionVisitor extends DefaultExpressionVisitor implements DorisAstVisitor { + public DorisExpressionVisitor(DorisContext context) {} + + @Override + public String visitDorisGenericDataType(DorisGenericDataType dorisGenericDataType, Void context) { + return DorisAstVisitor.super.visitDorisGenericDataType(dorisGenericDataType, context); + } + + @Override + public String visitIdentifier(Identifier node, Void context) { + String value = StringUtils.isNotBlank(node.getOrigin()) ? + StripUtils.strip(node.getOrigin()) : node.getValue(); + if (!node.isDelimited()) { + boolean reservedKeyWord = DorisReservedWordUtil.isReservedKeyWord(value); + //如果node是关键字,那么进行转义处理 + if (reservedKeyWord) { + return StripUtils.addPrefix(value); + } + return value; + } else { + String strip = StripUtils.strip(value); + return StripUtils.addPrefix(strip); + } + } + + @Override + public String formatStringLiteral(String s) { + if (s == null) { + return null; + } + String result = s.replace("\\", "\\\\"); + result = result.replace("\"", "\\\""); + return "\"" + result + "\""; + } +} diff --git a/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/format/DorisOutVisitor.java b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/format/DorisOutVisitor.java new file mode 100644 index 0000000..fe83991 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/format/DorisOutVisitor.java @@ -0,0 +1,659 @@ +package com.aliyun.fastmodel.transform.doris.format; + +import java.util.Iterator; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import com.aliyun.fastmodel.core.formatter.FastModelVisitor; +import com.aliyun.fastmodel.core.tree.Property; +import com.aliyun.fastmodel.core.tree.datatype.BaseDataType; +import com.aliyun.fastmodel.core.tree.expr.BaseExpression; +import com.aliyun.fastmodel.core.tree.expr.Identifier; +import com.aliyun.fastmodel.core.tree.expr.atom.FunctionCall; +import com.aliyun.fastmodel.core.tree.expr.literal.BooleanLiteral; +import com.aliyun.fastmodel.core.tree.expr.literal.ListStringLiteral; +import com.aliyun.fastmodel.core.tree.statement.table.AddCols; +import com.aliyun.fastmodel.core.tree.statement.table.ChangeCol; +import com.aliyun.fastmodel.core.tree.statement.table.ColumnDefinition; +import com.aliyun.fastmodel.core.tree.statement.table.CreateTable; +import com.aliyun.fastmodel.core.tree.statement.table.DropCol; +import com.aliyun.fastmodel.core.tree.statement.table.PartitionedBy; +import com.aliyun.fastmodel.core.tree.statement.table.RenameCol; +import com.aliyun.fastmodel.core.tree.statement.table.RenameTable; +import com.aliyun.fastmodel.core.tree.statement.table.SetTableProperties; +import com.aliyun.fastmodel.core.tree.statement.table.UnSetTableProperties; +import com.aliyun.fastmodel.core.tree.statement.table.constraint.BaseConstraint; +import com.aliyun.fastmodel.core.tree.statement.table.constraint.PrimaryConstraint; +import com.aliyun.fastmodel.core.tree.statement.table.constraint.UniqueConstraint; +import com.aliyun.fastmodel.core.tree.statement.table.index.TableIndex; +import com.aliyun.fastmodel.core.tree.util.PropertyUtil; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.AggregateKeyConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.DuplicateKeyConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.DistributeConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.NonKeyConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.OrderByConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.RollupConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.RollupItem; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.ExpressionPartitionBy; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.ListPartitionedBy; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.RangePartitionedBy; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.MultiItemListPartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.MultiRangePartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.PartitionDesc; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.SingleItemListPartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.SingleRangePartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.ArrayPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.LessThanPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.ListPartitionValue; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.PartitionValue; +import com.aliyun.fastmodel.transform.api.format.PropertyKey; +import com.aliyun.fastmodel.transform.doris.context.DorisContext; +import com.aliyun.fastmodel.transform.doris.parser.visitor.DorisAstVisitor; +import com.google.common.base.Objects; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; + +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.COLUMN_AGG_DESC; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.COLUMN_AUTO_INCREMENT; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.COLUMN_KEY; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_ENGINE; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_INDEX_COMMENT; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_INDEX_TYPE; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_PARTITION_RAW; + +/** + * StarRocksVisitor + * + * @author panguanjing + * @date 2023/9/5 + */ +public class DorisOutVisitor extends FastModelVisitor implements DorisAstVisitor { + + public static final String MAXVALUE = "MAXVALUE"; + private final DorisContext context; + + public DorisOutVisitor(DorisContext context) { + this.context = context; + } + + @Override + public Boolean visitCreateTable(CreateTable node, Integer indent) { + boolean columnEmpty = node.isColumnEmpty(); + //maxcompute不支持没有列的表 + boolean executable = !columnEmpty; + builder.append("CREATE TABLE "); + if (node.isNotExists()) { + builder.append("IF NOT EXISTS "); + } + String tableName = getCode(node.getQualifiedName()); + builder.append(tableName); + if (!columnEmpty) { + builder.append("\n(\n"); + String elementIndent = indentString(indent + 1); + String columnList = formatColumnList(node.getColumnDefines(), elementIndent); + builder.append(columnList); + + if (!node.isIndexEmpty()) { + for (TableIndex tableIndex : node.getTableIndexList()) { + builder.append(",\n"); + process(tableIndex, indent + 1); + } + } + builder.append("\n").append(")"); + } + + //format engine + if (node.getProperties() != null) { + Optional first = node.getProperties().stream().filter( + p -> StringUtils.equalsIgnoreCase(p.getName(), TABLE_ENGINE.getValue())).findFirst(); + first.ifPresent(property -> builder.append("\nENGINE=").append(property.getValue())); + } + + //key constraint + if (!node.isConstraintEmpty()) { + List keyConstraint = node.getConstraintStatements().stream().filter( + c -> !(c instanceof NonKeyConstraint)).collect(Collectors.toList()); + appendConstraint(keyConstraint, indent); + } + + if (node.getComment() != null) { + builder.append("\n"); + builder.append(formatComment(node.getComment(), true)); + } + //format partitioned by + if (!node.isPartitionEmpty()) { + builder.append("\n"); + process(node.getPartitionedBy(), indent); + } else { + String propertyValue = PropertyUtil.getPropertyValue(node.getProperties(), TABLE_PARTITION_RAW.getValue()); + if (StringUtils.isNotBlank(propertyValue)) { + builder.append("\n"); + builder.append(propertyValue); + } + } + + //non key constraint + if (!node.isConstraintEmpty()) { + List nonKeyConstraint = node.getConstraintStatements().stream().filter( + c -> c instanceof NonKeyConstraint).collect(Collectors.toList()); + appendConstraint(nonKeyConstraint, indent); + } + + if (!node.isPropertyEmpty()) { + String prop = formatProperty(node.getProperties()); + if (StringUtils.isNotBlank(prop)) { + builder.append("\n"); + builder.append("PROPERTIES ("); + builder.append(prop); + builder.append(")"); + } + } + builder.append(";"); + return executable; + } + + @Override + protected String formatProperty(List properties) { + List collect = properties.stream().filter( + p -> { + PropertyKey byValue = DorisPropertyKey.getByValue(p.getName()); + return byValue == null || byValue.isSupportPrint(); + } + ).collect(Collectors.toList()); + return super.formatProperty(collect); + } + + @Override + protected String formatColumnDefinition(ColumnDefinition column, Integer max) { + BaseDataType dataType = column.getDataType(); + String col = formatColName(column.getColName(), max); + StringBuilder sb = new StringBuilder().append(col); + if (dataType != null) { + sb.append(" ").append(formatDataType(dataType)); + } + List columnProperties = column.getColumnProperties(); + + //key + String key = PropertyUtil.getPropertyValue(columnProperties, COLUMN_KEY.getValue()); + if (StringUtils.isNotBlank(key)) { + sb.append(" ").append("KEY"); + } + //aggDesc + String propertyValue = PropertyUtil.getPropertyValue(columnProperties, COLUMN_AGG_DESC.getValue()); + if (StringUtils.isNotBlank(propertyValue)) { + sb.append(" ").append(propertyValue); + } + boolean isNotNull = column.getNotNull() != null && column.getNotNull(); + if (isNotNull) { + sb.append(" NOT NULL"); + } else if (BooleanUtils.isFalse(column.getNotNull())) { + sb.append(" NULL"); + } + if (column.getDefaultValue() != null) { + String expressionValue = formatExpression(column.getDefaultValue()); + if (column.getDefaultValue() instanceof FunctionCall) { + sb.append(" DEFAULT (").append(expressionValue).append(")"); + } else { + sb.append(" DEFAULT ").append(expressionValue); + } + } + //auto increment + String autoIncrement = PropertyUtil.getPropertyValue(columnProperties, COLUMN_AUTO_INCREMENT.getValue()); + if (StringUtils.equalsIgnoreCase(BooleanLiteral.TRUE, autoIncrement)) { + sb.append(" ").append("AUTO_INCREMENT"); + } + sb.append(formatComment(column.getComment(), isEndNewLine(sb.toString()))); + return sb.toString(); + } + + private void appendConstraint(List constraints, Integer indent) { + for (BaseConstraint baseConstraint : constraints) { + builder.append("\n"); + process(baseConstraint, indent); + } + } + + @Override + public Boolean visitAggregateConstraint(AggregateKeyConstraint aggregateConstraint, Integer context) { + builder.append("AGGREGATE KEY ("); + List colNames = aggregateConstraint.getColumns(); + builder.append(colNames.stream().map(this::formatExpression).collect(Collectors.joining(","))); + builder.append(")"); + return true; + } + + @Override + public Boolean visitDuplicateConstraint(DuplicateKeyConstraint duplicateConstraint, Integer context) { + builder.append("DUPLICATE KEY ("); + List colNames = duplicateConstraint.getColumns(); + builder.append(colNames.stream().map(this::formatExpression).collect(Collectors.joining(","))); + builder.append(")"); + return true; + } + + @Override + public Boolean visitPrimaryConstraint(PrimaryConstraint primaryConstraint, Integer ident) { + builder.append("PRIMARY KEY ("); + List colNames = primaryConstraint.getColNames(); + builder.append(colNames.stream().map(this::formatExpression).collect(Collectors.joining(","))); + builder.append(")"); + return true; + } + + @Override + public Boolean visitRollupConstraint(RollupConstraint rollupConstraint, Integer context) { + builder.append("ROLLUP ("); + if (CollectionUtils.isNotEmpty(rollupConstraint.getRollupItemList())) { + String s = rollupConstraint.getRollupItemList().stream().map( + this::formatRollupItem + ).collect(Collectors.joining(",")); + builder.append(s); + } + builder.append(")"); + return true; + } + + private String formatRollupItem(RollupItem item) { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(formatExpression(item.getRollupName())); + stringBuilder.append(" ("); + String columnList = getCollect(item.getColumnList()); + stringBuilder.append(columnList); + stringBuilder.append(")"); + if (CollectionUtils.isNotEmpty(item.getDuplicateList())) { + stringBuilder.append(" DUPLICATE KEY ("); + String duplicate = getCollect(item.getDuplicateList()); + stringBuilder.append(duplicate); + stringBuilder.append(")"); + } + if (item.getFromRollup() != null) { + stringBuilder.append(" FROM "); + stringBuilder.append(formatExpression(item.getFromRollup())); + } + + if (CollectionUtils.isNotEmpty(item.getProperties())) { + stringBuilder.append(" PROPERTIES ("); + String p = formatProperty(item.getProperties()); + stringBuilder.append(p); + stringBuilder.append(")"); + } + return stringBuilder.toString(); + } + + private String getCollect(List item) { + return item.stream().map(this::formatExpression).collect(Collectors.joining(",")); + } + + @Override + protected String formatStringLiteral(String s) { + return new DorisExpressionVisitor(context).formatStringLiteral(s); + } + + @Override + public Boolean visitUniqueConstraint(UniqueConstraint uniqueConstraint, Integer indent) { + builder.append("UNIQUE KEY ("); + builder.append(uniqueConstraint.getColumnNames().stream().map(this::formatExpression).collect(Collectors.joining(","))); + builder.append(")"); + return true; + } + + @Override + protected String formatExpression(BaseExpression baseExpression) { + return new DorisExpressionVisitor(context).process(baseExpression); + } + + @Override + public Boolean visitChangeCol(ChangeCol renameCol, Integer context) { + //starRocks不支持修改列名 + Identifier oldColName = renameCol.getOldColName(); + ColumnDefinition columnDefinition = renameCol.getColumnDefinition(); + Identifier targetColName = columnDefinition.getColName(); + if (!Objects.equal(oldColName, targetColName)) { + return false; + } + builder.append("ALTER TABLE ").append(getCode(renameCol.getQualifiedName())); + builder.append(" MODIFY COLUMN"); + builder.append(" ").append(formatColumnDefinition(columnDefinition, 0)); + return true; + } + + @Override + public Boolean visitDropCol(DropCol dropCol, Integer context) { + return super.visitDropCol(dropCol, context); + } + + @Override + public Boolean visitRenameTable(RenameTable renameTable, Integer context) { + builder.append("ALTER TABLE "); + builder.append(getCode(renameTable.getQualifiedName())); + builder.append(" RENAME ").append(getCode(renameTable.getTarget())); + return true; + } + + /** + * 不支持修改列名 + * + * @param renameCol + * @param context + * @return + */ + @Override + public Boolean visitRenameCol(RenameCol renameCol, Integer context) { + return !super.visitRenameCol(renameCol, context); + } + + @Override + public Boolean visitSetTableProperties(SetTableProperties setTableProperties, Integer context) { + builder.append("ALTER TABLE "); + builder.append(formatName(setTableProperties.getQualifiedName())); + builder.append(" SET ("); + builder.append(formatProperty(setTableProperties.getProperties())); + builder.append(")"); + return true; + } + + @Override + public Boolean visitUnSetTableProperties(UnSetTableProperties unSetTableProperties, Integer context) { + builder.append("ALTER TABLE "); + builder.append(formatName(unSetTableProperties.getQualifiedName())); + builder.append(" SET ("); + List propertyKeys = unSetTableProperties.getPropertyKeys(); + String a = propertyKeys.stream().map( + k -> formatStringLiteral(k) + "=" + "\"\"" + ).collect(Collectors.joining(",")); + builder.append(a); + builder.append(")"); + return true; + } + + @Override + public Boolean visitAddCols(AddCols addCols, Integer context) { + builder.append("ALTER TABLE ").append(getCode(addCols.getQualifiedName())); + builder.append(" ADD COLUMN\n").append('(').append("\n"); + String columnList = formatColumnList(addCols.getColumnDefineList(), indentString(context + 1)); + builder.append(columnList); + builder.append("\n"); + builder.append(')'); + return true; + } + + @Override + public Boolean visitTableIndex(TableIndex tableIndex, Integer ident) { + builder.append(indentString(ident)); + builder.append("INDEX ").append(formatExpression(tableIndex.getIndexName())); + appendTableIndex(tableIndex.getIndexColumnNames()); + List properties = tableIndex.getProperties(); + if (CollectionUtils.isEmpty(properties)) { + return true; + } + Optional first = properties.stream().filter(p -> { + return StringUtils.equalsIgnoreCase(p.getName(), TABLE_INDEX_TYPE.getValue()); + }).findFirst(); + first.ifPresent(property -> builder.append(" USING ").append(property.getValue())); + + Optional comment = properties.stream().filter(p -> { + return StringUtils.equalsIgnoreCase(p.getName(), TABLE_INDEX_COMMENT.getValue()); + }).findFirst(); + comment.ifPresent(property -> builder.append(" COMMENT ").append(formatStringLiteral(property.getValue()))); + return true; + } + + @Override + public Boolean visitRangePartitionedBy(RangePartitionedBy starRocksPartitionedBy, Integer indent) { + builder.append("PARTITION BY RANGE ("); + List partitioned = starRocksPartitionedBy.getColumnDefinitions(); + String collect = partitioned.stream().map( + x -> this.formatExpression(x.getColName()) + ).collect(Collectors.joining(",")); + builder.append(collect).append(")"); + List rangePartitions = starRocksPartitionedBy.getRangePartitions(); + if (CollectionUtils.isNotEmpty(rangePartitions)) { + builder.append("\n"); + } else { + return true; + } + Iterator iterator = rangePartitions.iterator(); + builder.append("("); + if (iterator.hasNext()) { + builder.append("\n"); + process(iterator.next(), indent + 1); + while (iterator.hasNext()) { + builder.append(",\n"); + process(iterator.next(), indent + 1); + } + } + if (CollectionUtils.isNotEmpty(rangePartitions)) { + builder.append("\n"); + } + builder.append(")"); + return true; + } + + @Override + public Boolean visitPartitionedBy(PartitionedBy partitionedBy, Integer context) { + if (partitionedBy instanceof RangePartitionedBy) { + return visitRangePartitionedBy((RangePartitionedBy)partitionedBy, context); + } + if (partitionedBy instanceof ListPartitionedBy) { + return visitListPartitionedBy((ListPartitionedBy)partitionedBy, context); + } + if (partitionedBy instanceof ExpressionPartitionBy) { + return visitExpressionPartitionedBy((ExpressionPartitionBy)partitionedBy, context); + } + return super.visitPartitionedBy(partitionedBy, context); + } + + @Override + public Boolean visitListPartitionedBy(ListPartitionedBy listPartitionedBy, Integer indent) { + builder.append("PARTITION BY LIST ("); + List partitioned = listPartitionedBy.getColumnDefinitions(); + String collect = partitioned.stream().map( + x -> formatExpression(x.getColName()) + ).collect(Collectors.joining(",")); + builder.append(collect).append(")"); + builder.append("\n"); + List rangePartitions = listPartitionedBy.getListPartitions(); + if (rangePartitions == null) { + return true; + } + Iterator iterator = rangePartitions.iterator(); + if (iterator.hasNext()) { + builder.append("(\n"); + process(iterator.next(), indent + 1); + while (iterator.hasNext()) { + builder.append(",\n"); + process(iterator.next(), indent + 1); + } + builder.append("\n)"); + } + return true; + } + + @Override + public Boolean visitExpressionPartitionedBy(ExpressionPartitionBy expressionPartitionedBy, Integer indent) { + builder.append("PARTITION BY "); + List partitioned = expressionPartitionedBy.getColumnDefinitions(); + String col = partitioned.stream().map( + x -> formatExpression(x.getColName()) + ).collect(Collectors.joining(",")); + if (expressionPartitionedBy.getFunctionCall() == null) { + // 列表达式 + builder.append("(").append(col).append(")"); + } else { + // 时间函数表达式 + FunctionCall functionCall = expressionPartitionedBy.getFunctionCall(); + String function = formatExpression(functionCall); + builder.append(function); + } + return true; + } + + @Override + public Boolean visitSingleItemListPartition(SingleItemListPartition singleItemListPartition, Integer context) { + builder.append("PARTITION "); + if (singleItemListPartition.isIfNotExists()) { + builder.append("IF NOT EXISTS "); + } + builder.append(formatExpression(singleItemListPartition.getName())); + builder.append(" VALUES IN ("); + String collect = getListString(singleItemListPartition.getListStringLiteral()); + builder.append(collect); + builder.append(")"); + appendProperty(singleItemListPartition.getPropertyList()); + return true; + } + + private void appendProperty(List propertyList) { + if (propertyList == null || propertyList.isEmpty()) { + return; + } + builder.append(" "); + builder.append("("); + builder.append(formatProperty(propertyList)); + builder.append(")"); + } + + private String getListString(ListStringLiteral listStringLiteral) { + return listStringLiteral.getStringLiteralList().stream().map( + this::formatExpression + ).collect(Collectors.joining(",")); + } + + private String getListString(ListPartitionValue listStringLiteral) { + return listStringLiteral.getPartitionValueList().stream().map( + this::formatPartitionValue + ).collect(Collectors.joining(",")); + } + + private String formatPartitionValue(PartitionValue partitionValue) { + if (partitionValue.isMaxValue()) { + return MAXVALUE; + } + return formatExpression(partitionValue.getStringLiteral()); + } + + @Override + public Boolean visitMultiItemListPartition(MultiItemListPartition multiItemListPartition, Integer context) { + builder.append("PARTITION "); + if (multiItemListPartition.isIfNotExists()) { + builder.append("IF NOT EXISTS "); + } + builder.append(formatExpression(multiItemListPartition.getName())); + builder.append(" VALUES IN ("); + String collect = multiItemListPartition.getListStringLiterals().stream().map( + x -> "(" + getListString(x) + ")" + ).collect(Collectors.joining(",")); + builder.append(collect); + builder.append(")"); + appendProperty(multiItemListPartition.getPropertyList()); + return true; + } + + @Override + public Boolean visitOrderByConstraint(OrderByConstraint orderByConstraint, Integer context) { + builder.append("ORDER BY ("); + List colNames = orderByConstraint.getColumns(); + builder.append(colNames.stream().map(this::formatExpression).collect(Collectors.joining(","))); + builder.append(")"); + return true; + } + + @Override + public Boolean visitDistributeKeyConstraint(DistributeConstraint distributeKeyConstraint, Integer context) { + builder.append("DISTRIBUTED BY "); + boolean random = BooleanUtils.isTrue(distributeKeyConstraint.getRandom()); + if (random) { + builder.append("RANDOM"); + } else { + builder.append("HASH"); + } + if (CollectionUtils.isNotEmpty(distributeKeyConstraint.getColumns())) { + List colNames = distributeKeyConstraint.getColumns(); + builder.append("("); + builder.append(colNames.stream().map(this::formatExpression).collect(Collectors.joining(","))); + builder.append(")"); + } + if (distributeKeyConstraint.getBucket() != null) { + builder.append(" BUCKETS "); + builder.append(distributeKeyConstraint.getBucket()); + } + return true; + } + + @Override + public Boolean visitSingleRangePartition(SingleRangePartition singleRangePartition, Integer context) { + String s = indentString(context); + builder.append(s).append("PARTITION "); + if (singleRangePartition.isIfNotExists()) { + builder.append("IF NOT EXISTS "); + } + builder.append(formatExpression(singleRangePartition.getName())); + builder.append(" VALUES "); + process(singleRangePartition.getPartitionKey()); + + if (singleRangePartition.getPropertyList() != null) { + String property = formatProperty(singleRangePartition.getPropertyList()); + builder.append(property); + } + return true; + } + + @Override + public Boolean visitLessThanPartitionKey(LessThanPartitionKey lessThanPartitionKey, Integer context) { + builder.append("LESS THAN "); + if (lessThanPartitionKey.isMaxValue()) { + builder.append(MAXVALUE); + } else { + String collect = lessThanPartitionKey.getPartitionValues().getPartitionValueList().stream() + .map(this::formatPartitionValue) + .collect(Collectors.joining(",")); + builder.append("("); + builder.append(collect); + builder.append(")"); + } + return true; + } + + @Override + public Boolean visitArrayPartitionKey(ArrayPartitionKey arrayPartitionKey, Integer context) { + builder.append("["); + String value = arrayPartitionKey.getPartitionValues().stream().map( + p -> "(" + getListString(p) + ")" + ).collect(Collectors.joining(",")); + builder.append(value); + builder.append(")"); + return true; + } + + @Override + public Boolean visitMultiRangePartition(MultiRangePartition multiRangePartition, Integer context) { + String s = indentString(context); + builder.append(s).append("FROM "); + builder.append("(").append(formatListPartitionValue(multiRangePartition.getStart())); + builder.append(")"); + builder.append(" "); + builder.append("TO "); + builder.append("("); + builder.append(formatListPartitionValue(multiRangePartition.getEnd())); + builder.append(")"); + builder.append(" ").append(formatExpression(multiRangePartition.getIntervalLiteral())); + return true; + } + + private String formatListPartitionValue(ListPartitionValue listPartitionValue) { + return listPartitionValue.getPartitionValueList().stream().map( + p -> { + return formatPartitionValue(p); + } + ).collect(Collectors.joining(",")); + } + + @Override + public Boolean visitListPartitionValue(ListPartitionValue listPartitionValue, Integer context) { + builder.append(formatListPartitionValue(listPartitionValue)); + return true; + } + +} diff --git a/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/format/DorisPropertyKey.java b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/format/DorisPropertyKey.java new file mode 100644 index 0000000..916a5c6 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/format/DorisPropertyKey.java @@ -0,0 +1,56 @@ +package com.aliyun.fastmodel.transform.doris.format; + +import com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey; +import com.aliyun.fastmodel.transform.api.format.PropertyKey; +import org.apache.commons.lang3.StringUtils; + +/** + * DorisPropertyKey + * + * @author panguanjing + * @date 2024/1/20 + */ +public enum DorisPropertyKey implements PropertyKey { + /** + * on update + */ + COLUMN_ON_UPDATE_CURRENT_TIMESTAMP("column_on_update"); + + private final String value; + + private final boolean supportPrint; + + DorisPropertyKey(String value) { + this(value, false); + } + + DorisPropertyKey(String value, boolean supportPrint) { + this.value = value; + this.supportPrint = supportPrint; + } + + public static PropertyKey getByValue(String value) { + DorisPropertyKey[] propertyKeys = DorisPropertyKey.values(); + for (DorisPropertyKey starRocksProperty : propertyKeys) { + if (StringUtils.equalsIgnoreCase(starRocksProperty.getValue(), value)) { + return starRocksProperty; + } + } + for (ExtensionPropertyKey extensionPropertyKey : ExtensionPropertyKey.values()) { + if (StringUtils.equalsIgnoreCase(extensionPropertyKey.getValue(), value)) { + return extensionPropertyKey; + } + } + return null; + } + + @Override + public String getValue() { + return this.value; + } + + @Override + public boolean isSupportPrint() { + return this.supportPrint; + } +} diff --git a/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/parser/DorisLanguageParser.java b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/parser/DorisLanguageParser.java new file mode 100644 index 0000000..e24f109 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/parser/DorisLanguageParser.java @@ -0,0 +1,44 @@ +package com.aliyun.fastmodel.transform.doris.parser; + +import com.aliyun.fastmodel.common.parser.ParserHelper; +import com.aliyun.fastmodel.core.exception.ParseException; +import com.aliyun.fastmodel.core.parser.LanguageParser; +import com.aliyun.fastmodel.core.tree.Node; +import com.aliyun.fastmodel.core.tree.datatype.BaseDataType; +import com.aliyun.fastmodel.transform.api.context.ReverseContext; +import com.aliyun.fastmodel.transform.doris.parser.visitor.DorisAstBuilder; +import com.google.auto.service.AutoService; +import org.antlr.v4.runtime.ParserRuleContext; + +/** + * doris language parser + * + * @author panguanjing + * @date 2024/1/20 + */ +@AutoService(LanguageParser.class) +public class DorisLanguageParser implements LanguageParser { + @Override + public Node parseNode(String text, ReverseContext context) throws ParseException { + ParserRuleContext parserRuleContext = ParserHelper.getNode(text, charStream -> new DorisLexer(charStream), + tokenStream -> new DorisParser(tokenStream), + parser -> { + DorisParser dorisParser = (DorisParser)parser; + return dorisParser.multiStatements(); + } + ); + return parserRuleContext.accept(new DorisAstBuilder(context)); + } + + @Override + public BaseDataType parseDataType(String text, ReverseContext context) throws ParseException { + ParserRuleContext parserRuleContext = ParserHelper.getNode(text, charStream -> new DorisLexer(charStream), + tokenStream -> new DorisParser(tokenStream), + parser -> { + DorisParser dorisParser = (DorisParser)parser; + return dorisParser.dataType(); + } + ); + return (BaseDataType)parserRuleContext.accept(new DorisAstBuilder(context)); + } +} diff --git a/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/parser/tree/DorisDataTypeName.java b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/parser/tree/DorisDataTypeName.java new file mode 100644 index 0000000..41e6759 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/parser/tree/DorisDataTypeName.java @@ -0,0 +1,262 @@ +package com.aliyun.fastmodel.transform.doris.parser.tree; + +import com.aliyun.fastmodel.core.tree.datatype.IDataTypeName; +import com.aliyun.fastmodel.transform.api.datatype.simple.ISimpleDataTypeName; +import com.aliyun.fastmodel.transform.api.datatype.simple.SimpleDataTypeName; +import org.apache.commons.lang3.StringUtils; + +/** + * starRocks DataType Name + * + * @author panguanjing + * @date 2023/9/12 + */ +public enum DorisDataTypeName implements ISimpleDataTypeName { + + /** + * tinyint + */ + TINYINT("TINYINT", Dimension.ONE, SimpleDataTypeName.NUMBER), + + /** + * small int + */ + SMALLINT("SMALLINT", Dimension.ONE, SimpleDataTypeName.NUMBER), + + /** + * signed int + */ + SIGNED_INT("SIGNED INT", Dimension.ZERO, SimpleDataTypeName.NUMBER), + + /** + * unsigned int + */ + UNSIGNED_INT("UNSIGNED INT", Dimension.ZERO, SimpleDataTypeName.NUMBER), + + /** + * singed integer + */ + SIGNED_INTEGER("SIGNED INTEGER", Dimension.ZERO, SimpleDataTypeName.NUMBER), + + /** + * unsiged integer + */ + UNSIGNED_INTEGER("UNSIGNED INTEGER", Dimension.ZERO, SimpleDataTypeName.NUMBER), + + /** + * int + */ + INT("INT", Dimension.ONE, SimpleDataTypeName.NUMBER), + + /** + * integer + */ + INTEGER("INTEGER", Dimension.ONE, SimpleDataTypeName.NUMBER), + + /** + * bigint + */ + BIGINT("BIGINT", Dimension.ONE, SimpleDataTypeName.NUMBER), + + /** + * large int + */ + LARGEINT("LARGEINT", Dimension.ONE, SimpleDataTypeName.NUMBER), + + /** + * boolean + */ + BOOLEAN("BOOLEAN", Dimension.ZERO, SimpleDataTypeName.BOOLEAN), + + /** + * float + */ + FLOAT("FLOAT", Dimension.ZERO, SimpleDataTypeName.NUMBER), + + /** + * double + */ + DOUBLE("DOUBLE", Dimension.ZERO, SimpleDataTypeName.NUMBER), + + /** + * date + */ + DATE("DATE", Dimension.ZERO, SimpleDataTypeName.DATE), + + /** + * datetime + */ + DATETIME("DATETIME", Dimension.ZERO, SimpleDataTypeName.DATE), + + /** + * time + */ + TIME("TIME", Dimension.ZERO, SimpleDataTypeName.DATE), + + /** + * date + */ + DATEV2("DATEV2", Dimension.ZERO, SimpleDataTypeName.DATE), + + /** + * datetime + */ + DATETIMEV2("DATETIMEV2", Dimension.ZERO, SimpleDataTypeName.DATE), + + /** + * date + */ + DATEV1("DATEV1", Dimension.ZERO, SimpleDataTypeName.DATE), + + /** + * datetime + */ + DATETIMEV1("DATETIMEV1", Dimension.ZERO, SimpleDataTypeName.DATE), + + /** + * char + */ + CHAR("CHAR", Dimension.ONE, SimpleDataTypeName.STRING), + + /** + * varchar + */ + VARCHAR("VARCHAR", Dimension.ONE, SimpleDataTypeName.STRING), + + /** + * string + */ + STRING("STRING", Dimension.ZERO, SimpleDataTypeName.STRING), + + /** + * text + */ + TEXT("TEXT", Dimension.ZERO, SimpleDataTypeName.STRING), + + /** + * bitmap + */ + BITMAP("BITMAP", Dimension.ZERO, SimpleDataTypeName.NUMBER), + + /** + * QUANTILE_STATE + */ + QUANTILE_STATE("QUANTILE_STATE", Dimension.ZERO, SimpleDataTypeName.NUMBER), + + /** + * AGG_STATE + */ + AGG_STATE("AGG_STATE", Dimension.ZERO, SimpleDataTypeName.NUMBER), + + /** + * hll + */ + HLL("HLL", Dimension.ZERO, SimpleDataTypeName.NUMBER), + + /** + * json + */ + JSON("JSON", Dimension.ZERO, SimpleDataTypeName.STRING), + + /** + * jsonb + */ + JSONB("JSONB", Dimension.ZERO, SimpleDataTypeName.STRING), + + /** + * decimal + */ + DECIMAL("DECIMAL", Dimension.TWO, SimpleDataTypeName.NUMBER), + + /** + * decimal + */ + DECIMALV2("DECIMALV2", Dimension.TWO, SimpleDataTypeName.NUMBER), + + /** + * decimal32 + */ + DECIMALV3("DECIMALV3", Dimension.TWO, SimpleDataTypeName.NUMBER), + + /** + * numeric + */ + NUMERIC("NUMERIC", Dimension.TWO, SimpleDataTypeName.NUMBER), + + /** + * Array + */ + ARRAY("ARRAY", Dimension.MULTIPLE, SimpleDataTypeName.STRING), + + /** + * MAP + */ + Map("MAP", Dimension.MULTIPLE, SimpleDataTypeName.STRING), + + /** + * ipv4 + */ + IPV4("IPV4", Dimension.ZERO, SimpleDataTypeName.STRING), + /** + * ipv6 + */ + IPV6("IPV6", Dimension.ZERO, SimpleDataTypeName.STRING), + /** + * all + */ + ALL("ALL", Dimension.ZERO, SimpleDataTypeName.STRING), + ; + + /** + * multi prefix + */ + public static final String MULTI_PREFIX = "<"; + + private final String value; + + private final Dimension dimension; + + private final SimpleDataTypeName simpleDataTypeName; + + DorisDataTypeName(String value, Dimension dimension, + SimpleDataTypeName simpleDataTypeName) { + this.value = value; + this.dimension = dimension; + this.simpleDataTypeName = simpleDataTypeName; + } + + public static IDataTypeName getByValue(String value) { + String v = value; + if (v.indexOf(MULTI_PREFIX) > 0) { + v = v.substring(0, v.indexOf(MULTI_PREFIX)).trim(); + } + DorisDataTypeName[] dataTypeNames = DorisDataTypeName.values(); + for (DorisDataTypeName s : dataTypeNames) { + if (StringUtils.equalsIgnoreCase(s.getValue(), v)) { + return s; + } + } + throw new IllegalArgumentException("not support the dataType with value:" + value); + } + + @Override + public SimpleDataTypeName getSimpleDataTypeName() { + return simpleDataTypeName; + } + + @Override + public String getName() { + return name(); + } + + @Override + public String getValue() { + return value; + } + + @Override + public Dimension getDimension() { + return dimension; + } + +} diff --git a/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/parser/tree/DorisGenericDataType.java b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/parser/tree/DorisGenericDataType.java new file mode 100644 index 0000000..241a1d5 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/parser/tree/DorisGenericDataType.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022. Aliyun.com All right reserved. This software is the + * confidential and proprietary information of Aliyun.com ("Confidential + * Information"). You shall not disclose such Confidential Information and shall + * use it only in accordance with the terms of the license agreement you entered + * into with Aliyun.com. + */ + +package com.aliyun.fastmodel.transform.doris.parser.tree; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.core.tree.NodeLocation; +import com.aliyun.fastmodel.core.tree.datatype.DataTypeParameter; +import com.aliyun.fastmodel.core.tree.datatype.GenericDataType; +import com.aliyun.fastmodel.core.tree.datatype.IDataTypeName; +import com.aliyun.fastmodel.transform.doris.context.DorisContext; +import com.aliyun.fastmodel.transform.doris.format.DorisExpressionVisitor; +import com.aliyun.fastmodel.transform.doris.parser.visitor.DorisAstVisitor; +import lombok.Getter; + +/** + * DorisGenericDataType + * + * @author panguanjing + * @date 2024/01/20 + */ +@Getter +public class DorisGenericDataType extends GenericDataType { + + public DorisGenericDataType(String dataTypeName) { + super(dataTypeName); + } + + public DorisGenericDataType(String dataTypeName, List arguments) { + super(dataTypeName, arguments); + } + + public DorisGenericDataType(NodeLocation location, String origin, String dataTypeName, + List arguments) { + super(location, origin, dataTypeName, arguments); + } + + @Override + public IDataTypeName getTypeName() { + return DorisDataTypeName.getByValue(getName()); + } + + @Override + public R accept(IAstVisitor visitor, C context) { + DorisAstVisitor astVisitor = (DorisAstVisitor)visitor; + return astVisitor.visitDorisGenericDataType(this, context); + } + + @Override + public String toString() { + return new DorisExpressionVisitor(DorisContext.builder().build()).process(this); + } +} diff --git a/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/parser/util/DorisReservedWordUtil.java b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/parser/util/DorisReservedWordUtil.java new file mode 100644 index 0000000..11ee5e2 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/parser/util/DorisReservedWordUtil.java @@ -0,0 +1,38 @@ +package com.aliyun.fastmodel.transform.doris.parser.util; + +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.aliyun.fastmodel.transform.doris.parser.DorisLexer; +import com.google.common.base.Strings; +import org.antlr.v4.runtime.Vocabulary; + +/** + * DorisReservedWordUtil reserved keyword + * + * @author panguanjing + * @date 2023/11/6 + */ +public class DorisReservedWordUtil { + + private static final Pattern IDENTIFIER = Pattern.compile("'([A-Z_]+)'"); + + private static final Set SET = new HashSet<>(); + + static { + Vocabulary vocabulary = DorisLexer.VOCABULARY; + for (int i = 0; i <= vocabulary.getMaxTokenType(); i++) { + String name = Strings.nullToEmpty(vocabulary.getLiteralName(i)); + Matcher matcher = IDENTIFIER.matcher(name); + if (matcher.matches()) { + SET.add(matcher.group(1)); + } + } + } + + public static boolean isReservedKeyWord(String word) { + return SET.contains(word.toUpperCase()); + } +} diff --git a/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/parser/visitor/DorisAstBuilder.java b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/parser/visitor/DorisAstBuilder.java new file mode 100644 index 0000000..bbbc281 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/parser/visitor/DorisAstBuilder.java @@ -0,0 +1,620 @@ +package com.aliyun.fastmodel.transform.doris.parser.visitor; + +import java.util.List; +import java.util.stream.Collectors; + +import com.aliyun.fastmodel.common.parser.ParserHelper; +import com.aliyun.fastmodel.common.utils.StripUtils; +import com.aliyun.fastmodel.core.tree.BaseStatement; +import com.aliyun.fastmodel.core.tree.Comment; +import com.aliyun.fastmodel.core.tree.Node; +import com.aliyun.fastmodel.core.tree.Property; +import com.aliyun.fastmodel.core.tree.QualifiedName; +import com.aliyun.fastmodel.core.tree.datatype.BaseDataType; +import com.aliyun.fastmodel.core.tree.datatype.DataTypeParameter; +import com.aliyun.fastmodel.core.tree.datatype.Field; +import com.aliyun.fastmodel.core.tree.datatype.IDataTypeName; +import com.aliyun.fastmodel.core.tree.datatype.NumericParameter; +import com.aliyun.fastmodel.core.tree.datatype.RowDataType; +import com.aliyun.fastmodel.core.tree.datatype.TypeParameter; +import com.aliyun.fastmodel.core.tree.expr.BaseExpression; +import com.aliyun.fastmodel.core.tree.expr.Identifier; +import com.aliyun.fastmodel.core.tree.expr.atom.FunctionCall; +import com.aliyun.fastmodel.core.tree.expr.enums.DateTimeEnum; +import com.aliyun.fastmodel.core.tree.expr.literal.BooleanLiteral; +import com.aliyun.fastmodel.core.tree.expr.literal.CurrentTimestamp; +import com.aliyun.fastmodel.core.tree.expr.literal.DecimalLiteral; +import com.aliyun.fastmodel.core.tree.expr.literal.IntervalLiteral; +import com.aliyun.fastmodel.core.tree.expr.literal.LongLiteral; +import com.aliyun.fastmodel.core.tree.expr.literal.NullLiteral; +import com.aliyun.fastmodel.core.tree.expr.literal.StringLiteral; +import com.aliyun.fastmodel.core.tree.statement.CompositeStatement; +import com.aliyun.fastmodel.core.tree.statement.table.ColumnDefinition; +import com.aliyun.fastmodel.core.tree.statement.table.CreateTable; +import com.aliyun.fastmodel.core.tree.statement.table.PartitionedBy; +import com.aliyun.fastmodel.core.tree.statement.table.constraint.BaseConstraint; +import com.aliyun.fastmodel.core.tree.statement.table.constraint.UniqueConstraint; +import com.aliyun.fastmodel.core.tree.statement.table.index.TableIndex; +import com.aliyun.fastmodel.core.tree.util.IdentifierUtil; +import com.aliyun.fastmodel.transform.api.context.ReverseContext; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.AggregateKeyConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.DuplicateKeyConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.ClusterKeyConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.DistributeConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.ExpressionPartitionBy; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.ListPartitionedBy; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.RangePartitionedBy; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.MultiRangePartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.PartitionDesc; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.SingleRangePartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.ArrayPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.LessThanPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.ListPartitionValue; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.PartitionKey; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.PartitionValue; +import com.aliyun.fastmodel.transform.doris.format.DorisPropertyKey; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.BooleanLiteralContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.ColumnDefContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.CommentSpecContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.ComplexColTypeContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.ComplexDataTypeContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.ConstantSeqContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.CreateTableContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.DataTypeContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.DecimalLiteralContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.ErrorCapturingIdentifierContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.FixedPartitionDefContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.IdentifierContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.IdentifierListContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.InPartitionDefContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.IntegerLiteralContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.LessThanPartitionDefContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.MultiStatementsContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.MultipartIdentifierContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.NullLiteralContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.PartitionDefContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.PartitionValueDefContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.PrimitiveColTypeContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.PrimitiveDataTypeContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.PropertyItemContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.PropertyKeyContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.PropertyValueContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.StepPartitionDefContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParser.StringLiteralContext; +import com.aliyun.fastmodel.transform.doris.parser.DorisParserBaseVisitor; +import com.aliyun.fastmodel.transform.doris.parser.tree.DorisDataTypeName; +import com.aliyun.fastmodel.transform.doris.parser.tree.DorisGenericDataType; +import com.google.common.collect.Lists; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.BooleanUtils; + +import static com.aliyun.fastmodel.common.parser.ParserHelper.getLocation; +import static com.aliyun.fastmodel.common.parser.ParserHelper.getOrigin; +import static com.aliyun.fastmodel.common.parser.ParserHelper.visitIfPresent; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.COLUMN_AGG_DESC; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.COLUMN_AUTO_INCREMENT; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.COLUMN_KEY; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_ENGINE; + +/** + * DorisAstBuilder + * + * @author panguanjing + * @date 2024/1/20 + */ +public class DorisAstBuilder extends DorisParserBaseVisitor { + + private final ReverseContext context; + + public DorisAstBuilder(ReverseContext context) { + this.context = context; + } + + @Override + public Node visitMultiStatements(MultiStatementsContext ctx) { + List list = ParserHelper.visit(this, ctx.statement(), BaseStatement.class); + if (CollectionUtils.isEmpty(list)) { + return null; + } + if (list.size() == 1) { + return list.get(0); + } + return new CompositeStatement(ParserHelper.getLocation(ctx), ParserHelper.getOrigin(ctx), list); + } + + @Override + public Node visitCreateTable(CreateTableContext ctx) { + boolean ifNotExist = ctx.NOT() != null && ctx.EXISTS() != null; + QualifiedName tableName = (QualifiedName)visit(ctx.name); + List list = null; + List tableIndices = null; + Comment comment = null; + if (ctx.ctasCols != null) { + } else { + list = ParserHelper.visit(this, + ctx.columnDefs().columnDef(), ColumnDefinition.class); + if (ctx.indexDefs() != null) { + tableIndices = ParserHelper.visit(this, ctx.indexDefs().indexDef(), TableIndex.class); + } + } + List properties = Lists.newArrayList(); + if (ctx.ENGINE() != null) { + Property property = getEngineProp(ctx.engine); + properties.add(property); + } + List constraints = Lists.newArrayList(); + //aggregate, unique, duplicate + if (ctx.AGGREGATE() != null) { + AggregateKeyConstraint aggregateKeyConstraint = getAggregateKeyConstraint(ctx); + constraints.add(aggregateKeyConstraint); + } + if (ctx.UNIQUE() != null) { + UniqueConstraint uniqueConstraint = getUniqueConstraint(ctx); + constraints.add(uniqueConstraint); + } + if (ctx.DUPLICATE() != null) { + DuplicateKeyConstraint duplicateKeyConstraint = getDuplicateKeyConstraint(ctx); + constraints.add(duplicateKeyConstraint); + } + //cluster by + if (ctx.CLUSTER() != null) { + ClusterKeyConstraint clusterByConstraint = getClusterByConstraint(ctx); + constraints.add(clusterByConstraint); + } + + //distributed by + if (ctx.DISTRIBUTED() != null) { + //distribute key constraint + DistributeConstraint distributeKeyConstraint = getDistributeKeyConstraint(ctx); + constraints.add(distributeKeyConstraint); + } + + //table comment + if (ctx.STRING_LITERAL() != null) { + String value = StripUtils.strip(ctx.STRING_LITERAL().getText()); + comment = new Comment(value); + } + + //partition by + PartitionedBy partitionedBy = null; + if (ctx.PARTITION() != null) { + partitionedBy = getPartitionBy(ctx); + } + + //table properties + if (ctx.properties != null) { + List propertyList = ParserHelper.visit(this, + ctx.properties.propertyItemList().propertyItem(), Property.class); + properties.addAll(propertyList); + } + + return CreateTable.builder() + .tableName(tableName) + .columns(list) + .properties(properties) + .tableIndex(tableIndices) + .constraints(constraints) + .partition(partitionedBy) + .comment(comment) + .build(); + } + + private PartitionedBy getPartitionBy(CreateTableContext ctx) { + List list = null; + List columnDefines = null; + if (ctx.partitionKeys != null) { + List columns = ParserHelper.visit(this, + ctx.partitionKeys.identifierSeq().ident, Identifier.class); + columnDefines = columns.stream().map( + i -> ColumnDefinition.builder() + .colName(i) + .build() + ).collect(Collectors.toList()); + } + if (ctx.partitionsDef() != null) { + list = ParserHelper.visit(this, ctx.partitionsDef().partitions, PartitionDesc.class); + } + if (ctx.RANGE() != null) { + RangePartitionedBy rangePartitionedBy = new RangePartitionedBy( + columnDefines, list + ); + return rangePartitionedBy; + } + if (ctx.LIST() != null) { + ListPartitionedBy listPartitionedBy = new ListPartitionedBy(columnDefines, list); + return listPartitionedBy; + } + FunctionCall functionCall = null; + if (ctx.partitionExpr != null) { + functionCall = (FunctionCall)visit(ctx.partitionExpr); + ExpressionPartitionBy expressionPartitionBy = new ExpressionPartitionBy( + columnDefines, functionCall, list + ); + return expressionPartitionBy; + } + return null; + } + + @Override + public Node visitPartitionDef(PartitionDefContext ctx) { + List list = null; + if (ctx.partitionProperties != null) { + list = ParserHelper.visit(this, ctx.partitionProperties.propertyItem(), Property.class); + } + //singleRange Partition + if (ctx.lessThanPartitionDef() != null) { + LessThanPartitionDefContext lessThanPartitionDefContext = ctx.lessThanPartitionDef(); + SingleRangePartition singleRangePartition = new SingleRangePartition( + (Identifier)visit(lessThanPartitionDefContext.partitionName), + lessThanPartitionDefContext.IF() != null, + (PartitionKey)visit(lessThanPartitionDefContext), + list + ); + return singleRangePartition; + } + + //singleRange Partition + FixedPartitionDefContext fixedPartitionDefContext = ctx.fixedPartitionDef(); + if (fixedPartitionDefContext != null) { + SingleRangePartition singleRangePartition = new SingleRangePartition( + (Identifier)visit(fixedPartitionDefContext.partitionName), + fixedPartitionDefContext.IF() != null, + (PartitionKey)visit(ctx.fixedPartitionDef()), + list + ); + return singleRangePartition; + } + + return super.visitPartitionDef(ctx); + } + + @Override + public Node visitLessThanPartitionDef(LessThanPartitionDefContext ctx) { + ListPartitionValue visit = (ListPartitionValue)visit(ctx.constantSeq()); + return new LessThanPartitionKey( + ctx.MAXVALUE() != null, + visit + ); + } + + @Override + public Node visitFixedPartitionDef(FixedPartitionDefContext ctx) { + ListPartitionValue lower = (ListPartitionValue)visit(ctx.lower); + ListPartitionValue upper = (ListPartitionValue)visit(ctx.upper); + return new ArrayPartitionKey(Lists.newArrayList(lower, upper)); + } + + @Override + public Node visitConstantSeq(ConstantSeqContext ctx) { + List valueList = ParserHelper.visit(this, + ctx.values, PartitionValue.class); + return new ListPartitionValue( + valueList + ); + } + + @Override + public Node visitPartitionValueDef(PartitionValueDefContext ctx) { + + BaseExpression baseExpression = null; + if (ctx.INTEGER_VALUE() != null) { + baseExpression = new LongLiteral(ctx.INTEGER_VALUE().getText()); + } + if (ctx.STRING_LITERAL() != null) { + String v = StripUtils.strip(ctx.STRING_LITERAL().getText()); + baseExpression = new StringLiteral(v); + } + boolean maxValue = false; + if (ctx.MAXVALUE() != null) { + maxValue = true; + } + PartitionValue partitionValue = new PartitionValue( + maxValue, baseExpression + ); + return partitionValue; + } + + @Override + public Node visitNullLiteral(NullLiteralContext ctx) { + return new NullLiteral(); + } + + @Override + public Node visitBooleanLiteral(BooleanLiteralContext ctx) { + String value = ctx.booleanValue().getText(); + return new BooleanLiteral(ParserHelper.getLocation(ctx), ParserHelper.getOrigin(ctx), value); + } + + @Override + public Node visitStringLiteral(StringLiteralContext ctx) { + String value = StripUtils.strip(ctx.STRING_LITERAL().getText()); + return new StringLiteral(ParserHelper.getLocation(ctx), ParserHelper.getOrigin(ctx), value); + } + + @Override + public Node visitIntegerLiteral(IntegerLiteralContext ctx) { + String value = ctx.INTEGER_VALUE().getText(); + if (ctx.SUBTRACT() != null) { + value = "-" + value; + } + return new LongLiteral(ParserHelper.getLocation(ctx), ParserHelper.getOrigin(ctx), value); + } + + @Override + public Node visitDecimalLiteral(DecimalLiteralContext ctx) { + String number = null; + if (ctx.DECIMAL_VALUE() != null) { + number = ctx.DECIMAL_VALUE().getText(); + } else if (ctx.EXPONENT_VALUE() != null) { + number = ctx.EXPONENT_VALUE().getText(); + } + if (ctx.SUBTRACT() != null) { + number = "-" + number; + } + return new DecimalLiteral(ParserHelper.getLocation(ctx), ParserHelper.getOrigin(ctx), number); + } + + @Override + public Node visitStepPartitionDef(StepPartitionDefContext ctx) { + ListPartitionValue fromPartitionValue = (ListPartitionValue)visit(ctx.from); + ListPartitionValue toPartitionValue = (ListPartitionValue)visit(ctx.to); + LongLiteral longLiteral = new LongLiteral(ctx.unitsAmount.getText()); + DateTimeEnum timeEnum = null; + if (ctx.datetimeUnit() != null) { + timeEnum = DateTimeEnum.getByCode(ctx.datetimeUnit().getText()); + } + IntervalLiteral intervalLiteral = new IntervalLiteral( + longLiteral, timeEnum + ); + return new MultiRangePartition(fromPartitionValue, toPartitionValue, intervalLiteral, null); + } + + @Override + public Node visitInPartitionDef(InPartitionDefContext ctx) { + return super.visitInPartitionDef(ctx); + } + + private DuplicateKeyConstraint getDuplicateKeyConstraint(CreateTableContext ctx) { + List list = ParserHelper.visit(this, ctx.keys.identifierSeq().ident, Identifier.class); + DuplicateKeyConstraint duplicateKeyConstraint = new DuplicateKeyConstraint( + IdentifierUtil.sysIdentifier(), + list + ); + return duplicateKeyConstraint; + } + + private UniqueConstraint getUniqueConstraint(CreateTableContext ctx) { + List list = ParserHelper.visit(this, ctx.keys.identifierSeq().ident, Identifier.class); + UniqueConstraint uniqueConstraint = new UniqueConstraint( + IdentifierUtil.sysIdentifier(), + list + ); + return uniqueConstraint; + } + + private AggregateKeyConstraint getAggregateKeyConstraint(CreateTableContext ctx) { + List list = ParserHelper.visit(this, ctx.keys.identifierSeq().ident, Identifier.class); + AggregateKeyConstraint aggregateKeyConstraint = new AggregateKeyConstraint( + IdentifierUtil.sysIdentifier(), + list + ); + return aggregateKeyConstraint; + } + + private ClusterKeyConstraint getClusterByConstraint(CreateTableContext ctx) { + IdentifierListContext clusterKeys = ctx.clusterKeys; + List list = ParserHelper.visit(this, ctx.clusterKeys.identifierSeq().ident, Identifier.class); + ClusterKeyConstraint clusterByConstraint = new ClusterKeyConstraint(list); + return clusterByConstraint; + } + + private DistributeConstraint getDistributeKeyConstraint(CreateTableContext ctx) { + IdentifierListContext hashKeys = ctx.hashKeys; + List identifiers = ParserHelper.visit(this, hashKeys.identifierSeq().ident, Identifier.class); + Boolean random = ctx.RANDOM() != null; + Integer bucket = null; + if (ctx.INTEGER_VALUE() != null) { + bucket = Integer.parseInt(ctx.INTEGER_VALUE().getText()); + } + DistributeConstraint distributeKeyConstraint = new DistributeConstraint( + identifiers, random, bucket + ); + return distributeKeyConstraint; + } + + private Property getEngineProp(IdentifierContext engine) { + return new Property(TABLE_ENGINE.getValue(), + engine.getText()); + } + + @Override + public Node visitColumnDef(ColumnDefContext ctx) { + ColumnDefinition columnDefinition = ColumnDefinition.builder() + .colName((Identifier)visit(ctx.colName)) + .dataType((BaseDataType)visit(ctx.type)) + .defaultValue(getDefaultValue(ctx)) + .comment(getColComment(ctx)) + .notNull(getNotNull(ctx)) + .properties(getProperties(ctx)) + .build(); + return columnDefinition; + } + + private List getProperties(ColumnDefContext ctx) { + List properties = Lists.newArrayList(); + + if (ctx.aggType != null) { + Property property = new Property(COLUMN_AGG_DESC.getValue(), ctx.aggType.getText()); + properties.add(property); + } + if (ctx.KEY() != null) { + Property property = new Property(COLUMN_KEY.getValue(), "KEY"); + properties.add(property); + } + + if (ctx.AUTO_INCREMENT() != null) { + Property property = new Property(COLUMN_AUTO_INCREMENT.getValue(), BooleanUtils.toStringTrueFalse(true)); + properties.add(property); + } + + if (ctx.ON() != null && ctx.UPDATE() != null) { + String value = CurrentTimestamp.CURRENT_TIMESTAMP; + if (ctx.onUpdateValuePrecision != null) { + value = value + "(" + ctx.onUpdateValuePrecision.getText() + ")"; + } + Property property = new Property(DorisPropertyKey.COLUMN_ON_UPDATE_CURRENT_TIMESTAMP.getValue(), value); + properties.add(property); + } + + return properties; + } + + private Comment getColComment(ColumnDefContext ctx) { + if (ctx.comment == null) { + return null; + } + String comment = StripUtils.strip(ctx.comment.getText()); + return new Comment(comment); + } + + private Boolean getNotNull(ColumnDefContext ctx) { + if (ctx.NOT() != null && ctx.NULL() != null) { + return true; + } + if (ctx.NULL() != null) { + return false; + } + return null; + } + + private BaseExpression getDefaultValue(ColumnDefContext ctx) { + if (ctx.DEFAULT() == null) { + return null; + } + if (ctx.nullValue != null) { + return new NullLiteral(); + } + if (ctx.INTEGER_VALUE() != null) { + return new LongLiteral(ctx.INTEGER_VALUE().getText()); + } + if (ctx.stringValue != null) { + String v = StripUtils.strip(ctx.stringValue.getText()); + return new StringLiteral(v); + } + if (ctx.CURRENT_TIMESTAMP() != null && ctx.ON() == null) { + //TODO 需要支持函数中含有数字的方式 + return new CurrentTimestamp(); + } + return null; + } + + @Override + public Node visitComplexDataType(ComplexDataTypeContext ctx) { + if (ctx.ARRAY() != null) { + List argument = Lists.newArrayList(); + DataTypeContext dataTypeContext = ctx.dataType(0); + BaseDataType baseDataType = (BaseDataType)visit(dataTypeContext); + argument.add(new TypeParameter(baseDataType)); + return new DorisGenericDataType(DorisDataTypeName.ARRAY.getValue(), argument); + } + if (ctx.MAP() != null) { + List typeParameters = ctx.dataType().stream().map( + d -> { + BaseDataType baseDataType = (BaseDataType)visit(d); + return new TypeParameter(baseDataType); + } + ).collect(Collectors.toList()); + return new DorisGenericDataType(DorisDataTypeName.Map.getValue(), typeParameters); + } + + if (ctx.STRUCT() != null) { + List list = ParserHelper.visit(this, ctx.complexColTypeList().complexColType(), Field.class); + return new RowDataType(getLocation(ctx), getOrigin(ctx), list); + } + return super.visitComplexDataType(ctx); + } + + @Override + public Node visitComplexColType(ComplexColTypeContext ctx) { + Identifier identifier = (Identifier)visit(ctx.identifier()); + BaseDataType dataType = (BaseDataType)visit(ctx.dataType()); + Comment comment = visitIfPresent(this, ctx.commentSpec(), Comment.class).orElse(null); + Field field = new Field(identifier, dataType, comment); + return field; + } + + @Override + public Node visitCommentSpec(CommentSpecContext ctx) { + String strip = StripUtils.strip(ctx.STRING_LITERAL().getText()); + return new Comment(strip); + } + + @Override + public Node visitPrimitiveDataType(PrimitiveDataTypeContext ctx) { + PrimitiveColTypeContext primitiveColTypeContext = ctx.primitiveColType(); + String text = primitiveColTypeContext.type.getText(); + IDataTypeName dorisDataTypeName = null; + if (primitiveColTypeContext.SIGNED() != null) { + dorisDataTypeName = DorisDataTypeName.getByValue("SIGNED " + text); + } else if (primitiveColTypeContext.UNSIGNED() != null) { + dorisDataTypeName = DorisDataTypeName.getByValue("UNSIGNED " + text); + } else { + dorisDataTypeName = DorisDataTypeName.getByValue(text); + } + //类型参数 + List typeParameters = Lists.newArrayList(); + if (ctx.LEFT_PAREN() != null && ctx.RIGHT_PAREN() != null) { + if (!ctx.INTEGER_VALUE().isEmpty()) { + typeParameters = ctx.INTEGER_VALUE().stream().map(i -> { + DataTypeParameter dataTypeParameter = new NumericParameter(i.getText()); + return dataTypeParameter; + }).collect(Collectors.toList()); + } + } + DorisGenericDataType dorisGenericDataType = new DorisGenericDataType( + ParserHelper.getLocation(ctx), + ParserHelper.getOrigin(ctx), + dorisDataTypeName.getValue(), + typeParameters + ); + return dorisGenericDataType; + } + + @Override + public Node visitMultipartIdentifier(MultipartIdentifierContext ctx) { + List list = ParserHelper.visit(this, + ctx.parts, Identifier.class); + return QualifiedName.of(list); + } + + @Override + public Node visitErrorCapturingIdentifier(ErrorCapturingIdentifierContext ctx) { + return ParserHelper.getIdentifier(ctx); + } + + @Override + public Node visitIdentifier(IdentifierContext ctx) { + return ParserHelper.getIdentifier(ctx); + } + + @Override + public Node visitPropertyItem(PropertyItemContext ctx) { + PropertyKeyContext key = ctx.key; + String keyString = null; + String valueString = null; + if (key.constant() != null) { + keyString = StripUtils.strip(key.constant().getText()); + } else if (key.identifier() != null) { + Identifier identifier = (Identifier)visit(key.identifier()); + keyString = identifier.getValue(); + } + PropertyValueContext value = ctx.value; + if (value.constant() != null) { + valueString = StripUtils.strip(value.constant().getText()); + } else if (value.identifier() != null) { + Identifier identifier = (Identifier)visit(value.identifier()); + valueString = identifier.getValue(); + } + return new Property(keyString, valueString); + } +} diff --git a/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/parser/visitor/DorisAstVisitor.java b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/parser/visitor/DorisAstVisitor.java new file mode 100644 index 0000000..ed63750 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/main/java/com/aliyun/fastmodel/transform/doris/parser/visitor/DorisAstVisitor.java @@ -0,0 +1,16 @@ +package com.aliyun.fastmodel.transform.doris.parser.visitor; + +import com.aliyun.fastmodel.transform.api.extension.visitor.ExtensionAstVisitor; +import com.aliyun.fastmodel.transform.doris.parser.tree.DorisGenericDataType; + +/** + * Desc: + * + * @author panguanjing + * @date 2024/1/20 + */ +public interface DorisAstVisitor extends ExtensionAstVisitor { + default R visitDorisGenericDataType(DorisGenericDataType dorisGenericDataType, C context) { + return visitGenericDataType(dorisGenericDataType, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-doris/src/test/java/com/aliyun/fastmodel/transform/doris/DorisTransformerTest.java b/fastmodel-transform/fastmodel-transform-doris/src/test/java/com/aliyun/fastmodel/transform/doris/DorisTransformerTest.java new file mode 100644 index 0000000..f013d8e --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/test/java/com/aliyun/fastmodel/transform/doris/DorisTransformerTest.java @@ -0,0 +1,158 @@ +package com.aliyun.fastmodel.transform.doris; + +import java.nio.charset.Charset; +import java.util.List; + +import com.aliyun.fastmodel.core.tree.BaseStatement; +import com.aliyun.fastmodel.core.tree.Node; +import com.aliyun.fastmodel.core.tree.Property; +import com.aliyun.fastmodel.core.tree.QualifiedName; +import com.aliyun.fastmodel.core.tree.expr.Identifier; +import com.aliyun.fastmodel.core.tree.statement.table.ColumnDefinition; +import com.aliyun.fastmodel.core.tree.statement.table.CreateTable; +import com.aliyun.fastmodel.core.tree.util.DataTypeUtil; +import com.aliyun.fastmodel.transform.api.client.dto.table.Column; +import com.aliyun.fastmodel.transform.api.client.dto.table.Table; +import com.aliyun.fastmodel.transform.api.context.ReverseContext; +import com.aliyun.fastmodel.transform.api.context.TransformContext; +import com.aliyun.fastmodel.transform.api.dialect.DialectNode; +import com.google.common.collect.Lists; +import lombok.SneakyThrows; +import org.apache.commons.io.IOUtils; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +/** + * DorisTransformerTest + * + * @author panguanjing + * @date 2024/1/20 + */ +public class DorisTransformerTest { + + DorisTransformer dorisTransformer = new DorisTransformer(); + + @Test + public void reverse() { + DialectNode dialectNode = new DialectNode("create table d_1 (a int);"); + ReverseContext context = ReverseContext.builder().merge(true).build(); + BaseStatement reverse = dorisTransformer.reverse(dialectNode, context); + assertNotNull(reverse); + } + + @Test + @SneakyThrows + public void testReverseRange() { + String rangeContent = IOUtils.resourceToString("/doris/range.txt", Charset.defaultCharset()); + DialectNode dialectNode = new DialectNode(rangeContent); + BaseStatement reverse = dorisTransformer.reverse(dialectNode); + assertNotNull(reverse); + CreateTable createTable = (CreateTable)reverse; + List columnDefines = createTable.getColumnDefines(); + assertEquals(10, columnDefines.size()); + } + + @Test + @SneakyThrows + public void transform() { + String rangeContent = IOUtils.resourceToString("/doris/range.txt", Charset.defaultCharset()); + DialectNode dialectNode = new DialectNode(rangeContent); + BaseStatement reverse = dorisTransformer.reverse(dialectNode); + assertNotNull(reverse); + DialectNode transform = dorisTransformer.transform(reverse); + assertEquals("CREATE TABLE example_db.example_range_tbl\n" + + "(\n" + + " `user_id` LARGEINT NOT NULL COMMENT \"User ID\",\n" + + " `date` DATE NOT NULL COMMENT \"Date when the data are imported\",\n" + + " `timestamp` DATETIME NOT NULL COMMENT \"Timestamp when the data are imported\",\n" + + " `city` VARCHAR(20) NULL COMMENT \"User location city\",\n" + + " `age` SMALLINT NULL COMMENT \"User age\",\n" + + " `sex` TINYINT NULL COMMENT \"User gender\",\n" + + " `last_visit_date` DATETIME REPLACE NULL DEFAULT \"1970-01-01 00:00:00\" COMMENT \"User last visit time\",\n" + + " `cost` BIGINT SUM NULL DEFAULT \"0\" COMMENT \"Total user consumption\",\n" + + " `max_dwell_time` INT MAX NULL DEFAULT \"0\" COMMENT \"Maximum user dwell time\",\n" + + " `min_dwell_time` INT MIN NULL DEFAULT \"99999\" COMMENT \"Minimum user dwell time\"\n" + + ")\n" + + "ENGINE=olap\n" + + "AGGREGATE KEY (`user_id`,`date`,`timestamp`,`city`,`age`,`sex`)\n" + + "PARTITION BY RANGE (`date`)\n" + + "(\n" + + " PARTITION `p201701` VALUES LESS THAN (\"2017-02-01\"),\n" + + " PARTITION `p201702` VALUES LESS THAN (\"2017-03-01\"),\n" + + " PARTITION `p201703` VALUES LESS THAN (\"2017-04-01\")\n" + + ")\n" + + "DISTRIBUTED BY HASH(`user_id`) BUCKETS 16\n" + + "PROPERTIES (\"replication_num\"=\"3\",\"storage_medium\"=\"SSD\",\"storage_cooldown_time\"=\"2018-01-01 12:00:00\");", + transform.getNode()); + } + + @Test + @SneakyThrows + public void reverseWithProperty() { + String table = IOUtils.resourceToString("/doris/property.txt", Charset.defaultCharset()); + DialectNode dialectNode = new DialectNode(table); + CreateTable reverse = (CreateTable)dorisTransformer.reverse(dialectNode); + List properties = reverse.getProperties(); + assertTrue(properties.size() > 0); + DialectNode transform = dorisTransformer.transform(reverse); + assertEquals("CREATE TABLE `t_yunshi_holo_binlog_2_020601`\n" + + "(\n" + + " `id` BIGINT(20) NOT NULL,\n" + + " `col1` TEXT NULL,\n" + + " `col2` TEXT NULL,\n" + + " `col3` TEXT NULL\n" + + ")\n" + + "ENGINE=OLAP\n" + + "UNIQUE KEY (`id`)\n" + + "COMMENT \"Auto created by DataWorks Data Integration\"\n" + + "DISTRIBUTED BY HASH(`id`) BUCKETS 4\n" + + "PROPERTIES (\"replication_allocation\"=\"tag.location.default: 1\",\"in_memory\"=\"false\",\"storage_format\"=\"V2\"," + + "\"light_schema_change\"=\"true\",\"disable_auto_compaction\"=\"false\");", + transform.getNode()); + } + + @Test + @SneakyThrows + public void reverseTable() { + List columns = Lists.newArrayList(); + Column e = Column.builder() + .name("c1") + .comment("comment") + .dataType("bigint") + .build(); + columns.add(e); + Table table = Table.builder() + .name("t1") + .columns(columns) + .build(); + Node node = dorisTransformer.reverseTable(table); + DialectNode transform = dorisTransformer.transform((BaseStatement)node); + assertEquals("CREATE TABLE IF NOT EXISTS t1\n" + + "(\n" + + " c1 BIGINT NOT NULL COMMENT \"comment\"\n" + + ");", transform.getNode()); + + } + + @Test + public void transformTable() { + List columns = Lists.newArrayList(); + ColumnDefinition e = ColumnDefinition.builder() + .colName(new Identifier("c1")) + .dataType(DataTypeUtil.simpleType("bigint", null)) + .build(); + columns.add(e); + Node table = CreateTable.builder() + .tableName(QualifiedName.of("t1")) + .columns(columns) + .build(); + Table table1 = dorisTransformer.transformTable(table, TransformContext.builder().build()); + assertEquals("t1", table1.getName()); + List columns1 = table1.getColumns(); + assertEquals(1, columns1.size()); + } + +} \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-doris/src/test/java/com/aliyun/fastmodel/transform/doris/client/DorisClientConverterTest.java b/fastmodel-transform/fastmodel-transform-doris/src/test/java/com/aliyun/fastmodel/transform/doris/client/DorisClientConverterTest.java new file mode 100644 index 0000000..b115e55 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/test/java/com/aliyun/fastmodel/transform/doris/client/DorisClientConverterTest.java @@ -0,0 +1,85 @@ +package com.aliyun.fastmodel.transform.doris.client; + +import java.util.ArrayList; +import java.util.List; + +import com.aliyun.fastmodel.core.parser.LanguageParser; +import com.aliyun.fastmodel.core.tree.datatype.IDataTypeName; +import com.aliyun.fastmodel.core.tree.expr.BaseExpression; +import com.aliyun.fastmodel.core.tree.expr.Identifier; +import com.aliyun.fastmodel.core.tree.expr.literal.StringLiteral; +import com.aliyun.fastmodel.core.tree.statement.table.ColumnDefinition; +import com.aliyun.fastmodel.core.tree.statement.table.PartitionedBy; +import com.aliyun.fastmodel.core.tree.util.DataTypeUtil; +import com.aliyun.fastmodel.transform.api.client.PropertyConverter; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.RangePartitionedBy; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.PartitionDesc; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.SingleRangePartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.ListPartitionValue; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.PartitionValue; +import com.google.common.collect.Lists; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * DorisClientConverterTest + * + * @author panguanjing + * @date 2024/2/21 + */ +public class DorisClientConverterTest { + + DorisClientConverter dorisClientConverter = new DorisClientConverter(); + + @Test + public void getDataTypeName() { + IDataTypeName bigint = dorisClientConverter.getDataTypeName("bigint"); + assertNotNull(bigint); + } + + @Test + public void getLanguageParser() { + LanguageParser languageParser = dorisClientConverter.getLanguageParser(); + assertNotNull(languageParser); + } + + @Test + public void getRaw() { + List columns = Lists.newArrayList(); + columns.add(ColumnDefinition.builder().colName(new Identifier("c1")).dataType(DataTypeUtil.simpleType("bigint", null)).build()); + ArrayList rangePartitions = Lists.newArrayList(); + SingleRangePartition singleRangePartition = new SingleRangePartition( + new Identifier("a"), + false, + null, null + ); + rangePartitions.add(singleRangePartition); + PartitionedBy partitionedBy = new RangePartitionedBy(columns, rangePartitions); + String raw = dorisClientConverter.getRaw(partitionedBy); + assertEquals("PARTITION BY RANGE (c1)\n" + + "(\n" + + " PARTITION a VALUES \n" + + ")", raw); + } + + @Test + public void getRawListPartitionValue() { + BaseExpression stringLiteral = new StringLiteral("abc"); + List partitonValueList = Lists.newArrayList( + new PartitionValue(false, stringLiteral) + ); + ListPartitionValue listPartitionValue = new ListPartitionValue( + partitonValueList + ); + String raw = dorisClientConverter.getRaw(listPartitionValue); + assertEquals("\"abc\"", raw); + } + + @Test + public void getPropertyConverter() { + PropertyConverter propertyConverter = dorisClientConverter.getPropertyConverter(); + assertNotNull(propertyConverter); + } +} \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-doris/src/test/java/com/aliyun/fastmodel/transform/doris/client/DorisGenerator2Test.java b/fastmodel-transform/fastmodel-transform-doris/src/test/java/com/aliyun/fastmodel/transform/doris/client/DorisGenerator2Test.java new file mode 100644 index 0000000..c282f0e --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/test/java/com/aliyun/fastmodel/transform/doris/client/DorisGenerator2Test.java @@ -0,0 +1,921 @@ +package com.aliyun.fastmodel.transform.doris.client; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import com.aliyun.fastmodel.core.tree.expr.enums.DateTimeEnum; +import com.aliyun.fastmodel.core.tree.statement.table.CreateTable; +import com.aliyun.fastmodel.transform.api.client.CodeGenerator; +import com.aliyun.fastmodel.transform.api.client.dto.constraint.Constraint; +import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; +import com.aliyun.fastmodel.transform.api.client.dto.property.StringProperty; +import com.aliyun.fastmodel.transform.api.client.dto.request.DdlGeneratorModelRequest; +import com.aliyun.fastmodel.transform.api.client.dto.result.DdlGeneratorResult; +import com.aliyun.fastmodel.transform.api.client.dto.table.Column; +import com.aliyun.fastmodel.transform.api.client.dto.table.Table; +import com.aliyun.fastmodel.transform.api.client.dto.table.TableConfig; +import com.aliyun.fastmodel.transform.api.client.generator.DefaultCodeGenerator; +import com.aliyun.fastmodel.transform.api.dialect.DialectMeta; +import com.aliyun.fastmodel.transform.api.dialect.DialectNode; +import com.aliyun.fastmodel.transform.api.extension.client.constraint.ClientConstraintType; +import com.aliyun.fastmodel.transform.api.extension.client.constraint.DistributeClientConstraint; +import com.aliyun.fastmodel.transform.api.extension.client.property.column.AggrColumnProperty; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.MultiRangePartitionProperty; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.ReplicationNum; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.SingleRangePartitionProperty; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.TablePartitionRaw; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.ArrayClientPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.LessThanClientPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.MultiRangeClientPartition; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.PartitionClientValue; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.SingleRangeClientPartition; +import com.aliyun.fastmodel.transform.api.extension.tree.column.AggregateDesc; +import com.aliyun.fastmodel.transform.doris.parser.DorisLanguageParser; +import com.google.common.collect.Lists; +import org.junit.Test; + +import static com.aliyun.fastmodel.core.tree.expr.literal.CurrentTimestamp.CURRENT_TIMESTAMP; +import static com.aliyun.fastmodel.transform.doris.parser.tree.DorisDataTypeName.DATETIME; +import static com.aliyun.fastmodel.transform.doris.parser.tree.DorisDataTypeName.FLOAT; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * ddl generator test + * + * @author panguanjing + * @date 2023/9/17 + */ +public class DorisGenerator2Test { + CodeGenerator codeGenerator = new DefaultCodeGenerator(); + + DorisLanguageParser dorisLanguageParser = new DorisLanguageParser(); + + /** + * 通过string property传入 + */ + @Test + public void testGeneratorProperties1() { + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + List columns = Lists.newArrayList(); + columns.add(Column.builder() + .dataType("decimal") + .precision(10) + .scale(4) + .name("c1") + .nullable(true) + .build()); + + List properties = Lists.newArrayList(); + StringProperty stringProperty = new StringProperty(); + stringProperty.setKey("replication_num"); + stringProperty.setValueString("3"); + properties.add(stringProperty); + Table after = Table.builder() + .database("autotest") + .name("abc") + .columns(columns) + .comment("comment") + .properties(properties) + .build(); + request.setAfter(after); + DdlGeneratorResult generate = getDdlGeneratorResult(request); + List dialectNodes = generate.getDialectNodes().stream() + .filter(DialectNode::getExecutable) + .collect(Collectors.toList()); + assertEquals("CREATE TABLE IF NOT EXISTS autotest.abc\n" + + "(\n" + + " c1 DECIMAL(10,4) NULL\n" + + ")\n" + + "COMMENT \"comment\"\n" + + "PROPERTIES (\"replication_num\"=\"3\");", dialectNodes.stream().map(DialectNode::getNode).collect(Collectors.joining("\n"))); + } + + /** + * 通过固定的property传入 + */ + @Test + public void testGeneratorProperties2() { + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + List columns = Lists.newArrayList(); + columns.add(Column.builder() + .dataType("decimal") + .precision(10) + .scale(4) + .name("c1") + .nullable(true) + .build()); + + List properties = Lists.newArrayList(); + ReplicationNum stringProperty = new ReplicationNum(); + stringProperty.setValueString("3"); + properties.add(stringProperty); + Table after = Table.builder() + .name("abc") + .columns(columns) + .comment("comment") + .properties(properties) + .build(); + request.setAfter(after); + DdlGeneratorResult generate = getDdlGeneratorResult(request); + List dialectNodes = generate.getDialectNodes().stream() + .filter(DialectNode::getExecutable) + .collect(Collectors.toList()); + assertEquals("CREATE TABLE IF NOT EXISTS abc\n" + + "(\n" + + " c1 DECIMAL(10,4) NULL\n" + + ")\n" + + "COMMENT \"comment\"\n" + + "PROPERTIES (\"replication_num\"=\"3\");", dialectNodes.stream().map(DialectNode::getNode).collect(Collectors.joining("\n"))); + } + + @Test + public void testGeneratorSupportDecimal() { + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + List columns = Lists.newArrayList(); + columns.add(Column.builder() + .dataType("decimal") + .precision(10) + .scale(4) + .name("c1") + .nullable(true) + .build()); + + Table after = Table.builder() + .name("abc") + .columns(columns) + .comment("comment") + .build(); + request.setAfter(after); + DdlGeneratorResult generate = getDdlGeneratorResult(request); + List dialectNodes = generate.getDialectNodes().stream() + .filter(DialectNode::getExecutable) + .collect(Collectors.toList()); + assertEquals("CREATE TABLE IF NOT EXISTS abc\n" + + "(\n" + + " c1 DECIMAL(10,4) NULL\n" + + ")\n" + + "COMMENT \"comment\";", dialectNodes.stream().map(DialectNode::getNode).collect(Collectors.joining("\n"))); + } + + @Test + public void testGeneratorSupportArrayInt() { + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + List columns = Lists.newArrayList(); + columns.add(Column.builder() + .dataType("array") + .name("c1") + .nullable(true) + .build()); + + Table after = Table.builder() + .name("abc") + .columns(columns) + .comment("comment") + .build(); + request.setAfter(after); + DdlGeneratorResult generate = getDdlGeneratorResult(request); + List dialectNodes = generate.getDialectNodes().stream() + .filter(DialectNode::getExecutable) + .collect(Collectors.toList()); + assertEquals("CREATE TABLE IF NOT EXISTS abc\n" + + "(\n" + + " c1 ARRAY NULL\n" + + ")\n" + + "COMMENT \"comment\";", dialectNodes.stream().map(DialectNode::getNode).collect(Collectors.joining("\n"))); + } + + @Test + public void testGeneratorSupportPartitionRaw() { + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + List columns = Lists.newArrayList(); + columns.add(Column.builder() + .dataType("int") + .name("c1") + .nullable(true) + .build()); + List properties = Lists.newArrayList(); + TablePartitionRaw e = new TablePartitionRaw(); + e.setValueString("PARTITION BY RANGE (pay_dt) (\n" + + " PARTITION p1 VALUES LESS THAN (\"20210102\"),\n" + + " PARTITION p2 VALUES LESS THAN (\"20210103\"),\n" + + " PARTITION p3 VALUES LESS THAN MAXVALUE\n" + + ")"); + properties.add(e); + + DistributeClientConstraint starRocksDistributeConstraint = new DistributeClientConstraint(); + starRocksDistributeConstraint.setColumns(Lists.newArrayList("c1")); + List list = Lists.newArrayList(starRocksDistributeConstraint); + + Table after = Table.builder() + .name("abc") + .columns(columns) + .comment("comment") + .properties(properties) + .constraints(list) + .build(); + request.setAfter(after); + DdlGeneratorResult generate = getDdlGeneratorResult(request); + List dialectNodes = generate.getDialectNodes().stream() + .filter(DialectNode::getExecutable) + .collect(Collectors.toList()); + assertEquals("CREATE TABLE IF NOT EXISTS abc\n" + + "(\n" + + " c1 INT NULL\n" + + ")\n" + + "COMMENT \"comment\"\n" + + "PARTITION BY RANGE (pay_dt) (\n" + + " PARTITION p1 VALUES LESS THAN (\"20210102\"),\n" + + " PARTITION p2 VALUES LESS THAN (\"20210103\"),\n" + + " PARTITION p3 VALUES LESS THAN MAXVALUE\n" + + ")\n" + + "DISTRIBUTED BY HASH(c1);", dialectNodes.stream().map(DialectNode::getNode).collect(Collectors.joining("\n"))); + } + + @Test + public void testGeneratorSupportDistribute() { + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + List columns = Lists.newArrayList(); + columns.add(Column.builder() + .dataType("int") + .name("c1") + .nullable(true) + .build()); + + DistributeClientConstraint starRocksDistributeConstraint = new DistributeClientConstraint(); + starRocksDistributeConstraint.setColumns(Lists.newArrayList("c1")); + starRocksDistributeConstraint.setBucket(1); + List list = Lists.newArrayList(starRocksDistributeConstraint); + + Table after = Table.builder() + .name("abc") + .columns(columns) + .comment("comment") + .constraints(list) + .build(); + request.setAfter(after); + DdlGeneratorResult generate = getDdlGeneratorResult(request); + List dialectNodes = generate.getDialectNodes().stream() + .filter(DialectNode::getExecutable) + .collect(Collectors.toList()); + assertEquals("CREATE TABLE IF NOT EXISTS abc\n" + + "(\n" + + " c1 INT NULL\n" + + ")\n" + + "COMMENT \"comment\"\n" + + "DISTRIBUTED BY HASH(c1) BUCKETS 1;", dialectNodes.stream().map(DialectNode::getNode).collect(Collectors.joining("\n"))); + } + + @Test + public void testGeneratorSingleRangePartitionProperty() { + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + List columns = Lists.newArrayList(); + columns.add(Column.builder() + .dataType("int") + .name("c1") + .nullable(true) + .build()); + + columns.add(Column.builder() + .dataType("int") + .name("c2") + .partitionKeyIndex(0) + .partitionKey(true) + .comment("comment") + .build()); + List properties = Lists.newArrayList(); + //first + SingleRangePartitionProperty e = new SingleRangePartitionProperty(); + SingleRangeClientPartition value = new SingleRangeClientPartition(); + value.setName("a1"); + value.setIfNotExists(true); + List> partitionValues = Lists.newArrayList(); + PartitionClientValue p1 = PartitionClientValue.builder() + .value("2021-01-01") + .build(); + partitionValues.add(Lists.newArrayList(p1)); + PartitionClientValue p2 = PartitionClientValue.builder() + .value("2022-01-02") + .build(); + PartitionClientValue p3 = PartitionClientValue.builder() + .maxValue(true) + .build(); + ; + partitionValues.add(Lists.newArrayList(p2, p3)); + ArrayClientPartitionKey partitionKey = ArrayClientPartitionKey.builder() + .partitionValue(partitionValues) + .build(); + value.setPartitionKey(partitionKey); + e.setValue(value); + properties.add(e); + + //second + //first + e = new SingleRangePartitionProperty(); + value = new SingleRangeClientPartition(); + value.setName("a2"); + value.setIfNotExists(false); + partitionValues = Lists.newArrayList(); + p1 = PartitionClientValue.builder() + .value("2021-01-01") + .build(); + partitionValues.add(Lists.newArrayList(p1)); + p2 = PartitionClientValue.builder() + .value("2022-01-02") + .build(); + p3 = PartitionClientValue.builder() + .maxValue(true) + .build(); + partitionValues.add(Lists.newArrayList(p2, p3)); + partitionKey = ArrayClientPartitionKey.builder() + .partitionValue(partitionValues) + .build(); + value.setPartitionKey(partitionKey); + e.setValue(value); + properties.add(e); + Table after = Table.builder() + .name("abc") + .columns(columns) + .comment("comment") + .properties(properties) + .build(); + request.setAfter(after); + DdlGeneratorResult generate = getDdlGeneratorResult(request); + List dialectNodes = generate.getDialectNodes(); + assertEquals("CREATE TABLE IF NOT EXISTS abc\n" + + "(\n" + + " c1 INT NULL,\n" + + " c2 INT NOT NULL COMMENT \"comment\"\n" + + ")\n" + + "COMMENT \"comment\"\n" + + "PARTITION BY RANGE (c2)\n" + + "(\n" + + " PARTITION IF NOT EXISTS a1 VALUES [(\"2021-01-01\"),(\"2022-01-02\",MAXVALUE)),\n" + + " PARTITION a2 VALUES [(\"2021-01-01\"),(\"2022-01-02\",MAXVALUE))\n" + + ");", dialectNodes.stream().map(DialectNode::getNode).collect(Collectors.joining("\n"))); + } + + @Test + public void testGeneratorSingleRangePartitionPropertyWithLessThan() { + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + List columns = Lists.newArrayList(); + columns.add(Column.builder() + .dataType("int") + .name("c1") + .nullable(true) + .build()); + + columns.add(Column.builder() + .dataType("int") + .name("c2") + .partitionKeyIndex(0) + .partitionKey(true) + .comment("comment") + .build()); + List properties = Lists.newArrayList(); + SingleRangePartitionProperty e = new SingleRangePartitionProperty(); + SingleRangeClientPartition value = new SingleRangeClientPartition(); + value.setName("a1"); + value.setIfNotExists(true); + LessThanClientPartitionKey partitionKey = LessThanClientPartitionKey.builder() + .maxValue(false) + .partitionValueList(Lists.newArrayList(PartitionClientValue.builder().value("2020-01-01").build(), + PartitionClientValue.builder().value("2021-02-03").build())) + .build(); + value.setPartitionKey(partitionKey); + e.setValue(value); + properties.add(e); + Table after = Table.builder() + .name("abc") + .columns(columns) + .comment("comment") + .properties(properties) + .build(); + request.setAfter(after); + DdlGeneratorResult generate = getDdlGeneratorResult(request); + List dialectNodes = generate.getDialectNodes(); + assertEquals("CREATE TABLE IF NOT EXISTS abc\n" + + "(\n" + + " c1 INT NULL,\n" + + " c2 INT NOT NULL COMMENT \"comment\"\n" + + ")\n" + + "COMMENT \"comment\"\n" + + "PARTITION BY RANGE (c2)\n" + + "(\n" + + " PARTITION IF NOT EXISTS a1 VALUES LESS THAN (\"2020-01-01\",\"2021-02-03\")\n" + + ");", dialectNodes.stream().map(DialectNode::getNode).collect(Collectors.joining("\n"))); + } + + private DdlGeneratorResult getDdlGeneratorResult(DdlGeneratorModelRequest request) { + request.setConfig(TableConfig.builder() + .dialectMeta(DialectMeta.DEFAULT_DORIS) + .build()); + return codeGenerator.generate(request); + } + + @Test + public void testGeneratorMultiRange() { + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + List columns = Lists.newArrayList(); + List columnProp = Lists.newArrayList(); + AggrColumnProperty aggrColumnProperty = new AggrColumnProperty(); + aggrColumnProperty.setValueString(AggregateDesc.MIN.name()); + columnProp.add(aggrColumnProperty); + + columns.add(Column.builder() + .dataType("int") + .name("c1") + .nullable(true) + .properties(columnProp) + .build()); + + columns.add(Column.builder() + .dataType("int") + .name("c2") + .partitionKeyIndex(0) + .partitionKey(true) + .comment("comment") + .build()); + List properties = Lists.newArrayList(); + SingleRangePartitionProperty e = new SingleRangePartitionProperty(); + SingleRangeClientPartition value = new SingleRangeClientPartition(); + value.setName("a1"); + value.setIfNotExists(true); + ArrayList strings = Lists.newArrayList(PartitionClientValue.builder().value("2001-01-01").build(), + PartitionClientValue.builder().value("2002-01-01").build()); + LessThanClientPartitionKey partitionKeyValue = LessThanClientPartitionKey.builder() + .partitionValueList(strings) + .build(); + value.setPartitionKey(partitionKeyValue); + e.setValue(value); + properties.add(e); + Table after = Table.builder() + .name("abc") + .columns(columns) + .comment("comment") + .properties(properties) + .build(); + request.setAfter(after); + DdlGeneratorResult generate = getDdlGeneratorResult(request); + List dialectNodes = generate.getDialectNodes(); + assertEquals("CREATE TABLE IF NOT EXISTS abc\n" + + "(\n" + + " c1 INT MIN NULL,\n" + + " c2 INT NOT NULL COMMENT \"comment\"\n" + + ")\n" + + "COMMENT \"comment\"\n" + + "PARTITION BY RANGE (c2)\n" + + "(\n" + + " PARTITION IF NOT EXISTS a1 VALUES LESS THAN (\"2001-01-01\",\"2002-01-01\")\n" + + ");", dialectNodes.stream().map(DialectNode::getNode).collect(Collectors.joining("\n"))); + } + + @Test + public void testGeneratorMultiRangeInterval() { + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + List columns = Lists.newArrayList(); + List columnProp = Lists.newArrayList(); + AggrColumnProperty aggrColumnProperty = new AggrColumnProperty(); + aggrColumnProperty.setValueString(AggregateDesc.MIN.name()); + columnProp.add(aggrColumnProperty); + + columns.add(Column.builder() + .dataType("int") + .name("c1") + .nullable(true) + .properties(columnProp) + .build()); + + columns.add(Column.builder() + .dataType("int") + .name("c2") + .partitionKeyIndex(0) + .partitionKey(true) + .comment("comment") + .build()); + List properties = Lists.newArrayList(); + MultiRangePartitionProperty e = new MultiRangePartitionProperty(); + MultiRangeClientPartition v = new MultiRangeClientPartition(); + v.setStart("2020-01-01"); + v.setEnd("2023-01-01"); + v.setDateTimeEnum(DateTimeEnum.DAY); + v.setInterval(1L); + e.setValue(v); + properties.add(e); + Table after = Table.builder() + .name("abc") + .columns(columns) + .comment("comment") + .properties(properties) + .build(); + request.setAfter(after); + DdlGeneratorResult generate = getDdlGeneratorResult(request); + List dialectNodes = generate.getDialectNodes(); + assertEquals("CREATE TABLE IF NOT EXISTS abc\n" + + "(\n" + + " c1 INT MIN NULL,\n" + + " c2 INT NOT NULL COMMENT \"comment\"\n" + + ")\n" + + "COMMENT \"comment\"\n" + + "PARTITION BY RANGE (c2)\n" + + "(\n" + + " FROM (\"2020-01-01\") TO (\"2023-01-01\") INTERVAL 1 DAY\n" + + ");", dialectNodes.stream().map(DialectNode::getNode).collect(Collectors.joining("\n"))); + } + + @Test + public void testKeyWords() { + List columns = Lists.newArrayList(); + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + columns.add(Column.builder() + .dataType("tinyint") + .name("add") + .nullable(false) + .primaryKey(true) + .comment("ti_comment") + .build()); + columns.add(Column.builder() + .dataType("smallint") + .name("c2") + .nullable(false) + .primaryKey(true) + .comment("si_comment") + .build()); + Table after = Table.builder() + .name("abc") + .columns(columns) + .comment("comment") + .build(); + request.setAfter(after); + DdlGeneratorResult generate = getDdlGeneratorResult(request); + List dialectNodes = generate.getDialectNodes(); + assertEquals(1, dialectNodes.size()); + assertEquals("CREATE TABLE IF NOT EXISTS abc\n" + + "(\n" + + " `add` TINYINT NOT NULL COMMENT \"ti_comment\",\n" + + " c2 SMALLINT NOT NULL COMMENT \"si_comment\"\n" + + ")\n" + + "PRIMARY KEY (`add`,c2)\n" + + "COMMENT \"comment\";", dialectNodes.get(0).getNode()); + } + + @Test + public void testGeneratorDistribute() { + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + List columns = Lists.newArrayList(); + columns.add(Column.builder() + .dataType("decimal") + .precision(10) + .scale(4) + .name("add") + .nullable(true) + .primaryKey(true) + .build()); + + List constraints = Lists.newArrayList(); + DistributeClientConstraint distributeConstraint = new DistributeClientConstraint(); + distributeConstraint.setBucket(1); + distributeConstraint.setColumns(Lists.newArrayList("add")); + constraints.add(distributeConstraint); + Table after = Table.builder() + .name("abc") + .columns(columns) + .comment("comment") + .constraints(constraints) + .build(); + request.setAfter(after); + DdlGeneratorResult generate = getDdlGeneratorResult(request); + List dialectNodes = generate.getDialectNodes().stream() + .filter(DialectNode::getExecutable) + .collect(Collectors.toList()); + assertEquals("CREATE TABLE IF NOT EXISTS abc\n" + + "(\n" + + " `add` DECIMAL(10,4) NULL\n" + + ")\n" + + "COMMENT \"comment\"\n" + + "DISTRIBUTED BY HASH(`add`) BUCKETS 1;", dialectNodes.stream().map(DialectNode::getNode).collect(Collectors.joining("\n"))); + } + + @Test + public void testGeneratorDistributeRandom() { + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + List columns = Lists.newArrayList(); + columns.add(Column.builder() + .dataType("decimal") + .precision(10) + .scale(4) + .name("add") + .nullable(true) + .primaryKey(true) + .build()); + + List constraints = Lists.newArrayList(); + DistributeClientConstraint distributeConstraint = new DistributeClientConstraint(); + distributeConstraint.setRandom(true); + constraints.add(distributeConstraint); + Table after = Table.builder() + .name("abc") + .columns(columns) + .comment("comment") + .constraints(constraints) + .build(); + request.setAfter(after); + DdlGeneratorResult generate = getDdlGeneratorResult(request); + List dialectNodes = generate.getDialectNodes().stream() + .filter(DialectNode::getExecutable) + .collect(Collectors.toList()); + assertEquals("CREATE TABLE IF NOT EXISTS abc\n" + + "(\n" + + " `add` DECIMAL(10,4) NULL\n" + + ")\n" + + "COMMENT \"comment\"\n" + + "DISTRIBUTED BY RANDOM;", dialectNodes.stream().map(DialectNode::getNode).collect(Collectors.joining("\n"))); + } + + @Test + public void testGeneratorCommentWithConverter() { + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + List columns = Lists.newArrayList(); + columns.add(Column.builder() + .dataType("decimal") + .precision(10) + .scale(4) + .name("add") + .primaryKey(true) + .build()); + + Table after = Table.builder() + .name("abc") + .columns(columns) + .comment("\"\"comment") + .build(); + + request.setAfter(after); + DdlGeneratorResult generate = getDdlGeneratorResult(request); + List dialectNodes = generate.getDialectNodes().stream() + .filter(DialectNode::getExecutable) + .collect(Collectors.toList()); + assertEquals("CREATE TABLE IF NOT EXISTS abc\n" + + "(\n" + + " `add` DECIMAL(10,4) NOT NULL\n" + + ")\n" + + "COMMENT \"\\\"\\\"comment\";", dialectNodes.stream().map(DialectNode::getNode).collect(Collectors.joining("\n"))); + } + + @Test + public void testGeneratorCommentWithSingleQuote() { + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + List columns = Lists.newArrayList(); + columns.add(Column.builder() + .dataType("decimal") + .precision(10) + .scale(4) + .name("add") + .nullable(true) + .primaryKey(true) + .build()); + + Table after = Table.builder() + .name("abc") + .columns(columns) + .comment("'\\comment'") + .build(); + + request.setAfter(after); + DdlGeneratorResult generate = getDdlGeneratorResult(request); + List dialectNodes = generate.getDialectNodes().stream() + .filter(DialectNode::getExecutable) + .collect(Collectors.toList()); + assertEquals("CREATE TABLE IF NOT EXISTS abc\n" + + "(\n" + + " `add` DECIMAL(10,4) NULL\n" + + ")\n" + + "COMMENT \"'\\\\comment'\";", dialectNodes.stream().map(DialectNode::getNode).collect(Collectors.joining("\n"))); + } + + @Test + public void testDuplicateKey() { + List columns = Lists.newArrayList(); + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + columns.add(Column.builder() + .dataType("tinyint") + .name("c1") + .nullable(false) + .comment("ti_comment") + .build()); + columns.add(Column.builder() + .dataType("smallint") + .name("c2") + .nullable(false) + .primaryKey(false) + .comment("si_comment") + .build()); + List constraints = Lists.newArrayList(); + ArrayList es = Lists.newArrayList("c1"); + Constraint constraint = Constraint.builder().name(null) + .columns(es) + .type(ClientConstraintType.DUPLICATE_KEY) + .build(); + constraints.add(constraint); + Table after = Table.builder() + .name("abc") + .columns(columns) + .comment("comment") + .constraints(constraints) + .build(); + request.setAfter(after); + DdlGeneratorResult generate = getDdlGeneratorResult(request); + List dialectNodes = generate.getDialectNodes(); + assertEquals(1, dialectNodes.size()); + assertEquals("CREATE TABLE IF NOT EXISTS abc\n" + + "(\n" + + " c1 TINYINT NOT NULL COMMENT \"ti_comment\",\n" + + " c2 SMALLINT NOT NULL COMMENT \"si_comment\"\n" + + ")\n" + + "DUPLICATE KEY (c1)\n" + + "COMMENT \"comment\";", dialectNodes.get(0).getNode()); + } + + @Test + public void testAggregateKey() { + List columns = Lists.newArrayList(); + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + columns.add(Column.builder() + .dataType("tinyint") + .name("c1") + .nullable(false) + .comment("ti_comment") + .build()); + columns.add(Column.builder() + .dataType("smallint") + .name("c2") + .nullable(false) + .primaryKey(false) + .comment("si_comment") + .build()); + List constraints = Lists.newArrayList(); + ArrayList strings = Lists.newArrayList("c1", "c2"); + Constraint constraint = Constraint.builder(). + columns(strings) + .type(ClientConstraintType.AGGREGATE_KEY) + .build(); + constraints.add(constraint); + Table after = Table.builder() + .name("abc") + .columns(columns) + .comment("comment") + .constraints(constraints) + .build(); + request.setAfter(after); + DdlGeneratorResult generate = getDdlGeneratorResult(request); + List dialectNodes = generate.getDialectNodes(); + assertEquals(1, dialectNodes.size()); + assertEquals("CREATE TABLE IF NOT EXISTS abc\n" + + "(\n" + + " c1 TINYINT NOT NULL COMMENT \"ti_comment\",\n" + + " c2 SMALLINT NOT NULL COMMENT \"si_comment\"\n" + + ")\n" + + "AGGREGATE KEY (c1,c2)\n" + + "COMMENT \"comment\";", dialectNodes.get(0).getNode()); + } + + @Test + public void testUniqueKey() { + List columns = Lists.newArrayList(); + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + columns.add(Column.builder() + .dataType("tinyint") + .name("c1") + .nullable(false) + .comment("ti_comment") + .build()); + columns.add(Column.builder() + .dataType("smallint") + .name("c2") + .nullable(false) + .primaryKey(false) + .comment("si_comment") + .build()); + List constraints = Lists.newArrayList(); + ArrayList strings = Lists.newArrayList("c1", "c2"); + Constraint constraint = Constraint.builder().columns(strings) + .type(ClientConstraintType.UNIQUE_KEY) + .build(); + constraints.add(constraint); + Table after = Table.builder() + .name("abc") + .columns(columns) + .comment("comment") + .constraints(constraints) + .build(); + request.setAfter(after); + DdlGeneratorResult generate = getDdlGeneratorResult(request); + List dialectNodes = generate.getDialectNodes(); + assertEquals(1, dialectNodes.size()); + assertEquals("CREATE TABLE IF NOT EXISTS abc\n" + + "(\n" + + " c1 TINYINT NOT NULL COMMENT \"ti_comment\",\n" + + " c2 SMALLINT NOT NULL COMMENT \"si_comment\"\n" + + ")\n" + + "UNIQUE KEY (c1,c2)\n" + + "COMMENT \"comment\";", dialectNodes.get(0).getNode()); + } + + @Test + public void testDefaultValue() { + List columns = Lists.newArrayList(); + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + columns.add(Column.builder() + .dataType("tinyint") + .name("c1") + .nullable(true) + .comment("ti_comment") + .defaultValue("0") + .build()); + columns.add(Column.builder() + .dataType("string") + .name("c2") + .nullable(false) + .primaryKey(false) + .comment("si_comment") + .defaultValue("default_value") + .build()); + + columns.add(Column.builder() + .dataType(DATETIME.getValue()) + .name("c3") + .nullable(false) + .primaryKey(false) + .comment("si_comment") + .defaultValue(CURRENT_TIMESTAMP) + .build()); + + columns.add(Column.builder() + .dataType("string") + .name("c4") + .nullable(false) + .primaryKey(false) + .comment("si_comment") + .defaultValue("NULL") + .build()); + + columns.add(Column.builder() + .dataType("string") + .name("c5") + .nullable(false) + .primaryKey(false) + .comment("si_comment2") + .defaultValue("test") + .build()); + + columns.add(Column.builder() + .dataType("double") + .name("c6") + .nullable(false) + .primaryKey(false) + .comment("si_comment2") + .defaultValue("3.14") + .build()); + + columns.add(Column.builder() + .dataType(FLOAT.getValue()) + .name("c7") + .nullable(false) + .primaryKey(false) + .comment("si_comment2") + .defaultValue("0.14") + .build()); + List constraints = Lists.newArrayList(); + Constraint constraint = Constraint.builder() + .columns(Lists.newArrayList("c1", "c2")) + .type(ClientConstraintType.UNIQUE_KEY) + .build(); + constraints.add(constraint); + Table after = Table.builder() + .name("abc") + .columns(columns) + .comment("comment") + .constraints(constraints) + .build(); + request.setAfter(after); + DdlGeneratorResult generate = getDdlGeneratorResult(request); + List dialectNodes = generate.getDialectNodes(); + assertEquals(1, dialectNodes.size()); + String node = dialectNodes.get(0).getNode(); + assertEquals("CREATE TABLE IF NOT EXISTS abc\n" + + "(\n" + + " c1 TINYINT NULL DEFAULT \"0\" COMMENT \"ti_comment\",\n" + + " c2 STRING NOT NULL DEFAULT \"default_value\" COMMENT \"si_comment\",\n" + + " c3 DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT \"si_comment\",\n" + + " c4 STRING NOT NULL DEFAULT NULL COMMENT \"si_comment\",\n" + + " c5 STRING NOT NULL DEFAULT \"test\" COMMENT \"si_comment2\",\n" + + " c6 DOUBLE NOT NULL DEFAULT \"3.14\" COMMENT \"si_comment2\",\n" + + " c7 FLOAT NOT NULL DEFAULT \"0.14\" COMMENT \"si_comment2\"\n" + + ")\n" + + "UNIQUE KEY (c1,c2)\n" + + "COMMENT \"comment\";", node); + CreateTable o = dorisLanguageParser.parseNode(node); + assertNotNull(o); + } +} diff --git a/fastmodel-transform/fastmodel-transform-doris/src/test/java/com/aliyun/fastmodel/transform/doris/client/DorisGeneratorAlterTest.java b/fastmodel-transform/fastmodel-transform-doris/src/test/java/com/aliyun/fastmodel/transform/doris/client/DorisGeneratorAlterTest.java new file mode 100644 index 0000000..d0e1364 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/test/java/com/aliyun/fastmodel/transform/doris/client/DorisGeneratorAlterTest.java @@ -0,0 +1,250 @@ +package com.aliyun.fastmodel.transform.doris.client; + +import java.util.List; +import java.util.stream.Collectors; + +import com.aliyun.fastmodel.transform.api.client.CodeGenerator; +import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; +import com.aliyun.fastmodel.transform.api.client.dto.property.StringProperty; +import com.aliyun.fastmodel.transform.api.client.dto.request.DdlGeneratorModelRequest; +import com.aliyun.fastmodel.transform.api.client.dto.result.DdlGeneratorResult; +import com.aliyun.fastmodel.transform.api.client.dto.table.Column; +import com.aliyun.fastmodel.transform.api.client.dto.table.Table; +import com.aliyun.fastmodel.transform.api.client.dto.table.TableConfig; +import com.aliyun.fastmodel.transform.api.client.generator.DefaultCodeGenerator; +import com.aliyun.fastmodel.transform.api.dialect.DialectMeta; +import com.aliyun.fastmodel.transform.api.dialect.DialectNode; +import com.google.common.collect.Lists; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * ddl generator test + * + * @author panguanjing + * @date 2023/9/17 + */ +public class DorisGeneratorAlterTest { + CodeGenerator codeGenerator = new DefaultCodeGenerator(); + + @Test + public void testGeneratorAddColumn() { + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + List oneColumns = Lists.newArrayList(); + Column e1 = Column.builder() + .dataType("int") + .name("c1") + .nullable(true) + .build(); + oneColumns.add(e1); + + List twoColumns = Lists.newArrayList(); + twoColumns.add(e1); + twoColumns.add(Column.builder() + .dataType("int") + .name("c2") + .comment("comment") + .build()); + Table after = Table.builder() + .database("autotest") + .name("abc") + .columns(twoColumns) + .comment("comment") + .build(); + request.setAfter(after); + Table before = Table.builder() + .database("autotest") + .name("abc") + .columns(oneColumns) + .comment("comment2") + .build(); + request.setBefore(before); + request.setConfig(getConfig()); + DdlGeneratorResult generate = codeGenerator.generate(request); + List dialectNodes = generate.getDialectNodes(); + assertEquals("ALTER TABLE autotest.abc ADD COLUMN\n" + + "(\n" + + " c2 INT NOT NULL COMMENT \"comment\"\n" + + ");\n" + + "ALTER TABLE autotest.abc SET COMMENT \"comment\"", + dialectNodes.stream().map(DialectNode::getNode).collect(Collectors.joining(";\n"))); + } + + private static TableConfig getConfig() { + return TableConfig.builder() + .dialectMeta(DialectMeta.DEFAULT_DORIS) + .build(); + } + + @Test + public void testGeneratorDropColumn() { + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + List beforeColumns = Lists.newArrayList(); + + beforeColumns.add(Column.builder() + .dataType("int") + .name("c1") + .nullable(false) + .build()); + + Column build = Column.builder() + .dataType("int") + .name("c2") + .partitionKeyIndex(0) + .partitionKey(true) + .comment("comment") + .build(); + beforeColumns.add(build); + + List afterColumns = Lists.newArrayList(); + afterColumns.add(build); + + Table before = Table.builder() + .database("autotest") + .name("abc") + .columns(beforeColumns) + .comment("comment1") + .build(); + + Table after = Table.builder() + .database("autotest") + .name("abc") + .columns(afterColumns) + .build(); + + request.setBefore(before); + request.setAfter(after); + request.setConfig(getConfig()); + DdlGeneratorResult generate = codeGenerator.generate(request); + List dialectNodes = generate.getDialectNodes(); + assertEquals("ALTER TABLE autotest.abc DROP COLUMN c1,\n" + + "ALTER TABLE autotest.abc SET COMMENT \"\"", dialectNodes.stream().filter(DialectNode::isExecutable).map(DialectNode::getNode) + .collect(Collectors.joining(",\n"))); + } + + @Test + public void testGeneratorModifyColumn() { + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + List beforeColumns = Lists.newArrayList(); + + beforeColumns.add(Column.builder() + .dataType("int") + .name("c1") + .nullable(false) + .build()); + + Column build = Column.builder() + .dataType("int") + .name("c1") + .comment("comment") + .nullable(true) + .build(); + + List afterColumns = Lists.newArrayList(); + afterColumns.add(build); + + Table before = Table.builder() + .database("autotest") + .name("abc") + .columns(beforeColumns) + .build(); + + Table after = Table.builder() + .database("autotest") + .name("abc") + .columns(afterColumns) + .build(); + + request.setBefore(before); + request.setAfter(after); + request.setConfig(getConfig()); + DdlGeneratorResult generate = codeGenerator.generate(request); + List dialectNodes = generate.getDialectNodes(); + assertEquals("ALTER TABLE autotest.abc MODIFY COLUMN c1 INT NULL COMMENT \"comment\"", dialectNodes.stream().filter(DialectNode::isExecutable) + .map(DialectNode::getNode) + .collect(Collectors.joining(",\n"))); + } + + @Test + public void testGeneratorSetProperties() { + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + List beforeColumns = Lists.newArrayList(); + + beforeColumns.add(Column.builder() + .dataType("int") + .name("c1") + .nullable(false) + .build()); + + StringProperty stringProperty = new StringProperty(); + stringProperty.setKey("default.replication_num"); + stringProperty.setValueString("2"); + List properties = Lists.newArrayList( + stringProperty + ); + Table before = Table.builder() + .database("autotest") + .name("abc") + .columns(beforeColumns) + .build(); + + Table after = Table.builder() + .database("autotest") + .name("abc") + .columns(beforeColumns) + .properties(properties) + .build(); + + request.setBefore(before); + request.setAfter(after); + request.setConfig(getConfig()); + DdlGeneratorResult generate = codeGenerator.generate(request); + List dialectNodes = generate.getDialectNodes(); + assertEquals("ALTER TABLE autotest.abc SET (\"default.replication_num\"=\"2\")", dialectNodes.stream().filter(DialectNode::isExecutable) + .map(DialectNode::getNode) + .collect(Collectors.joining(",\n"))); + + } + + @Test + public void testGeneratorUnSetProperties() { + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + List beforeColumns = Lists.newArrayList(); + + beforeColumns.add(Column.builder() + .dataType("int") + .name("c1") + .nullable(false) + .build()); + + StringProperty stringProperty = new StringProperty(); + stringProperty.setKey("default.replication_num"); + stringProperty.setValueString("2"); + List properties = Lists.newArrayList( + stringProperty + ); + Table before = Table.builder() + .database("autotest") + .name("abc") + .columns(beforeColumns) + .properties(properties) + .build(); + + Table after = Table.builder() + .database("autotest") + .name("abc") + .columns(beforeColumns) + .build(); + + request.setBefore(before); + request.setAfter(after); + request.setConfig(getConfig()); + DdlGeneratorResult generate = codeGenerator.generate(request); + List dialectNodes = generate.getDialectNodes(); + assertEquals("ALTER TABLE autotest.abc SET (\"default.replication_num\"=\"\")", dialectNodes.stream().filter(DialectNode::isExecutable) + .map(DialectNode::getNode) + .collect(Collectors.joining(",\n"))); + + } +} diff --git a/fastmodel-transform/fastmodel-transform-doris/src/test/java/com/aliyun/fastmodel/transform/doris/client/DorisGeneratorTest.java b/fastmodel-transform/fastmodel-transform-doris/src/test/java/com/aliyun/fastmodel/transform/doris/client/DorisGeneratorTest.java new file mode 100644 index 0000000..4537df9 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/test/java/com/aliyun/fastmodel/transform/doris/client/DorisGeneratorTest.java @@ -0,0 +1,188 @@ +package com.aliyun.fastmodel.transform.doris.client; + +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; + +import com.aliyun.fastmodel.transform.api.client.dto.constraint.Constraint; +import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; +import com.aliyun.fastmodel.transform.api.client.dto.property.StringProperty; +import com.aliyun.fastmodel.transform.api.client.dto.request.DdlGeneratorModelRequest; +import com.aliyun.fastmodel.transform.api.client.dto.request.DdlReverseSqlRequest; +import com.aliyun.fastmodel.transform.api.client.dto.result.DdlGeneratorResult; +import com.aliyun.fastmodel.transform.api.client.dto.result.DdlTableResult; +import com.aliyun.fastmodel.transform.api.client.dto.table.Column; +import com.aliyun.fastmodel.transform.api.client.dto.table.Table; +import com.aliyun.fastmodel.transform.api.client.dto.table.TableConfig; +import com.aliyun.fastmodel.transform.api.client.generator.DefaultCodeGenerator; +import com.aliyun.fastmodel.transform.api.dialect.DialectMeta; +import com.aliyun.fastmodel.transform.api.dialect.DialectNode; +import com.aliyun.fastmodel.transform.api.extension.client.constraint.ClientConstraintType; +import com.google.common.collect.Lists; +import lombok.SneakyThrows; +import org.apache.commons.io.IOUtils; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * doris generator test + * + * @author panguanjing + * @date 2024/1/21 + */ +public class DorisGeneratorTest { + + DefaultCodeGenerator defaultCodeGenerator = new DefaultCodeGenerator(); + + @Test + public void testGenerator() { + List columns = Lists.newArrayList(); + Column e = Column.builder() + .name("c1") + .dataType("int") + .comment("column_comment") + .nullable(false) + .build(); + columns.add(e); + Table table = Table.builder() + .name("t1") + .comment("comment") + .columns(columns) + .build(); + DdlGeneratorModelRequest request = DdlGeneratorModelRequest.builder() + .config(TableConfig.builder() + .dialectMeta(DialectMeta.DEFAULT_DORIS) + .build()) + .after(table) + .build(); + DdlGeneratorResult generate = defaultCodeGenerator.generate(request); + assertEquals("CREATE TABLE IF NOT EXISTS t1\n" + + "(\n" + + " c1 INT NOT NULL COMMENT \"column_comment\"\n" + + ")\n" + + "COMMENT \"comment\";", generate.getDialectNodes().get(0).getNode()); + } + + @Test + public void testGeneratorArrayInt() { + List columns = Lists.newArrayList(); + Column e = Column.builder() + .name("c1") + .dataType("array") + .comment("column_comment") + .nullable(false) + .build(); + columns.add(e); + Table table = Table.builder() + .name("t1") + .comment("comment") + .columns(columns) + .build(); + DdlGeneratorModelRequest request = DdlGeneratorModelRequest.builder() + .config(TableConfig.builder() + .dialectMeta(DialectMeta.DEFAULT_DORIS) + .build()) + .after(table) + .build(); + DdlGeneratorResult generate = defaultCodeGenerator.generate(request); + assertEquals("CREATE TABLE IF NOT EXISTS t1\n" + + "(\n" + + " c1 ARRAY NOT NULL COMMENT \"column_comment\"\n" + + ")\n" + + "COMMENT \"comment\";", generate.getDialectNodes().get(0).getNode()); + } + + @Test + public void testUniqueKey() { + List columns = Lists.newArrayList(); + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + columns.add(Column.builder() + .dataType("tinyint") + .name("c1") + .nullable(false) + .comment("ti_comment") + .build()); + columns.add(Column.builder() + .dataType("smallint") + .name("c2") + .nullable(false) + .primaryKey(false) + .comment("si_comment") + .build()); + List constraints = Lists.newArrayList(); + ArrayList strings = Lists.newArrayList("c1", "c2"); + Constraint constraint = Constraint.builder().columns(strings) + .type(ClientConstraintType.UNIQUE_KEY) + .build(); + constraints.add(constraint); + Table after = Table.builder() + .name("abc") + .columns(columns) + .comment("comment") + .constraints(constraints) + .build(); + request.setAfter(after); + DdlGeneratorResult generate = getDdlGeneratorResult(request); + List dialectNodes = generate.getDialectNodes(); + assertEquals(1, dialectNodes.size()); + assertEquals("CREATE TABLE IF NOT EXISTS abc\n" + + "(\n" + + " c1 TINYINT NOT NULL COMMENT \"ti_comment\",\n" + + " c2 SMALLINT NOT NULL COMMENT \"si_comment\"\n" + + ")\n" + + "UNIQUE KEY (c1,c2)\n" + + "COMMENT \"comment\";", dialectNodes.get(0).getNode()); + } + + @Test + public void testGeneratorWithProperty() { + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + List columns = Lists.newArrayList(); + columns.add(Column.builder() + .dataType("tinyint") + .name("c1") + .nullable(false) + .comment("ti_comment") + .build()); + List properties = Lists.newArrayList(); + StringProperty stringProperty = new StringProperty(); + stringProperty.setKey("replication_allocation"); + stringProperty.setValueString("tag.location.default: 1"); + properties.add(stringProperty); + Table after = Table.builder() + .name("abc") + .columns(columns) + .comment("comment") + .properties(properties) + .build(); + request.setAfter(after); + DdlGeneratorResult generate = getDdlGeneratorResult(request); + List dialectNodes = generate.getDialectNodes(); + assertEquals("CREATE TABLE IF NOT EXISTS abc\n" + + "(\n" + + " c1 TINYINT NOT NULL COMMENT \"ti_comment\"\n" + + ")\n" + + "COMMENT \"comment\"\n" + + "PROPERTIES (\"replication_allocation\"=\"tag.location.default: 1\");", dialectNodes.get(0).getNode()); + } + + @Test + @SneakyThrows + public void testReverse() { + String content = IOUtils.resourceToString("/doris/range_error.txt", Charset.defaultCharset()); + DdlReverseSqlRequest request = DdlReverseSqlRequest.builder() + .code(content) + .dialectMeta(DialectMeta.DEFAULT_DORIS) + .build(); + DdlTableResult reverse = defaultCodeGenerator.reverse(request); + assertEquals("fml_raw_partition", reverse.getTable().getName()); + } + + private DdlGeneratorResult getDdlGeneratorResult(DdlGeneratorModelRequest request) { + request.setConfig(TableConfig.builder() + .dialectMeta(DialectMeta.DEFAULT_DORIS) + .build()); + return defaultCodeGenerator.generate(request); + } +} diff --git a/fastmodel-transform/fastmodel-transform-doris/src/test/java/com/aliyun/fastmodel/transform/doris/format/DorisOutVisitorTest.java b/fastmodel-transform/fastmodel-transform-doris/src/test/java/com/aliyun/fastmodel/transform/doris/format/DorisOutVisitorTest.java new file mode 100644 index 0000000..958e344 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/test/java/com/aliyun/fastmodel/transform/doris/format/DorisOutVisitorTest.java @@ -0,0 +1,36 @@ +package com.aliyun.fastmodel.transform.doris.format; + +import com.aliyun.fastmodel.core.tree.expr.Identifier; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.DistributeConstraint; +import com.aliyun.fastmodel.transform.doris.context.DorisContext; +import com.google.common.collect.Lists; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * Desc: + * + * @author panguanjing + * @date 2024/1/21 + */ +public class DorisOutVisitorTest { + + DorisOutVisitor dorisOutVisitor = new DorisOutVisitor(DorisContext.builder().build()); + + @Test + public void testVisitDorisGenericDataType() { + DistributeConstraint distributeConstraint1 = new DistributeConstraint(Lists.newArrayList( + new Identifier("c1"), + new Identifier("c2") + ), 10); + dorisOutVisitor.visitDistributeKeyConstraint(distributeConstraint1, 0); + String string = dorisOutVisitor.getBuilder().toString(); + assertEquals("DISTRIBUTED BY HASH(c1,c2) BUCKETS 10", string); + } + + @Test + public void testVisitCreateTable() { + + } +} \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-doris/src/test/java/com/aliyun/fastmodel/transform/doris/parser/DorisLanguageParserTest.java b/fastmodel-transform/fastmodel-transform-doris/src/test/java/com/aliyun/fastmodel/transform/doris/parser/DorisLanguageParserTest.java new file mode 100644 index 0000000..67d1619 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/test/java/com/aliyun/fastmodel/transform/doris/parser/DorisLanguageParserTest.java @@ -0,0 +1,91 @@ +package com.aliyun.fastmodel.transform.doris.parser; + +import java.nio.charset.Charset; +import java.util.List; + +import com.aliyun.fastmodel.core.tree.datatype.BaseDataType; +import com.aliyun.fastmodel.core.tree.statement.table.ColumnDefinition; +import com.aliyun.fastmodel.core.tree.statement.table.CreateTable; +import com.aliyun.fastmodel.transform.api.dialect.DialectNode; +import com.aliyun.fastmodel.transform.doris.DorisTransformer; +import lombok.SneakyThrows; +import org.apache.commons.io.IOUtils; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * doris language parser test + * + * @author panguanjing + * @date 2024/1/20 + */ +public class DorisLanguageParserTest { + + DorisLanguageParser dorisLanguageParser = new DorisLanguageParser(); + + @Test + @SneakyThrows + public void testParse() { + String content = IOUtils.resourceToString("/doris/range.txt", Charset.defaultCharset()); + CreateTable o = dorisLanguageParser.parseNode(content); + assertNotNull(o); + List columnDefines = o.getColumnDefines(); + assertEquals(10, columnDefines.size()); + } + + @Test + @SneakyThrows + public void testParseRangeError() { + String content = IOUtils.resourceToString("/doris/range_error.txt", Charset.defaultCharset()); + CreateTable o = dorisLanguageParser.parseNode(content); + assertNotNull(o); + } + + @Test + public void testArrayIntParse() { + CreateTable createTable = dorisLanguageParser.parseNode("create table a (array_int array comment 'comment') comment 'abc';"); + List columnDefines = createTable.getColumnDefines(); + ColumnDefinition columnDefinition = columnDefines.get(0); + BaseDataType dataType = columnDefinition.getDataType(); + assertEquals("ARRAY", dataType.toString()); + + } + + @Test + public void testMapParse() { + CreateTable createTable = dorisLanguageParser.parseNode("create table a (array_int map comment 'comment') comment 'abc';"); + List columnDefines = createTable.getColumnDefines(); + ColumnDefinition columnDefinition = columnDefines.get(0); + BaseDataType dataType = columnDefinition.getDataType(); + assertEquals("MAP", dataType.toString()); + } + + @Test + public void testParseStepPartition() { + String sql = "CREATE TABLE IF NOT EXISTS abc\n" + + "(\n" + + " c1 INT MIN NULL,\n" + + " c2 INT NOT NULL COMMENT \"comment\"\n" + + ")\n" + + "COMMENT \"comment\"\n" + + "PARTITION BY RANGE (c2)\n" + + "(\n" + + " FROM (\"2020-01-01\") TO (\"2023-01-01\") INTERVAL 1 DAY\n" + + ");"; + CreateTable o = dorisLanguageParser.parseNode(sql); + DorisTransformer dorisTransformer = new DorisTransformer(); + DialectNode transform = dorisTransformer.transform(o); + assertEquals("CREATE TABLE abc\n" + + "(\n" + + " c1 INT MIN NULL,\n" + + " c2 INT NOT NULL COMMENT \"comment\"\n" + + ")\n" + + "COMMENT \"comment\"\n" + + "PARTITION BY RANGE (c2)\n" + + "(\n" + + " FROM (\"2020-01-01\") TO (\"2023-01-01\") INTERVAL 1 DAY\n" + + ");", transform.getNode()); + } +} \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-doris/src/test/java/com/aliyun/fastmodel/transform/doris/parser/util/DorisReservedWordUtilTest.java b/fastmodel-transform/fastmodel-transform-doris/src/test/java/com/aliyun/fastmodel/transform/doris/parser/util/DorisReservedWordUtilTest.java new file mode 100644 index 0000000..03e5648 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/test/java/com/aliyun/fastmodel/transform/doris/parser/util/DorisReservedWordUtilTest.java @@ -0,0 +1,23 @@ +package com.aliyun.fastmodel.transform.doris.parser.util; + +import org.junit.Test; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * Desc: + * + * @author panguanjing + * @date 2024/1/24 + */ +public class DorisReservedWordUtilTest { + + @Test + public void isReservedKeyWord() { + boolean flag = DorisReservedWordUtil.isReservedKeyWord("add"); + assertTrue(flag); + flag = DorisReservedWordUtil.isReservedKeyWord("test"); + assertFalse(flag); + } +} \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-doris/src/test/resources/doris/property.txt b/fastmodel-transform/fastmodel-transform-doris/src/test/resources/doris/property.txt new file mode 100644 index 0000000..7886c6e --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/test/resources/doris/property.txt @@ -0,0 +1,16 @@ +CREATE TABLE `t_yunshi_holo_binlog_2_020601` ( + `id` bigint(20) NOT NULL, + `col1` text NULL, + `col2` text NULL, + `col3` text NULL +) ENGINE=OLAP +UNIQUE KEY(`id`) +COMMENT 'Auto created by DataWorks Data Integration' +DISTRIBUTED BY HASH(`id`) BUCKETS 4 +PROPERTIES ( + "replication_allocation" = "tag.location.default: 1", + "in_memory" = "false", + "storage_format" = "V2", + "light_schema_change" = "true", + "disable_auto_compaction" = "false" +); \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-doris/src/test/resources/doris/range.txt b/fastmodel-transform/fastmodel-transform-doris/src/test/resources/doris/range.txt new file mode 100644 index 0000000..decb46a --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/test/resources/doris/range.txt @@ -0,0 +1,28 @@ +CREATE TABLE IF NOT EXISTS example_db.example_range_tbl +( + `user_id` LARGEINT NOT NULL COMMENT "User ID", + `date` DATE NOT NULL COMMENT "Date when the data are imported", + `timestamp` DATETIME NOT NULL COMMENT "Timestamp when the data are imported", + `city` VARCHAR(20) COMMENT "User location city", + `age` SMALLINT COMMENT "User age", + `sex` TINYINT COMMENT "User gender", + `last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01 00:00:00" COMMENT "User last visit time", + `cost` BIGINT SUM DEFAULT "0" COMMENT "Total user consumption", + `max_dwell_time` INT MAX DEFAULT "0" COMMENT "Maximum user dwell time", + `min_dwell_time` INT MIN DEFAULT "99999" COMMENT "Minimum user dwell time" +) +ENGINE=olap +AGGREGATE KEY(`user_id`, `date`, `timestamp`, `city`, `age`, `sex`) +PARTITION BY RANGE(`date`) +( + PARTITION `p201701` VALUES LESS THAN ("2017-02-01"), + PARTITION `p201702` VALUES LESS THAN ("2017-03-01"), + PARTITION `p201703` VALUES LESS THAN ("2017-04-01") +) +DISTRIBUTED BY HASH(`user_id`) BUCKETS 16 +PROPERTIES +( + "replication_num" = "3", + "storage_medium" = "SSD", + "storage_cooldown_time" = "2018-01-01 12:00:00" +); \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-doris/src/test/resources/doris/range_error.txt b/fastmodel-transform/fastmodel-transform-doris/src/test/resources/doris/range_error.txt new file mode 100644 index 0000000..007bb20 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/test/resources/doris/range_error.txt @@ -0,0 +1,12 @@ +CREATE TABLE IF NOT EXISTS yunshi_db.fml_raw_partition +( + c1 TINYINT NOT NULL COMMENT "", + c2 DATE NOT NULL COMMENT "", + c3 INT NOT NULL COMMENT "", + c4 STRING NULL COMMENT "" +) +UNIQUE KEY (c1,c2,c3) +COMMENT "" +PARTITION BY RANGE (c2)() +DISTRIBUTED BY HASH(c1,c2) BUCKETS 4 +PROPERTIES ("replication_num"="3"); \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-doris/src/test/resources/doris/steppartition.txt b/fastmodel-transform/fastmodel-transform-doris/src/test/resources/doris/steppartition.txt new file mode 100644 index 0000000..29e5f10 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-doris/src/test/resources/doris/steppartition.txt @@ -0,0 +1,10 @@ +CREATE TABLE IF NOT EXISTS abc +( + c1 INT MIN NULL, + c2 INT NOT NULL COMMENT "comment" +) +COMMENT "comment" +PARTITION BY RANGE (c2) +( + FROM ("2020-01-01") TO ("2023-01-01") INTERVAL 1 DAY +); \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-graph/src/main/java/com/aliyun/fastmodel/transform/graph/domain/table/TableVertex.java b/fastmodel-transform/fastmodel-transform-graph/src/main/java/com/aliyun/fastmodel/transform/graph/domain/table/TableVertex.java index c826ad2..b03be9f 100644 --- a/fastmodel-transform/fastmodel-transform-graph/src/main/java/com/aliyun/fastmodel/transform/graph/domain/table/TableVertex.java +++ b/fastmodel-transform/fastmodel-transform-graph/src/main/java/com/aliyun/fastmodel/transform/graph/domain/table/TableVertex.java @@ -21,7 +21,7 @@ import com.aliyun.fastmodel.core.tree.QualifiedName; import com.aliyun.fastmodel.core.tree.statement.table.CreateTable; -import com.aliyun.fastmodel.transform.api.domain.factory.DomainFactorys; +import com.aliyun.fastmodel.transform.api.domain.factory.DomainFactorySingleton; import com.aliyun.fastmodel.transform.api.domain.table.TableDataModel; import com.aliyun.fastmodel.transform.graph.domain.Vertex; import com.aliyun.fastmodel.transform.graph.domain.VertexType; @@ -52,7 +52,7 @@ public class TableVertex implements Vertex { public TableVertex(CreateTable createTable) { creatTable = createTable; - tableDataModel = DomainFactorys.newTableFactory().create(createTable); + tableDataModel = DomainFactorySingleton.newTableFactory().create(createTable); if (CollectionUtils.isNotEmpty(tableDataModel.getCols())) { maps.put(COLUMNS, tableDataModel.getCols()); } diff --git a/fastmodel-transform/fastmodel-transform-hive/src/main/java/com/aliyun/fastmodel/transform/hive/client/converter/HiveClientConverter.java b/fastmodel-transform/fastmodel-transform-hive/src/main/java/com/aliyun/fastmodel/transform/hive/client/converter/HiveClientConverter.java index d264604..a6c1da7 100644 --- a/fastmodel-transform/fastmodel-transform-hive/src/main/java/com/aliyun/fastmodel/transform/hive/client/converter/HiveClientConverter.java +++ b/fastmodel-transform/fastmodel-transform-hive/src/main/java/com/aliyun/fastmodel/transform/hive/client/converter/HiveClientConverter.java @@ -14,6 +14,7 @@ import java.util.stream.Collectors; import com.aliyun.fastmodel.core.exception.ParseException; +import com.aliyun.fastmodel.core.parser.LanguageParser; import com.aliyun.fastmodel.core.tree.Node; import com.aliyun.fastmodel.core.tree.Property; import com.aliyun.fastmodel.core.tree.QualifiedName; @@ -96,7 +97,12 @@ protected List toProperty(Table table, List proper } @Override - protected BaseDataType getDataType(Column column) { + public LanguageParser getLanguageParser() { + return hiveLanguageParser; + } + + @Override + public BaseDataType getDataType(Column column) { String dataTypeName = column.getDataType(); if (StringUtils.isBlank(dataTypeName)) { throw new IllegalArgumentException("dataType name can't be null:" + column.getName()); diff --git a/fastmodel-transform/fastmodel-transform-hologres/src/main/java/com/aliyun/fastmodel/transform/hologres/client/converter/HologresClientConverter.java b/fastmodel-transform/fastmodel-transform-hologres/src/main/java/com/aliyun/fastmodel/transform/hologres/client/converter/HologresClientConverter.java index 754dc09..3b4b591 100644 --- a/fastmodel-transform/fastmodel-transform-hologres/src/main/java/com/aliyun/fastmodel/transform/hologres/client/converter/HologresClientConverter.java +++ b/fastmodel-transform/fastmodel-transform-hologres/src/main/java/com/aliyun/fastmodel/transform/hologres/client/converter/HologresClientConverter.java @@ -11,6 +11,7 @@ import java.util.List; import java.util.Optional; +import com.aliyun.fastmodel.core.parser.LanguageParser; import com.aliyun.fastmodel.core.tree.Property; import com.aliyun.fastmodel.core.tree.datatype.BaseDataType; import com.aliyun.fastmodel.core.tree.datatype.IDataTypeName; @@ -29,7 +30,6 @@ import com.aliyun.fastmodel.transform.hologres.context.HologresTransformContext; import com.aliyun.fastmodel.transform.hologres.parser.HologresParser; import com.aliyun.fastmodel.transform.hologres.parser.tree.datatype.HologresDataTypeName; -import com.google.common.collect.Lists; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; @@ -48,6 +48,11 @@ public HologresClientConverter() { hologresParser = new HologresParser(); } + @Override + public LanguageParser getLanguageParser() { + return hologresParser; + } + @Override public BaseDataType getDataType(Column column) { String dataTypeName = column.getDataType(); diff --git a/fastmodel-transform/fastmodel-transform-hologres/src/test/java/com/aliyun/fastmodel/transform/hologres/client/generator/HologresCodeGeneratorSetDefaultValueTest.java b/fastmodel-transform/fastmodel-transform-hologres/src/test/java/com/aliyun/fastmodel/transform/hologres/client/generator/HologresCodeGeneratorSetDefaultValueTest.java index f5f4041..13f0a10 100644 --- a/fastmodel-transform/fastmodel-transform-hologres/src/test/java/com/aliyun/fastmodel/transform/hologres/client/generator/HologresCodeGeneratorSetDefaultValueTest.java +++ b/fastmodel-transform/fastmodel-transform-hologres/src/test/java/com/aliyun/fastmodel/transform/hologres/client/generator/HologresCodeGeneratorSetDefaultValueTest.java @@ -88,7 +88,7 @@ public void testSetDefaultFromNullToValue() { String result = generate.getDialectNodes().stream().filter(DialectNode::isExecutable).map(DialectNode::getNode).collect(Collectors.joining("\n")); assertEquals("BEGIN;\n" - + "ALTER TABLE a ALTER COLUMN c1 SET DEFAULT null;\n" + + "ALTER TABLE a ALTER COLUMN c1 SET DEFAULT NULL;\n" + "COMMIT;", result); } diff --git a/fastmodel-transform/fastmodel-transform-mysql/src/main/java/com/aliyun/fastmodel/transform/mysql/parser/MysqlAstBuilder.java b/fastmodel-transform/fastmodel-transform-mysql/src/main/java/com/aliyun/fastmodel/transform/mysql/parser/MysqlAstBuilder.java index 96944c9..a044181 100644 --- a/fastmodel-transform/fastmodel-transform-mysql/src/main/java/com/aliyun/fastmodel/transform/mysql/parser/MysqlAstBuilder.java +++ b/fastmodel-transform/fastmodel-transform-mysql/src/main/java/com/aliyun/fastmodel/transform/mysql/parser/MysqlAstBuilder.java @@ -53,6 +53,7 @@ import com.aliyun.fastmodel.core.tree.statement.table.constraint.PrimaryConstraint; import com.aliyun.fastmodel.core.tree.statement.table.constraint.UniqueConstraint; import com.aliyun.fastmodel.core.tree.statement.table.index.IndexColumnName; +import com.aliyun.fastmodel.core.tree.statement.table.index.IndexSortKey; import com.aliyun.fastmodel.core.tree.statement.table.index.SortType; import com.aliyun.fastmodel.core.tree.statement.table.index.TableIndex; import com.aliyun.fastmodel.core.tree.util.IdentifierUtil; @@ -517,8 +518,8 @@ public Node visitCheckTableConstraint(CheckTableConstraintContext ctx) { @Override public Node visitSimpleIndexDeclaration(SimpleIndexDeclarationContext ctx) { - List visit = ParserHelper.visit(this, ctx.indexColumnNames().indexColumnName(), - IndexColumnName.class); + List visit = ParserHelper.visit(this, ctx.indexColumnNames().indexColumnName(), + IndexSortKey.class); List list = ImmutableList.of(); List indexOptionContexts = ctx.indexOption(); if (indexOptionContexts != null) { diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/pom.xml b/fastmodel-transform/fastmodel-transform-oceanbase/pom.xml new file mode 100644 index 0000000..a65e141 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/pom.xml @@ -0,0 +1,49 @@ + + + 4.0.0 + + com.aliyun.fastmodel + fastmodel-transform + ${revision} + + + fastmodel-transform-oceanbase + + + UTF-8 + + + + + com.aliyun.fastmodel + fastmodel-transform-api + ${project.version} + + + + com.google.auto.service + auto-service + + + + org.antlr + antlr4-runtime + + + com.aliyun.fastmodel + fastmodel-common + ${project.parent.version} + compile + + + + commons-io + commons-io + test + + + + + \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/antlr4/com/aliyun/fastmodel/transform/oceanbase/mysql/parser/OBLexer.g4 b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/antlr4/com/aliyun/fastmodel/transform/oceanbase/mysql/parser/OBLexer.g4 new file mode 100644 index 0000000..1374204 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/antlr4/com/aliyun/fastmodel/transform/oceanbase/mysql/parser/OBLexer.g4 @@ -0,0 +1,4384 @@ +/* + * Copyright (c) 2023 OceanBase. + * + * Licensed 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. + */ + +lexer grammar OBLexer; +@members { +public boolean inRangeOperator = false; +} + +ACCESS + : ( A C C E S S ) + ; + +ACCESSIBLE + : ( A C C E S S I B L E ) + ; + +ADD + : ( A D D ) + ; + +AGAINST + : ( A G A I N S T ) + ; + +ALTER + : ( A L T E R ) + ; + +ALWAYS + : ( A L W A Y S ) + ; + +AND + : ( A N D ) + ; + +ANALYZE + : ( A N A L Y Z E ) + ; + +ALL + : ( A L L ) + ; + +NAMESPACE + : N A M E S P A C E + ; + +AS + : ( A S ) + ; + +ASENSITIVE + : ( A S E N S I T I V E ) + ; + +ASC + : ( A S C ) + ; + +BETWEEN + : ( B E T W E E N ) + ; + +BEFORE + : ( B E F O R E ) + ; + +BIGINT + : ( B I G I N T ) + ; + +BINARY + : ( B I N A R Y ) + ; + +BLOB + : ( B L O B ) + ; + +BOTH + : ( B O T H ) + ; + +BY + : ( B Y ) + ; + +CALL + : ( C A L L ) + ; + +CASCADE + : ( C A S C A D E ) + ; + +CASE + : ( C A S E ) + ; + +CHANGE + : ( C H A N G E ) + ; + +CHARACTER + : ( C H A R ) + | ( C H A R A C T E R ) + ; + +CHECK + : ( C H E C K ) + ; + +CIPHER + : ( C I P H E R ) + ; + +CONDITION + : ( C O N D I T I O N ) + ; + +CONSTRAINT + : ( C O N S T R A I N T ) + ; + +CONTINUE + : ( C O N T I N U E ) + ; + +CONVERT + : ( C O N V E R T ) + ; + +COLLATE + : ( C O L L A T E ) + ; + +COLUMN + : ( C O L U M N ) + ; + +COLUMNS + : ( C O L U M N S ) + ; + +LS + : L S + ; + +CREATE + : ( C R E A T E ) + ; + +CROSS + : ( C R O S S ) + ; + +CYCLE + : ( C Y C L E ) + ; + +CURRENT_DATE + : ( C U R R E N T '_' D A T E ) + ; + +CURRENT_TIME + : ( C U R R E N T '_' T I M E ) + ; + +CURRENT_TIMESTAMP + : ( C U R R E N T '_' T I M E S T A M P ) + ; + +CURRENT_USER + : ( C U R R E N T '_' U S E R ) + ; + +WITH_ROWID + : (( W I T H ([ \t\n\r\f]+|('--'[ \t\n\r\f]+(~[\n\r])*)|('#'(~[\n\r])*)) R O W I D )) + ; + +CURSOR + : ( C U R S O R ) + ; + +DAY_HOUR + : ( D A Y '_' H O U R ) + ; + +DAY_MICROSECOND + : ( D A Y '_' M I C R O S E C O N D ) + ; + +DAY_MINUTE + : ( D A Y '_' M I N U T E ) + ; + +DAY_SECOND + : ( D A Y '_' S E C O N D ) + ; + +DATABASE + : ( D A T A B A S E ) + ; + +DATABASES + : ( D A T A B A S E S ) + ; + +NUMBER + : ( D E C ) + | ( N U M E R I C ) + | ( N U M B E R ) + ; + +DECIMAL + : ( D E C I M A L ) + ; + +DECLARE + : ( D E C L A R E ) + ; + +DEFAULT + : ( D E F A U L T ) + ; + +DELAYED + : ( D E L A Y E D ) + ; + +DELETE + : ( D E L E T E ) + ; + +DESC + : ( D E S C ) + ; + +DESCRIBE + : ( D E S C R I B E ) + ; + +DETERMINISTIC + : ( D E T E R M I N I S T I C ) + ; + +DIV + : ( D I V ) + ; + +DISTINCT + : ( D I S T I N C T ) + ; + +DISTINCTROW + : ( D I S T I N C T R O W ) + ; + +DOUBLE + : ( D O U B L E ) + ; + +DROP + : ( D R O P ) + ; + +DUAL + : ( D U A L ) + ; + +EACH + : ( E A C H ) + ; + +ENCLOSED + : ( E N C L O S E D ) + ; + +ELSE + : ( E L S E ) + ; + +ELSEIF + : ( E L S E I F ) + ; + +ESCAPED + : ( E S C A P E D ) + ; + +EXISTS + : ( E X I S T S ) + ; + +EXIT + : ( E X I T ) + ; + +EXPLAIN + : ( E X P L A I N ) + ; + +FETCH + : ( F E T C H ) + ; + +FIELDS + : ( F I E L D S ) + ; + +FOREIGN + : ( F O R E I G N ) + ; + +FLOAT + : ( F L O A T ) + ; + +FLOAT4 + : ( F L O A T '4') + ; + +FLOAT8 + : ( F L O A T '8') + ; + +FOR + : ( F O R ) + ; + +FORCE + : ( F O R C E ) + ; + +FROM + : ( F R O M ) + ; + +FULL + : ( F U L L ) + ; + +FULLTEXT + : ( F U L L T E X T ) + ; + +GET + : ( G E T ) + ; + +GENERATED + : ( G E N E R A T E D ) + ; + +GRANT + : ( G R A N T ) + ; + +GROUP + : ( G R O U P ) + ; + +HAVING + : ( H A V I N G ) + ; + +HIGH_PRIORITY + : ( H I G H '_' P R I O R I T Y ) + ; + +HOUR_MICROSECOND + : ( H O U R '_' M I C R O S E C O N D ) + ; + +HOUR_MINUTE + : ( H O U R '_' M I N U T E ) + ; + +HOUR_SECOND + : ( H O U R '_' S E C O N D ) + ; + +ID + : ( I D ) + ; + +IF + : ( I F ) + ; + +IN + : ( I N ) + ; + +INDEX + : ( I N D E X ) + ; + +INNER + : ( I N N E R ) + ; + +INFILE + : ( I N F I L E ) + ; + +INOUT + : ( I N O U T ) + ; + +INSENSITIVE + : ( I N S E N S I T I V E ) + ; + +INTEGER + : ( I N T ) + | ( I N T E G E R ) + ; + +INT1 + : ( I N T '1') + ; + +INT2 + : ( I N T '2') + ; + +INT3 + : ( I N T '3') + ; + +LIB + : L I B + ; + +INT4 + : ( I N T '4') + ; + +INT8 + : ( I N T '8') + ; + +INTERVAL + : I N T E R V A L + ; + +INSERT + : ( I N S E R T ) + ; + +ORDINALITY + : O R D I N A L I T Y + ; + +INTO + : ( I N T O ) + ; + +IO_AFTER_GTIDS + : ( I O '_' A F T E R '_' G T I D S ) + ; + +IO_BEFORE_GTIDS + : ( I O '_' B E F O R E '_' G T I D S ) + ; + +IS + : ( I S ) + ; + +ISSUER + : ( I S S U E R ) + ; + +ITERATE + : ( I T E R A T E ) + ; + +JOIN + : ( J O I N ) + ; + +KEY + : ( K E Y ) + ; + +KEYS + : ( K E Y S ) + ; + +KILL + : ( K I L L ) + ; + +LANGUAGE + : ( L A N G U A G E ) + ; + +LEADING + : ( L E A D I N G ) + ; + +LEAVE + : ( L E A V E ) + ; + +LEFT + : ( L E F T ) + ; + +LIMIT + : ( L I M I T ) + ; + +LIKE + : ( L I K E ) + ; + +LINEAR + : ( L I N E A R ) + ; + +LINES + : ( L I N E S ) + ; + +BISON_LIST + : ( L I S T ) + ; + +LOAD + : ( L O A D ) + ; + +LOCAL + : ( L O C A L ) + ; + +OPTIMIZER_FEATURES_ENABLE + : O P T I M I Z E R '_' F E A T U R E S '_' E N A B L E + ; + +LOCALTIME + : ( L O C A L T I M E ) + ; + +LOCALTIMESTAMP + : ( L O C A L T I M E S T A M P ) + ; + +LOCK_ + : ( L O C K ) + ; + +LONG + : ( L O N G ) + ; + +UNLIMITED + : U N L I M I T E D + ; + +LONGBLOB + : ( L O N G B L O B ) + ; + +LONGTEXT + : ( L O N G T E X T ) + ; + +LOOP + : ( L O O P ) + ; + +LOW_PRIORITY + : ( L O W '_' P R I O R I T Y ) + ; + +MASTER_BIND + : ( M A S T E R '_' B I N D ) + ; + +MASTER_SSL_VERIFY_SERVER_CERT + : ( M A S T E R '_' S S L '_' V E R I F Y '_' S E R V E R '_' C E R T ) + ; + +MATCH + : ( M A T C H ) + ; + +MAXVALUE + : ( M A X V A L U E ) + ; + +MEDIUMBLOB + : ( M E D I U M B L O B ) + ; + +MEDIUMINT + : ( M E D I U M I N T ) + ; + +MERGE + : ( M E R G E ) + ; + +MEDIUMTEXT + : ( M E D I U M T E X T ) + ; + +MIDDLEINT + : ( M I D D L E I N T ) + ; + +MINUTE_MICROSECOND + : ( M I N U T E '_' M I C R O S E C O N D ) + ; + +MINUTE_SECOND + : ( M I N U T E '_' S E C O N D ) + ; + +MOD + : ( M O D ) + ; + +MODE + : ( M O D E ) + ; + +MODIFIES + : ( M O D I F I E S ) + ; + +NATURAL + : ( N A T U R A L ) + ; + +NO_WRITE_TO_BINLOG + : ( N O '_' W R I T E '_' T O '_' B I N L O G ) + ; + +ON + : ( O N ) + ; + +OPTION + : ( O P T I O N ) + ; + +OPTIMIZE + : ( O P T I M I Z E ) + ; + +OPTIONALLY + : ( O P T I O N A L L Y ) + ; + +OR + : ( O R ) + ; + +ORDER + : ( O R D E R ) + ; + +OUT + : ( O U T ) + ; + +IOPS_WEIGHT + : I O P S '_' W E I G H T + ; + +OUTER + : ( O U T E R ) + ; + +OUTFILE + : ( O U T F I L E ) + ; + +PARSER + : ( P A R S E R ) + ; + +PROCEDURE + : ( P R O C E D U R E ) + ; + +PURGE + : ( P U R G E ) + ; + +PARTITION + : ( P A R T I T I O N ) + ; + +PRECISION + : ( P R E C I S I O N ) + ; + +PRIMARY + : ( P R I M A R Y ) + ; + +PUBLIC + : ( P U B L I C ) + ; + +RANGE + : ( R A N G E ) + ; + +READ + : ( R E A D ) + ; + +READ_WRITE + : ( R E A D '_' W R I T E ) + ; + +READS + : ( R E A D S ) + ; + +REAL + : ( R E A L ) + ; + +RELEASE + : ( R E L E A S E ) + ; + +REFERENCES + : ( R E F E R E N C E S ) + ; + +REGEXP + : ( R E G E X P ) + | ( R L I K E ) + ; + +RENAME + : ( R E N A M E ) + ; + +REPLACE + : ( R E P L A C E ) + ; + +REPEAT + : ( R E P E A T ) + ; + +REQUIRE + : ( R E Q U I R E ) + ; + +RESIGNAL + : ( R E S I G N A L ) + ; + +RESTRICT + : ( R E S T R I C T ) + ; + +RETURN + : ( R E T U R N ) + ; + +REVOKE + : ( R E V O K E ) + ; + +RIGHT + : ( R I G H T ) + ; + +ROWS + : ( R O W S ) + ; + +SECOND_MICROSECOND + : ( S E C O N D '_' M I C R O S E C O N D ) + ; + +SELECT + : ( S E L E C T ) + ; + +SCHEMA + : ( S C H E M A ) + ; + +SCHEMAS + : ( S C H E M A S ) + ; + +SEPARATOR + : ( S E P A R A T O R ) + ; + +SET + : ( S E T ) + ; + +REJECT + : R E J E C T + ; + +SENSITIVE + : ( S E N S I T I V E ) + ; + +SHOW + : ( S H O W ) + ; + +SIGNAL + : ( S I G N A L ) + ; + +SMALLINT + : ( S M A L L I N T ) + ; + +SPATIAL + : ( S P A T I A L ) + ; + +SPECIFIC + : ( S P E C I F I C ) + ; + +SQL + : ( S Q L ) + ; + +SQLEXCEPTION + : ( S Q L E X C E P T I O N ) + ; + +SQLSTATE + : ( S Q L S T A T E ) + ; + +SQLWARNING + : ( S Q L W A R N I N G ) + ; + +SQL_BIG_RESULT + : ( S Q L '_' B I G '_' R E S U L T ) + ; + +SQL_CALC_FOUND_ROWS + : ( S Q L '_' C A L C '_' F O U N D '_' R O W S ) + ; + +SQL_SMALL_RESULT + : ( S Q L '_' S M A L L '_' R E S U L T ) + ; + +SSL + : ( S S L ) + ; + +STARTING + : ( S T A R T I N G ) + ; + +NUMERIC + : N U M E R I C + ; + +STORED + : ( S T O R E D ) + ; + +PLUS + : P L U S + ; + +STRAIGHT_JOIN + : ( S T R A I G H T '_' J O I N ) + ; + +SUBJECT + : ( S U B J E C T ) + ; + +SYSDATE + : ( S Y S D A T E ) + ; + +TERMINATED + : ( T E R M I N A T E D ) + ; + +TEXT + : ( T E X T ) + ; + +TINYBLOB + : ( T I N Y B L O B ) + ; + +TINYINT + : ( T I N Y I N T ) + ; + +TINYTEXT + : ( T I N Y T E X T ) + ; + +TABLE + : ( T A B L E ) + ; + +TABLEGROUP + : ( T A B L E G R O U P ) + ; + +THEN + : ( T H E N ) + ; + +TO + : ( T O ) + ; + +TRAILING + : ( T R A I L I N G ) + ; + +TRIGGER + : ( T R I G G E R ) + ; + +UNDO + : ( U N D O ) + ; + +CALIBRATION + : C A L I B R A T I O N + ; + +UNION + : ( U N I O N ) + ; + +UNIQUE + : ( U N I Q U E ) + ; + +UNLOCK + : ( U N L O C K ) + ; + +LINE_DELIMITER + : L I N E '_' D E L I M I T E R + ; + +UNSIGNED + : ( U N S I G N E D ) + ; + +UPDATE + : ( U P D A T E ) + ; + +USAGE + : ( U S A G E ) + ; + +GEOMCOLLECTION + : G E O M C O L L E C T I O N + ; + +USE + : ( U S E ) + ; + +USING + : ( U S I N G ) + ; + +UTC_DATE + : ( U T C '_' D A T E ) + ; + +UTC_TIME + : ( U T C '_' T I M E ) + ; + +UTC_TIMESTAMP + : ( U T C '_' T I M E S T A M P ) + ; + +VALUES + : ( V A L U E S ) + ; + +QUERY_RESPONSE_TIME + : Q U E R Y '_' R E S P O N S E '_' T I M E + ; + +VARBINARY + : ( V A R B I N A R Y ) + ; + +VARCHAR + : ( V A R C H A R ) + | ( V A R C H A R A C T E R ) + ; + +VARYING + : ( V A R Y I N G ) + ; + +VIRTUAL + : ( V I R T U A L ) + ; + +WHERE + : ( W H E R E ) + ; + +REDUNDANCY + : R E D U N D A N C Y + ; + +WHEN + : ( W H E N ) + ; + +WHILE + : ( W H I L E ) + ; + +CALIBRATION_INFO + : C A L I B R A T I O N '_' I N F O + ; + +SCN + : S C N + ; + +WINDOW + : ( W I N D O W ) + ; + +WITH + : ( W I T H ) + ; + +WRITE + : ( W R I T E ) + ; + +XOR + : ( X O R ) + ; + +X509 + : ( X '5''0''9') + ; + +YEAR_MONTH + : ( Y E A R '_' M O N T H ) + ; + +ZEROFILL + : ( Z E R O F I L L ) + ; + +GLOBAL_ALIAS + : ('@''@' G L O B A L ) + ; + +SESSION_ALIAS + : ('@''@' S E S S I O N ) + | ('@''@' L O C A L ) + ; + +UnderlineUTF8 + : ('_' U T F '8') + ; + +UnderlineUTF8MB4 + : ('_' U T F '8' M B '4') + ; + +UnderlineGBK + : ('_' G B K ) + ; + +UnderlineGB18030 + : ('_' G B '1''8''0''3''0') + ; + +UnderlineBINARY + : ('_' B I N A R Y ) + ; + +UnderlineUTF16 + : ('_' U T F '1''6') + ; + +UnderlineLATIN1 + : ('_' L A T I N '1') + ; + +UnderlineGB18030_2022 + : ('_' G B '1''8''0''3''0''_''2''0''2''2') + ; + +STRONG + : ( S T R O N G ) + ; + +WEAK + : ( W E A K ) + ; + +CONNECT + : C O N N E C T + ; + +FROZEN + : ( F R O Z E N ) + ; + +EXCEPT + : ( E X C E P T ) + ; + +MINUS + : ( M I N U S ) + ; + +INTERSECT + : ( I N T E R S E C T ) + ; + +ISNULL + : ( I S N U L L ) + ; + +NOT + : N O T + ; + +NULLX + : N U L L + ; + +INTNUM + : [0-9]+ + ; + +AUDIT + : A U D I T + ; + +WARNINGS + : W A R N I N G S + ; + +FORMAT + : F O R M A T + ; + +MINVALUE + : M I N V A L U E + ; + +EMPTY_FIELD_AS_NULL + : E M P T Y '_' F I E L D '_' A S '_' N U L L + ; + +UNINSTALL + : U N I N S T A L L + ; + +UNDOFILE + : U N D O F I L E + ; + +MASTER_SSL_CA + : M A S T E R '_' S S L '_' C A + ; + +YEAR + : Y E A R + ; + +DISCONNECT + : D I S C O N N E C T + ; + +STOP + : S T O P + ; + +STORAGE_FORMAT_WORK_VERSION + : S T O R A G E '_' F O R M A T '_' W O R K '_' V E R S I O N + ; + +SIZE + : S I Z E + ; + +DISABLE_PARALLEL_DML + : D I S A B L E '_' P A R A L L E L '_' D M L + ; + +AT + : A T + ; + +RELAY_LOG_POS + : R E L A Y '_' L O G '_' P O S + ; + +POOL + : P O O L + ; + +CURDATE + : C U R D A T E + ; + +JSON_VALUE + : J S O N '_' V A L U E + ; + +ZONE_TYPE + : Z O N E '_' T Y P E + ; + +LOCATION + : L O C A T I O N + ; + +WEIGHT_STRING + : W E I G H T '_' S T R I N G + ; + +CHANGED + : C H A N G E D + ; + +MASTER_SSL_CAPATH + : M A S T E R '_' S S L '_' C A P A T H + ; + +REWRITE_MERGE_VERSION + : R E W R I T E '_' M E R G E '_' V E R S I O N + ; + +NTH_VALUE + : N T H '_' V A L U E + ; + +SERIAL + : S E R I A L + ; + +PROGRESSIVE_MERGE_NUM + : P R O G R E S S I V E '_' M E R G E '_' N U M + ; + +QUEUE_TIME + : Q U E U E '_' T I M E + ; + +TABLET_MAX_SIZE + : T A B L E T '_' M A X '_' S I Z E + ; + +ILOGCACHE + : I L O G C A C H E + ; + +AUTHORS + : A U T H O R S + ; + +MIGRATE + : M I G R A T E + ; + +CONSISTENT + : C O N S I S T E N T + ; + +SUSPEND + : S U S P E N D + ; + +REMOTE_OSS + : R E M O T E '_' O S S + ; + +SECURITY + : S E C U R I T Y + ; + +SET_SLAVE_CLUSTER + : S E T '_' S L A V E '_' C L U S T E R + ; + +FAST + : F A S T + ; + +PREVIEW + : P R E V I E W + ; + +BANDWIDTH + : B A N D W I D T H + ; + +TRUNCATE + : T R U N C A T E + ; + +BACKUP_BACKUP_DEST + : B A C K U P '_' B A C K U P '_' D E S T + ; + +CONSTRAINT_SCHEMA + : C O N S T R A I N T '_' S C H E M A + ; + +MASTER_SSL_CERT + : M A S T E R '_' S S L '_' C E R T + ; + +TABLE_NAME + : T A B L E '_' N A M E + ; + +PRIORITY + : P R I O R I T Y + ; + +DO + : D O + ; + +MASTER_RETRY_COUNT + : M A S T E R '_' R E T R Y '_' C O U N T + ; + +REPLICA + : R E P L I C A + ; + +KILL_EXPR + : K I L L '_' E X P R + ; + +RECOVERY + : R E C O V E R Y + ; + +OLD_KEY + : O L D '_' K E Y + ; + +DISABLE + : D I S A B L E + ; + +PORT + : P O R T + ; + +REBUILD + : R E B U I L D + ; + +FOLLOWER + : F O L L O W E R + ; + +LOWER_OVER + : L O W E R '_' O V E R + ; + +ROOT + : R O O T + ; + +REDOFILE + : R E D O F I L E + ; + +MASTER_SERVER_ID + : M A S T E R '_' S E R V E R '_' I D + ; + +NCHAR + : N C H A R + ; + +KEY_BLOCK_SIZE + : K E Y '_' B L O C K '_' S I Z E + ; + +SEQUENCE + : S E Q U E N C E + ; + +MIGRATION + : M I G R A T I O N + ; + +SUBPARTITION + : S U B P A R T I T I O N + ; + +MYSQL_DRIVER + : M Y S Q L '_' D R I V E R + ; + +ROW_NUMBER + : R O W '_' N U M B E R + ; + +COMPRESSION + : C O M P R E S S I O N + ; + +BIT + : B I T + ; + +MAX_DISK_SIZE + : M A X '_' D I S K '_' S I Z E + ; + +SAMPLE + : S A M P L E + ; + +UNLOCKED + : U N L O C K E D + ; + +CLASS_ORIGIN + : C L A S S '_' O R I G I N + ; + +RUDUNDANT + : R U D U N D A N T + ; + +STATEMENTS + : S T A T E M E N T S + ; + +ACTION + : A C T I O N + ; + +REDUNDANT + : R E D U N D A N T + ; + +UPGRADE + : U P G R A D E + ; + +VALIDATE + : V A L I D A T E + ; + +START + : S T A R T + ; + +TEMPTABLE + : T E M P T A B L E + ; + +RECYCLEBIN + : R E C Y C L E B I N + ; + +PROFILES + : P R O F I L E S + ; + +TIMESTAMP_VALUE + : T I M E S T A M P '_' V A L U E + ; + +ERRORS + : E R R O R S + ; + +LEAVES + : L E A V E S + ; + +UNDEFINED + : U N D E F I N E D + ; + +EVERY + : E V E R Y + ; + +SHARDING + : S H A R D I N G + ; + +BYTE + : B Y T E + ; + +FLUSH + : F L U S H + ; + +MIN_ROWS + : M I N '_' R O W S + ; + +ERROR_P + : E R R O R '_' P + ; + +MAX_USER_CONNECTIONS + : M A X '_' U S E R '_' C O N N E C T I O N S + ; + +MAX_CPU + : M A X '_' C P U + ; + +LOCKED + : L O C K E D + ; + +DOP + : D O P + ; + +IO + : I O + ; + +BTREE + : B T R E E + ; + +SLOT_IDX + : S L O T '_' I D X + ; + +APPROXNUM + : A P P R O X N U M + ; + +HASH + : H A S H + ; + +ROTATE + : R O T A T E + ; + +COLLATION + : C O L L A T I O N + ; + +MASTER + : M A S T E R + ; + +ENCRYPTION + : E N C R Y P T I O N + ; + +MAX + : M A X + ; + +TRANSACTION + : T R A N S A C T I O N + ; + +SQL_TSI_MONTH + : S Q L '_' T S I '_' M O N T H + ; + +ARBITRATION + : A R B I T R A T I O N + ; + +IGNORE + : I G N O R E + ; + +MAX_QUERIES_PER_HOUR + : M A X '_' Q U E R I E S '_' P E R '_' H O U R + ; + +COMMENT + : C O M M E N T + ; + +CTX_ID + : C T X '_' I D + ; + +MIN_IOPS + : M I N '_' I O P S + ; + +NVARCHAR + : N V A R C H A R + ; + +OFF + : O F F + ; + +BIT_XOR + : B I T '_' X O R + ; + +PAUSE + : P A U S E + ; + +QUICK + : Q U I C K + ; + +PRETTY + : P R E T T Y + ; + +DUPLICATE + : D U P L I C A T E + ; + +WAIT + : W A I T + ; + +FIELD_OPTIONALLY_ENCLOSED_BY + : F I E L D '_' O P T I O N A L L Y '_' E N C L O S E D '_' B Y + ; + +DES_KEY_FILE + : D E S '_' K E Y '_' F I L E + ; + +ENGINES + : E N G I N E S + ; + +RETURNS + : R E T U R N S + ; + +MASTER_USER + : M A S T E R '_' U S E R + ; + +SOCKET + : S O C K E T + ; + +MASTER_DELAY + : M A S T E R '_' D E L A Y + ; + +FILE_ID + : F I L E '_' I D + ; + +FIRST + : F I R S T + ; + +TABLET + : T A B L E T + ; + +CLIENT + : C L I E N T + ; + +ENGINE_ + : E N G I N E + ; + +TABLES + : T A B L E S + ; + +TRADITIONAL + : T R A D I T I O N A L + ; + +BOOTSTRAP + : B O O T S T R A P + ; + +STDDEV + : S T D D E V + ; + +DATAFILE + : D A T A F I L E + ; + +VARCHARACTER + : V A R C H A R A C T E R + ; + +INVOKER + : I N V O K E R + ; + +DEPTH + : D E P T H + ; + +NORMAL + : N O R M A L + ; + +LN + : L N + ; + +COLUMN_NAME + : C O L U M N '_' N A M E + ; + +TRIGGERS + : T R I G G E R S + ; + +ENABLE_PARALLEL_DML + : E N A B L E '_' P A R A L L E L '_' D M L + ; + +RESET + : R E S E T + ; + +EVENT + : E V E N T + ; + +COALESCE + : C O A L E S C E + ; + +RESPECT + : R E S P E C T + ; + +STATUS + : S T A T U S + ; + +AUTO_INCREMENT_MODE + : A U T O '_' I N C R E M E N T '_' M O D E + ; + +UNBOUNDED + : U N B O U N D E D + ; + +WRAPPER + : W R A P P E R + ; + +TIMESTAMP + : T I M E S T A M P + ; + +PARTITIONS + : P A R T I T I O N S + ; + +SUBSTR + : S U B S T R + ; + +CHUNK + : C H U N K + ; + +FILEX + : F I L E X + ; + +BACKUPSET + : B A C K U P S E T + ; + +PRIMARY_CLUSTER_ID + : P R I M A R Y '_' C L U S T E R '_' I D + ; + +UNIT + : U N I T + ; + +NATIONAL_LITERAL + : N A T I O N A L '_' L I T E R A L + ; + +PRIVILEGES + : P R I V I L E G E S + ; + +LOWER_ON + : L O W E R '_' O N + ; + +BACKUPPIECE + : B A C K U P P I E C E + ; + +LESS + : L E S S + ; + +SWITCH + : S W I T C H + ; + +DIAGNOSTICS + : D I A G N O S T I C S + ; + +REDO_BUFFER_SIZE + : R E D O '_' B U F F E R '_' S I Z E + ; + +NO + : N O + ; + +MAJOR + : M A J O R + ; + +ACTIVE + : A C T I V E + ; + +ROUTINE + : R O U T I N E + ; + +FOLLOWING + : F O L L O W I N G + ; + +ROLLBACK + : R O L L B A C K + ; + +READ_ONLY + : R E A D '_' O N L Y + ; + +MEMBER + : M E M B E R + ; + +PARTITION_ID + : P A R T I T I O N '_' I D + ; + +DUMP + : D U M P + ; + +EXTERNAL + : E X T E R N A L + ; + +APPROX_COUNT_DISTINCT_SYNOPSIS + : A P P R O X '_' C O U N T '_' D I S T I N C T '_' S Y N O P S I S + ; + +GROUPING + : G R O U P I N G + ; + +OF + : O F + ; + +SLOG + : S L O G + ; + +OJ + : O J + ; + +ARCHIVELOG + : A R C H I V E L O G + ; + +MAX_CONNECTIONS_PER_HOUR + : M A X '_' C O N N E C T I O N S '_' P E R '_' H O U R + ; + +ENCODING + : E N C O D I N G + ; + +SECOND + : S E C O N D + ; + +UNKNOWN + : U N K N O W N + ; + +POINT + : P O I N T + ; + +PL + : P L + ; + +MEMSTORE_PERCENT + : M E M S T O R E '_' P E R C E N T + ; + +STD + : S T D + ; + +POLYGON + : P O L Y G O N + ; + +PS + : P S + ; + +OLD + : O L D + ; + +TABLE_ID + : T A B L E '_' I D + ; + +CONTEXT + : C O N T E X T + ; + +FINAL_COUNT + : F I N A L '_' C O U N T + ; + +MASTER_CONNECT_RETRY + : M A S T E R '_' C O N N E C T '_' R E T R Y + ; + +POSITION + : P O S I T I O N + ; + +DISCARD + : D I S C A R D + ; + +PREV + : P R E V + ; + +RECOVER + : R E C O V E R + ; + +PROCESS + : P R O C E S S + ; + +DEALLOCATE + : D E A L L O C A T E + ; + +OLD_PASSWORD + : O L D '_' P A S S W O R D + ; + +FAILOVER + : F A I L O V E R + ; + +P_NSEQ + : P '_' N S E Q + ; + +LISTAGG + : L I S T A G G + ; + +SLOW + : S L O W + ; + +NOAUDIT + : N O A U D I T + ; + +SUM + : S U M + ; + +OPTIONS + : O P T I O N S + ; + +MIN + : M I N + ; + +RT + : R T + ; + +RELOAD + : R E L O A D + ; + +ONE + : O N E + ; + +DELAY_KEY_WRITE + : D E L A Y '_' K E Y '_' W R I T E + ; + +ORIG_DEFAULT + : O R I G '_' D E F A U L T + ; + +RLIKE + : R L I K E + ; + +INDEXED + : I N D E X E D + ; + +RETURNING + : R E T U R N I N G + ; + +SQL_TSI_HOUR + : S Q L '_' T S I '_' H O U R + ; + +TIMESTAMPDIFF + : T I M E S T A M P D I F F + ; + +RESTORE + : R E S T O R E + ; + +OFFSET + : O F F S E T + ; + +TEMPORARY + : T E M P O R A R Y + ; + +VARIANCE + : V A R I A N C E + ; + +SNAPSHOT + : S N A P S H O T + ; + +STATISTICS + : S T A T I S T I C S + ; + +SERVER_TYPE + : S E R V E R '_' T Y P E + ; + +COMMITTED + : C O M M I T T E D + ; + +INDEXES + : I N D E X E S + ; + +FREEZE + : F R E E Z E + ; + +SCOPE + : S C O P E + ; + +IDC + : I D C + ; + +VIEW + : V I E W + ; + +ONE_SHOT + : O N E '_' S H O T + ; + +ACCOUNT + : A C C O U N T + ; + +LOCALITY + : L O C A L I T Y + ; + +REVERSE + : R E V E R S E + ; + +UP + : U P + ; + +CLUSTER_ID + : C L U S T E R '_' I D + ; + +NOARCHIVELOG + : N O A R C H I V E L O G + ; + +BEGIN_OUTLINE_DATA + : B E G I N '_' O U T L I N E '_' D A T A + ; + +MAX_SIZE + : M A X '_' S I Z E + ; + +PAGE + : P A G E + ; + +NAME + : N A M E + ; + +ROW_COUNT + : R O W '_' C O U N T + ; + +LAST + : L A S T + ; + +WASH + : W A S H + ; + +LOGONLY_REPLICA_NUM + : L O G O N L Y '_' R E P L I C A '_' N U M + ; + +DELAY + : D E L A Y + ; + +SUBDATE + : S U B D A T E + ; + +INCREMENTAL + : I N C R E M E N T A L + ; + +ROLLING + : R O L L I N G + ; + +VERIFY + : V E R I F Y + ; + +CONTAINS + : C O N T A I N S + ; + +GENERAL + : G E N E R A L + ; + +VISIBLE + : V I S I B L E + ; + +SIGNED + : S I G N E D + ; + +SERVER + : S E R V E R + ; + +NEXT + : N E X T + ; + +ENDS + : E N D S + ; + +GLOBAL + : G L O B A L + ; + +ROOTSERVICE_LIST + : R O O T S E R V I C E '_' L I S T + ; + +SHUTDOWN + : S H U T D O W N + ; + +VERBOSE + : V E R B O S E + ; + +CLUSTER_NAME + : C L U S T E R '_' N A M E + ; + +MASTER_PORT + : M A S T E R '_' P O R T + ; + +MYSQL_ERRNO + : M Y S Q L '_' E R R N O + ; + +LOWER_COMMA + : L O W E R '_' C O M M A + ; + +XA + : X A + ; + +TIME + : T I M E + ; + +DATETIME + : D A T E T I M E + ; + +NOMINVALUE + : N O M I N V A L U E + ; + +BOOL + : B O O L + ; + +DIRECTORY + : D I R E C T O R Y + ; + +DATA_TABLE_ID + : D A T A '_' T A B L E '_' I D + ; + +SEQUENCES + : S E Q U E N C E S + ; + +PRETTY_COLOR + : P R E T T Y '_' C O L O R + ; + +VALID + : V A L I D + ; + +MASTER_SSL_KEY + : M A S T E R '_' S S L '_' K E Y + ; + +MASTER_PASSWORD + : M A S T E R '_' P A S S W O R D + ; + +PLAN + : P L A N + ; + +SHARE + : S H A R E + ; + +MULTIPOLYGON + : M U L T I P O L Y G O N + ; + +STDDEV_SAMP + : S T D D E V '_' S A M P + ; + +USE_BLOOM_FILTER + : U S E '_' B L O O M '_' F I L T E R + ; + +CONSTRAINT_CATALOG + : C O N S T R A I N T '_' C A T A L O G + ; + +CLUSTER + : C L U S T E R + ; + +EXCHANGE + : E X C H A N G E + ; + +GRANTS + : G R A N T S + ; + +CAST + : C A S T + ; + +SERVER_PORT + : S E R V E R '_' P O R T + ; + +SQL_CACHE + : S Q L '_' C A C H E + ; + +MAX_USED_PART_ID + : M A X '_' U S E D '_' P A R T '_' I D + ; + +HYBRID_HIST + : H Y B R I D '_' H I S T + ; + +INSTANCE + : I N S T A N C E + ; + +FUNCTION + : F U N C T I O N + ; + +NOWAIT + : N O W A I T + ; + +INVISIBLE + : I N V I S I B L E + ; + +DENSE_RANK + : D E N S E '_' R A N K + ; + +COUNT + : C O U N T + ; + +NAMES + : N A M E S + ; + +MY_NAME + : M Y '_' N A M E + ; + +CHAR + : C H A R + ; + +LOWER_THAN_NEG + : L O W E R '_' T H A N '_' N E G + ; + +P_ENTITY + : P '_' E N T I T Y + ; + +ISOLATE + : I S O L A T E + ; + +MAX_ROWS + : M A X '_' R O W S + ; + +CTXCAT + : C T X C A T + ; + +ISOLATION + : I S O L A T I O N + ; + +REPLICATION + : R E P L I C A T I O N + ; + +DECRYPTION + : D E C R Y P T I O N + ; + +REMOVE + : R E M O V E + ; + +STATS_AUTO_RECALC + : S T A T S '_' A U T O '_' R E C A L C + ; + +CONSISTENT_MODE + : C O N S I S T E N T '_' M O D E + ; + +MODIFY + : M O D I F Y + ; + +UNCOMMITTED + : U N C O M M I T T E D + ; + +PHYSICAL + : P H Y S I C A L + ; + +NO_WAIT + : N O '_' W A I T + ; + +BACKUP_COPIES + : B A C K U P '_' C O P I E S + ; + +UNIT_NUM + : U N I T '_' N U M + ; + +PERCENTAGE + : P E R C E N T A G E + ; + +MAX_IOPS + : M A X '_' I O P S + ; + +SPFILE + : S P F I L E + ; + +REPEATABLE + : R E P E A T A B L E + ; + +COMPLETION + : C O M P L E T I O N + ; + +CONDENSED + : C O N D E N S E D + ; + +INPUT + : I N P U T + ; + +ROOTTABLE + : R O O T T A B L E + ; + +SUBSTRING + : S U B S T R I N G + ; + +ZONE + : Z O N E + ; + +BACKED + : B A C K E D + ; + +SERVICE + : S E R V I C E + ; + +TEMPLATE + : T E M P L A T E + ; + +DATE_SUB + : D A T E '_' S U B + ; + +EXPIRE_INFO + : E X P I R E '_' I N F O + ; + +EXPIRE + : E X P I R E + ; + +ENABLE + : E N A B L E + ; + +HOSTS + : H O S T S + ; + +SCHEMA_NAME + : S C H E M A '_' N A M E + ; + +EXPANSION + : E X P A N S I O N + ; + +REORGANIZE + : R E O R G A N I Z E + ; + +BLOCK_SIZE + : B L O C K '_' S I Z E + ; + +TRIM_SPACE + : T R I M '_' S P A C E + ; + +INNER_PARSE + : I N N E R '_' P A R S E + ; + +MINOR + : M I N O R + ; + +RESUME + : R E S U M E + ; + +INT + : I N T + ; + +STATS_PERSISTENT + : S T A T S '_' P E R S I S T E N T + ; + +NODEGROUP + : N O D E G R O U P + ; + +PARTITIONING + : P A R T I T I O N I N G + ; + +BIT_AND + : B I T '_' A N D + ; + +SUPER + : S U P E R + ; + +TIMES + : T I M E S + ; + +COMMIT + : C O M M I T + ; + +SAVEPOINT + : S A V E P O I N T + ; + +UNTIL + : U N T I L + ; + +USER + : U S E R + ; + +LEAK_RATE + : L E A K '_' R A T E + ; + +MEMTABLE + : M E M T A B L E + ; + +CHARSET + : C H A R S E T + ; + +MOVE + : M O V E + ; + +XML + : X M L + ; + +PATH + : P A T H + ; + +IPC + : I P C + ; + +TRIM + : T R I M + ; + +PERFORMANCE + : P E R F O R M A N C E + ; + +RANK + : R A N K + ; + +VAR_POP + : V A R '_' P O P + ; + +DEFAULT_AUTH + : D E F A U L T '_' A U T H + ; + +EXTENT_SIZE + : E X T E N T '_' S I Z E + ; + +BINLOG + : B I N L O G + ; + +LEAK_MOD + : L E A K '_' M O D + ; + +CLOG + : C L O G + ; + +GEOMETRYCOLLECTION + : G E O M E T R Y C O L L E C T I O N + ; + +STORAGE + : S T O R A G E + ; + +MEDIUM + : M E D I U M + ; + +USE_FRM + : U S E '_' F R M + ; + +CLIENT_VERSION + : C L I E N T '_' V E R S I O N + ; + +MASTER_HEARTBEAT_PERIOD + : M A S T E R '_' H E A R T B E A T '_' P E R I O D + ; + +SUBPARTITIONS + : S U B P A R T I T I O N S + ; + +CUBE + : C U B E + ; + +FRAGMENTATION + : F R A G M E N T A T I O N + ; + +BALANCE + : B A L A N C E + ; + +QUERY + : Q U E R Y + ; + +POLICY + : P O L I C Y + ; + +THROTTLE + : T H R O T T L E + ; + +SQL_TSI_QUARTER + : S Q L '_' T S I '_' Q U A R T E R + ; + +REPAIR + : R E P A I R + ; + +MASTER_SSL_CIPHER + : M A S T E R '_' S S L '_' C I P H E R + ; + +KEY_VERSION + : K E Y '_' V E R S I O N + ; + +CATALOG_NAME + : C A T A L O G '_' N A M E + ; + +NDBCLUSTER + : N D B C L U S T E R + ; + +CONNECTION + : C O N N E C T I O N + ; + +COMPACT + : C O M P A C T + ; + +SYNCHRONIZATION + : S Y N C H R O N I Z A T I O N + ; + +AVAILABILITY + : A V A I L A B I L I T Y + ; + +INCR + : I N C R + ; + +CANCEL + : C A N C E L + ; + +SIMPLE + : S I M P L E + ; + +BEGIN + : B E G I N + ; + +VARIABLES + : V A R I A B L E S + ; + +SQL_TSI_WEEK + : S Q L '_' T S I '_' W E E K + ; + +P_CHUNK + : P '_' C H U N K + ; + +SYSTEM + : S Y S T E M + ; + +ROOTSERVICE + : R O O T S E R V I C E + ; + +PLUGIN_DIR + : P L U G I N '_' D I R + ; + +ASCII + : A S C I I + ; + +INFO + : I N F O + ; + +SKIP_HEADER + : S K I P '_' H E A D E R + ; + +SQL_THREAD + : S Q L '_' T H R E A D + ; + +TYPES + : T Y P E S + ; + +LEADER + : L E A D E R + ; + +LOWER_KEY + : L O W E R '_' K E Y + ; + +FOUND + : F O U N D + ; + +EXTRACT + : E X T R A C T + ; + +FIXED + : F I X E D + ; + +CACHE + : C A C H E + ; + +CURRENT + : C U R R E N T + ; + +STACKED + : S T A C K E D + ; + +RETURNED_SQLSTATE + : R E T U R N E D '_' S Q L S T A T E + ; + +END + : E N D + ; + +PRESERVE + : P R E S E R V E + ; + +BADFILE + : B A D F I L E + ; + +LOG_DISK_SIZE + : L O G '_' D I S K '_' S I Z E + ; + +SQL_BUFFER_RESULT + : S Q L '_' B U F F E R '_' R E S U L T + ; + +JSON + : J S O N + ; + +SOME + : S O M E + ; + +INDEX_TABLE_ID + : I N D E X '_' T A B L E '_' I D + ; + +PATTERN + : P A T T E R N + ; + +RECOVERY_WINDOW + : R E C O V E R Y '_' W I N D O W + ; + +FREQUENCY + : F R E Q U E N C Y + ; + +PQ_MAP + : P Q '_' M A P + ; + +LOCKS + : L O C K S + ; + +MANUAL + : M A N U A L + ; + +GEOMETRY + : G E O M E T R Y + ; + +IDENTIFIED + : I D E N T I F I E D + ; + +NO_PARALLEL + : N O '_' P A R A L L E L + ; + +STORAGE_FORMAT_VERSION + : S T O R A G E '_' F O R M A T '_' V E R S I O N + ; + +OVER + : O V E R + ; + +MAX_SESSION_NUM + : M A X '_' S E S S I O N '_' N U M + ; + +USER_RESOURCES + : U S E R '_' R E S O U R C E S + ; + +BACKUPROUND + : B A C K U P R O U N D + ; + +DESTINATION + : D E S T I N A T I O N + ; + +SONAME + : S O N A M E + ; + +OUTLINE + : O U T L I N E + ; + +MASTER_LOG_FILE + : M A S T E R '_' L O G '_' F I L E + ; + +NOMAXVALUE + : N O M A X V A L U E + ; + +ESTIMATE + : E S T I M A T E + ; + +SLAVE + : S L A V E + ; + +SKIP_BLANK_LINES + : S K I P '_' B L A N K '_' L I N E S + ; + +GTS + : G T S + ; + +EXPORT + : E X P O R T + ; + +AVG_ROW_LENGTH + : A V G '_' R O W '_' L E N G T H + ; + +ENFORCED + : E N F O R C E D + ; + +FLASHBACK + : F L A S H B A C K + ; + +SESSION_USER + : S E S S I O N '_' U S E R + ; + +TABLEGROUPS + : T A B L E G R O U P S + ; + +CURTIME + : C U R T I M E + ; + +REPLICA_TYPE + : R E P L I C A '_' T Y P E + ; + +AGGREGATE + : A G G R E G A T E + ; + +JSON_ARRAYAGG + : J S O N '_' A R R A Y A G G + ; + +PERCENT_RANK + : P E R C E N T '_' R A N K + ; + +ENUM + : E N U M + ; + +NATIONAL + : N A T I O N A L + ; + +RECYCLE + : R E C Y C L E + ; + +REGION + : R E G I O N + ; + +MATERIALIZE + : M A T E R I A L I Z E + ; + +MUTEX + : M U T E X + ; + +PARALLEL + : P A R A L L E L + ; + +NOPARALLEL + : N O P A R A L L E L + ; + +LOWER_PARENS + : L O W E R '_' P A R E N S + ; + +MONITOR + : M O N I T O R + ; + +NDB + : N D B + ; + +SYSTEM_USER + : S Y S T E M '_' U S E R + ; + +MAXIMIZE + : M A X I M I Z E + ; + +MAX_UPDATES_PER_HOUR + : M A X '_' U P D A T E S '_' P E R '_' H O U R + ; + +CURSOR_NAME + : C U R S O R '_' N A M E + ; + +CONCURRENT + : C O N C U R R E N T + ; + +DUMPFILE + : D U M P F I L E + ; + +COMPRESSED + : C O M P R E S S E D + ; + +LINESTRING + : L I N E S T R I N G + ; + +DYNAMIC + : D Y N A M I C + ; + +CHAIN + : C H A I N + ; + +NEG + : N E G + ; + +INCREMENT + : I N C R E M E N T + ; + +LAG + : L A G + ; + +BASELINE_ID + : B A S E L I N E '_' I D + ; + +NEW + : N E W + ; + +SQL_TSI_YEAR + : S Q L '_' T S I '_' Y E A R + ; + +THAN + : T H A N + ; + +CPU + : C P U + ; + +HOST + : H O S T + ; + +VALUE + : V A L U E + ; + +LOGS + : L O G S + ; + +SERIALIZABLE + : S E R I A L I Z A B L E + ; + +AUTO_INCREMENT + : A U T O '_' I N C R E M E N T + ; + +BACKUP + : B A C K U P + ; + +LOGFILE + : L O G F I L E + ; + +ROW_FORMAT + : R O W '_' F O R M A T + ; + +SET_MASTER_CLUSTER + : S E T '_' M A S T E R '_' C L U S T E R + ; + +MINUTE + : M I N U T E + ; + +SWAPS + : S W A P S + ; + +TASK + : T A S K + ; + +INNODB + : I N N O D B + ; + +IO_THREAD + : I O '_' T H R E A D + ; + +HISTOGRAM + : H I S T O G R A M + ; + +PCTFREE + : P C T F R E E + ; + +BC2HOST + : B C '2' H O S T + ; + +PARAMETERS + : P A R A M E T E R S + ; + +TABLESPACE + : T A B L E S P A C E + ; + +OBCONFIG_URL + : O B C O N F I G '_' U R L + ; + +AUTO + : A U T O + ; + +PASSWORD + : P A S S W O R D + ; + +LOWER_THAN_BY_ACCESS_SESSION + : L O W E R '_' T H A N '_' B Y '_' A C C E S S '_' S E S S I O N + ; + +ROW + : R O W + ; + +MESSAGE_TEXT + : M E S S A G E '_' T E X T + ; + +DISK + : D I S K + ; + +FAULTS + : F A U L T S + ; + +HOUR + : H O U R + ; + +REFRESH + : R E F R E S H + ; + +COLUMN_STAT + : C O L U M N '_' S T A T + ; + +ANY + : A N Y + ; + +UNIT_GROUP + : U N I T '_' G R O U P + ; + +HIGHER_PARENS + : H I G H E R '_' P A R E N S + ; + +ERROR_CODE + : E R R O R '_' C O D E + ; + +PHASE + : P H A S E + ; + +ENTITY + : E N T I T Y + ; + +PROFILE + : P R O F I L E + ; + +LAST_VALUE + : L A S T '_' V A L U E + ; + +RESTART + : R E S T A R T + ; + +TRACE + : T R A C E + ; + +LOGICAL_READS + : L O G I C A L '_' R E A D S + ; + +DATE_ADD + : D A T E '_' A D D + ; + +BLOCK_INDEX + : B L O C K '_' I N D E X + ; + +SERVER_IP + : S E R V E R '_' I P + ; + +CODE + : C O D E + ; + +PLUGINS + : P L U G I N S + ; + +ADDDATE + : A D D D A T E + ; + +VIRTUAL_COLUMN_ID + : V I R T U A L '_' C O L U M N '_' I D + ; + +COLUMN_FORMAT + : C O L U M N '_' F O R M A T + ; + +MAX_MEMORY + : M A X '_' M E M O R Y + ; + +NESTED + : N E S T E D + ; + +CLEAN + : C L E A N + ; + +MASTER_SSL + : M A S T E R '_' S S L + ; + +CLEAR + : C L E A R + ; + +END_OUTLINE_DATA + : E N D '_' O U T L I N E '_' D A T A + ; + +SORTKEY + : S O R T K E Y + ; + +CHECKSUM + : C H E C K S U M + ; + +INSTALL + : I N S T A L L + ; + +MONTH + : M O N T H + ; + +AFTER + : A F T E R + ; + +CLOSE + : C L O S E + ; + +JSON_OBJECTAGG + : J S O N '_' O B J E C T A G G + ; + +SET_TP + : S E T '_' T P + ; + +OWNER + : O W N E R + ; + +BLOOM_FILTER + : B L O O M '_' F I L T E R + ; + +ILOG + : I L O G + ; + +META + : M E T A + ; + +STARTS + : S T A R T S + ; + +PLANREGRESS + : P L A N R E G R E S S + ; + +AUTOEXTEND_SIZE + : A U T O E X T E N D '_' S I Z E + ; + +TABLET_ID + : T A B L E T '_' I D + ; + +SOURCE + : S O U R C E + ; + +POW + : P O W + ; + +IGNORE_SERVER_IDS + : I G N O R E '_' S E R V E R '_' I D S + ; + +REPLICA_NUM + : R E P L I C A '_' N U M + ; + +LOWER_THAN_COMP + : L O W E R '_' T H A N '_' C O M P + ; + +BINDING + : B I N D I N G + ; + +MICROSECOND + : M I C R O S E C O N D + ; + +UNDO_BUFFER_SIZE + : U N D O '_' B U F F E R '_' S I Z E + ; + +SWITCHOVER + : S W I T C H O V E R + ; + +EXTENDED_NOADDR + : E X T E N D E D '_' N O A D D R + ; + +GLOBAL_NAME + : G L O B A L '_' N A M E + ; + +SPLIT + : S P L I T + ; + +BASELINE + : B A S E L I N E + ; + +MEMORY + : M E M O R Y + ; + +DESCRIPTION + : D E S C R I P T I O N + ; + +SEED + : S E E D + ; + +RTREE + : R T R E E + ; + +RESOURCE + : R E S O U R C E + ; + +STDDEV_POP + : S T D D E V '_' P O P + ; + +RUN + : R U N + ; + +OBSOLETE + : O B S O L E T E + ; + +SQL_AFTER_GTIDS + : S Q L '_' A F T E R '_' G T I D S + ; + +OPEN + : O P E N + ; + +SQL_TSI_DAY + : S Q L '_' T S I '_' D A Y + ; + +STRING + : S T R I N G + ; + +RELAY_THREAD + : R E L A Y '_' T H R E A D + ; + +BREADTH + : B R E A D T H + ; + +NOCACHE + : N O C A C H E + ; + +PRIMARY_ROOTSERVICE_LIST + : P R I M A R Y '_' R O O T S E R V I C E '_' L I S T + ; + +UNUSUAL + : U N U S U A L + ; + +RELAYLOG + : R E L A Y L O G + ; + +SQL_BEFORE_GTIDS + : S Q L '_' B E F O R E '_' G T I D S + ; + +PRIMARY_ZONE + : P R I M A R Y '_' Z O N E + ; + +TABLE_CHECKSUM + : T A B L E '_' C H E C K S U M + ; + +ZONE_LIST + : Z O N E '_' L I S T + ; + +DATABASE_ID + : D A T A B A S E '_' I D + ; + +TP_NO + : T P '_' N O + ; + +NETWORK + : N E T W O R K + ; + +PROTECTION + : P R O T E C T I O N + ; + +HIDDEN_ + : H I D D E N + ; + +BOOLEAN + : B O O L E A N + ; + +AVG + : A V G + ; + +MULTILINESTRING + : M U L T I L I N E S T R I N G + ; + +APPROX_COUNT_DISTINCT_SYNOPSIS_MERGE + : A P P R O X '_' C O U N T '_' D I S T I N C T '_' S Y N O P S I S '_' M E R G E + ; + +NOW + : N O W + ; + +BIT_OR + : B I T '_' O R + ; + +PROXY + : P R O X Y + ; + +DUPLICATE_SCOPE + : D U P L I C A T E '_' S C O P E + ; + +STATS_SAMPLE_PAGES + : S T A T S '_' S A M P L E '_' P A G E S + ; + +TABLET_SIZE + : T A B L E T '_' S I Z E + ; + +BASE + : B A S E + ; + +KVCACHE + : K V C A C H E + ; + +RELAY + : R E L A Y + ; + +MEMORY_SIZE + : M E M O R Y '_' S I Z E + ; + +CONTRIBUTORS + : C O N T R I B U T O R S + ; + +EMPTY + : E M P T Y + ; + +PARTIAL + : P A R T I A L + ; + +REPORT + : R E P O R T + ; + +ESCAPE + : E S C A P E + ; + +MASTER_AUTO_POSITION + : M A S T E R '_' A U T O '_' P O S I T I O N + ; + +DISKGROUP + : D I S K G R O U P + ; + +CALC_PARTITION_ID + : C A L C '_' P A R T I T I O N '_' I D + ; + +TP_NAME + : T P '_' N A M E + ; + +ACTIVATE + : A C T I V A T E + ; + +SQL_AFTER_MTS_GAPS + : S Q L '_' A F T E R '_' M T S '_' G A P S + ; + +EFFECTIVE + : E F F E C T I V E + ; + +FIRST_VALUE + : F I R S T '_' V A L U E + ; + +SQL_TSI_MINUTE + : S Q L '_' T S I '_' M I N U T E + ; + +UNICODE + : U N I C O D E + ; + +QUARTER + : Q U A R T E R + ; + +ANALYSE + : A N A L Y S E + ; + +DEFINER + : D E F I N E R + ; + +NONE + : N O N E + ; + +PROCESSLIST + : P R O C E S S L I S T + ; + +TYPE + : T Y P E + ; + +INSERT_METHOD + : I N S E R T '_' M E T H O D + ; + +EXTENDED + : E X T E N D E D + ; + +LOG + : L O G + ; + +WHENEVER + : W H E N E V E R + ; + +LEVEL + : L E V E L + ; + +TIME_ZONE_INFO + : T I M E '_' Z O N E '_' I N F O + ; + +TIMESTAMPADD + : T I M E S T A M P A D D + ; + +LOWER_INTO + : L O W E R '_' I N T O + ; + +GET_FORMAT + : G E T '_' F O R M A T + ; + +PREPARE + : P R E P A R E + ; + +MATERIALIZED + : M A T E R I A L I Z E D + ; + +STANDBY + : S T A N D B Y + ; + +WORK + : W O R K + ; + +HANDLER + : H A N D L E R + ; + +CUME_DIST + : C U M E '_' D I S T + ; + +LEAK + : L E A K + ; + +INITIAL_SIZE + : I N I T I A L '_' S I Z E + ; + +RELAY_LOG_FILE + : R E L A Y '_' L O G '_' F I L E + ; + +STORING + : S T O R I N G + ; + +IMPORT + : I M P O R T + ; + +MIN_MEMORY + : M I N '_' M E M O R Y + ; + +HELP + : H E L P + ; + +CREATE_TIMESTAMP + : C R E A T E '_' T I M E S T A M P + ; + +COMPUTE + : C O M P U T E + ; + +RANDOM + : R A N D O M + ; + +SOUNDS + : S O U N D S + ; + +TABLE_MODE + : T A B L E '_' M O D E + ; + +COPY + : C O P Y + ; + +SESSION + : S E S S I O N + ; + +DAG + : D A G + ; + +NOCYCLE + : N O C Y C L E + ; + +SQL_NO_CACHE + : S Q L '_' N O '_' C A C H E + ; + +EXECUTE + : E X E C U T E + ; + +PRECEDING + : P R E C E D I N G + ; + +SWITCHES + : S W I T C H E S + ; + +PACK_KEYS + : P A C K '_' K E Y S + ; + +ENABLE_EXTENDED_ROWID + : E N A B L E '_' E X T E N D E D '_' R O W I D + ; + +SQL_ID + : S Q L '_' I D + ; + +NOORDER + : N O O R D E R + ; + +TENANT_ID + : T E N A N T '_' I D + ; + +CHECKPOINT + : C H E C K P O I N T + ; + +DAY + : D A Y + ; + +GROUP_CONCAT + : G R O U P '_' C O N C A T + ; + +JSON_TABLE + : J S O N '_' T A B L E + ; + +LEAD + : L E A D + ; + +EVENTS + : E V E N T S + ; + +RECURSIVE + : R E C U R S I V E + ; + +ONLY + : O N L Y + ; + +TABLEGROUP_ID + : T A B L E G R O U P '_' I D + ; + +TOP_K_FRE_HIST + : T O P '_' K '_' F R E '_' H I S T + ; + +MASTER_SSL_CRL + : M A S T E R '_' S S L '_' C R L + ; + +RESOURCE_POOL_LIST + : R E S O U R C E '_' P O O L '_' L I S T + ; + +TRACING + : T R A C I N G + ; + +NTILE + : N T I L E + ; + +NULL_IF_EXETERNAL + : N U L L '_' I F '_' E X E T E R N A L + ; + +BUCKETS + : B U C K E T S + ; + +SKEWONLY + : S K E W O N L Y + ; + +IS_TENANT_SYS_POOL + : I S '_' T E N A N T '_' S Y S '_' P O O L + ; + +INLINE + : I N L I N E + ; + +SCHEDULE + : S C H E D U L E + ; + +JOB + : J O B + ; + +SRID + : S R I D + ; + +MASTER_LOG_POS + : M A S T E R '_' L O G '_' P O S + ; + +SUBCLASS_ORIGIN + : S U B C L A S S '_' O R I G I N + ; + +MULTIPOINT + : M U L T I P O I N T + ; + +BLOCK + : B L O C K + ; + +SQL_TSI_SECOND + : S Q L '_' T S I '_' S E C O N D + ; + +DATE + : D A T E + ; + +ROLLUP + : R O L L U P + ; + +MIN_CPU + : M I N '_' C P U + ; + +OCCUR + : O C C U R + ; + +DATA + : D A T A + ; + +SUCCESSFUL + : S U C C E S S F U L + ; + +REDO_TRANSPORT_OPTIONS + : R E D O '_' T R A N S P O R T '_' O P T I O N S + ; + +FIELD_DELIMITER + : F I E L D '_' D E L I M I T E R + ; + +MASTER_HOST + : M A S T E R '_' H O S T + ; + +VAR_SAMP + : V A R '_' S A M P + ; + +ALGORITHM + : A L G O R I T H M + ; + +EXPIRED + : E X P I R E D + ; + +CONSTRAINT_NAME + : C O N S T R A I N T '_' N A M E + ; + +APPROX_COUNT_DISTINCT + : A P P R O X '_' C O U N T '_' D I S T I N C T + ; + +BASIC + : B A S I C + ; + +DEFAULT_TABLEGROUP + : D E F A U L T '_' T A B L E G R O U P + ; + +LIST_ + : L I S T + ; + +NO_PX_JOIN_FILTER + : N O '_' P X '_' J O I N '_' F I L T E R + ; + +WEEK + : W E E K + ; + +LINK + : L I N K + ; + +STATEMENT_ID + : S T A T E M E N T '_' I D + ; + +NULLS + : N U L L S + ; + +MASTER_SSL_CRLPATH + : M A S T E R '_' S S L '_' C R L P A T H + ; + +CASCADED + : C A S C A D E D + ; + +PLUGIN + : P L U G I N + ; + +ENCRYPTED + : E N C R Y P T E D + ; + +TENANT + : T E N A N T + ; + +DECIMAL_VAL + : ([0-9]+ E [-+]?[0-9]+ | [0-9]+'.'[0-9]* E [-+]?[0-9]+ | '.'[0-9]+ E [-+]?[0-9]+) + | ([0-9]+'.'[0-9]* | '.'[0-9]+) + ; + +BOOL_VALUE + : T R U E + | F A L S E + ; + +LOG_RESTORE_SOURCE + : L O G '_' R E S T O R E '_' S O U R C E + ; + +ENABLE_ARBITRATION_SERVICE + : E N A B L E '_' A R B I T R A T I O N '_' S E R V I C E + ; + +At + : '@' + ; + +LeftBrace + : '{' + ; + +RightBrace + : '}' + ; + +Quote + : '\'' + ; + +PARSER_SYNTAX_ERROR + : X '\''([0-9A-F])*'\''|'0' X ([0-9A-F])+ + ; + +HEX_STRING_VALUE + : B '\''([01])*'\''|'0' B ([01])+ + ; + +DATE_VALUE + : D A T E ([ \t\n\r\f]+|('--'[ \t\n\r\f]+(~[\n\r])*)|('#'(~[\n\r])*))?'\''(~['])*'\'' + | T I M E ([ \t\n\r\f]+|('--'[ \t\n\r\f]+(~[\n\r])*)|('#'(~[\n\r])*))?'\''(~['])*'\'' + | T I M E S T A M P ([ \t\n\r\f]+|('--'[ \t\n\r\f]+(~[\n\r])*)|('#'(~[\n\r])*))?'\''(~['])*'\'' + | D A T E ([ \t\n\r\f]+|('--'[ \t\n\r\f]+(~[\n\r])*)|('#'(~[\n\r])*))?'"'(~["])*'"' + | T I M E ([ \t\n\r\f]+|('--'[ \t\n\r\f]+(~[\n\r])*)|('#'(~[\n\r])*))?'"'(~["])*'"' + | T I M E S T A M P ([ \t\n\r\f]+|('--'[ \t\n\r\f]+(~[\n\r])*)|('#'(~[\n\r])*))?'"'(~["])*'"' + ; + +HINT_VALUE + : '/''*' H I N T '+'(~[*])+'*''/' + ; + +//c_ret +// : '*''/' -> mode(DEFAULT_MODE) +// ; + +Comma + : [,] + ; + +Plus + : [+] + ; + +And + : [&] + ; + +Or + : [|] + ; + +Star + : [*] + ; + +Not + : [!] + ; + +LeftParen + : [(] + ; + +Minus + : [-] + ; + +Div + : [/] + ; + +Caret + : [^] + ; + +Colon + : [:] + ; + +Dot + : [.] + ; + +Mod + : [%] + ; + +RightParen + : [)] + ; + +Tilde + : [~] + ; + +DELIMITER + : [;] + ; + +CNNOP + : '||' + ; + +AND_OP + : '&&' + ; + +COMP_EQ + : '=' + ; + +SET_VAR + : ':=' + ; + +COMP_NSEQ + : '<=>' + ; + +COMP_GE + : '>=' + ; + +COMP_GT + : '>' + ; + +COMP_LE + : '<=' + ; + +COMP_LT + : '<' + ; + +COMP_NE + : '!=' | '<>' + ; + +SHIFT_LEFT + : '<<' + ; + +SHIFT_RIGHT + : '>>' + ; + +JSON_EXTRACT + : '->' + ; + +JSON_EXTRACT_UNQUOTED + : '->>' + ; + +QUESTIONMARK + : '?' + | ':'[0-9]+ + | ':'(([A-Za-z0-9$_]|(~[\u0000-\u007F\uD800-\uDBFF]))+)'.'(([A-Za-z0-9$_]|(~[\u0000-\u007F\uD800-\uDBFF]))+) + ; + +SYSTEM_VARIABLE + : ('@''@'[A-Za-z_][A-Za-z0-9_]*) + ; + +USER_VARIABLE + : ('@'[A-Za-z0-9_.$]*)|('@'[`'"][`'"A-Za-z0-9_.$/%]*) + ; + +NAME_OB + : (([A-Za-z0-9$_]|(~[\u0000-\u007F\uD800-\uDBFF]))+) + | '`' ~[`]* '`' + ; + +STRING_VALUE + : '\'' (~['\\]|('\'\'')|('\\'.))* '\'' + | '"' (~["\\]|('""')|('\\'.))* '"' + + ; + +In_c_comment + : '/*' .*? '*/' -> channel(1) + ; + +ANTLR_SKIP + : '--'[ \t]* .*? '\n' -> channel(1) + ; + +Blank + : [ \t\r\n] -> channel(1) ; + + + +fragment A : [aA]; +fragment B : [bB]; +fragment C : [cC]; +fragment D : [dD]; +fragment E : [eE]; +fragment F : [fF]; +fragment G : [gG]; +fragment H : [hH]; +fragment I : [iI]; +fragment J : [jJ]; +fragment K : [kK]; +fragment L : [lL]; +fragment M : [mM]; +fragment N : [nN]; +fragment O : [oO]; +fragment P : [pP]; +fragment Q : [qQ]; +fragment R : [rR]; +fragment S : [sS]; +fragment T : [tT]; +fragment U : [uU]; +fragment V : [vV]; +fragment W : [wW]; +fragment X : [xX]; +fragment Y : [yY]; +fragment Z : [zZ]; + diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/antlr4/com/aliyun/fastmodel/transform/oceanbase/mysql/parser/OBParser.g4 b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/antlr4/com/aliyun/fastmodel/transform/oceanbase/mysql/parser/OBParser.g4 new file mode 100644 index 0000000..2bca885 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/antlr4/com/aliyun/fastmodel/transform/oceanbase/mysql/parser/OBParser.g4 @@ -0,0 +1,4652 @@ +/* + * Copyright (c) 2023 OceanBase. + * + * Licensed 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. + */ + +parser grammar OBParser; + + +options { tokenVocab=OBLexer; } + +@parser::members { +public boolean is_pl_parse_ = false; +public boolean is_pl_parse_expr_ = false; +} + + +// start rule: sql_stmt + +sql_stmt + : stmt_list + ; + +stmt_list + : EOF + | DELIMITER + | stmt EOF + | stmt DELIMITER EOF? + ; + +stmt + : select_stmt + | insert_stmt + | create_table_stmt + | create_function_stmt + | drop_function_stmt + | drop_procedure_stmt + | drop_trigger_stmt + | create_table_like_stmt + | create_database_stmt + | drop_database_stmt + | alter_database_stmt + | use_database_stmt + | update_stmt + | delete_stmt + | drop_table_stmt + | drop_view_stmt + | explain_stmt + | create_outline_stmt + | alter_outline_stmt + | drop_outline_stmt + | show_stmt + | prepare_stmt + | variable_set_stmt + | execute_stmt + | alter_table_stmt + | alter_system_stmt + | audit_stmt + | deallocate_prepare_stmt + | create_user_stmt + | drop_user_stmt + | set_password_stmt + | rename_user_stmt + | lock_user_stmt + | grant_stmt + | revoke_stmt + | begin_stmt + | commit_stmt + | rollback_stmt + | create_tablespace_stmt + | drop_tablespace_stmt + | alter_tablespace_stmt + | rotate_master_key_stmt + | create_index_stmt + | drop_index_stmt + | kill_stmt + | help_stmt + | create_view_stmt + | create_tenant_stmt + | create_standby_tenant_stmt + | alter_tenant_stmt + | drop_tenant_stmt + | create_restore_point_stmt + | drop_restore_point_stmt + | create_resource_stmt + | alter_resource_stmt + | drop_resource_stmt + | set_names_stmt + | set_charset_stmt + | create_tablegroup_stmt + | drop_tablegroup_stmt + | alter_tablegroup_stmt + | rename_table_stmt + | truncate_table_stmt + | set_transaction_stmt + | create_savepoint_stmt + | rollback_savepoint_stmt + | release_savepoint_stmt + | lock_tables_stmt + | unlock_tables_stmt + | flashback_stmt + | purge_stmt + | analyze_stmt + | load_data_stmt + | create_dblink_stmt + | drop_dblink_stmt + | create_sequence_stmt + | alter_sequence_stmt + | drop_sequence_stmt + | xa_begin_stmt + | xa_end_stmt + | xa_prepare_stmt + | xa_commit_stmt + | xa_rollback_stmt + | switchover_cluster_stmt + | disconnect_cluster_stmt + | alter_cluster_stmt + | optimize_stmt + | dump_memory_stmt + | protection_mode_stmt + | get_diagnostics_stmt + | pl_expr_stmt + | method_opt + | switchover_tenant_stmt + | recover_tenant_stmt + ; + +pl_expr_stmt + : DO expr + ; + +switchover_tenant_stmt + : ALTER SYSTEM switchover_clause + ; + +switchover_clause + : ACTIVATE STANDBY tenant_name? + | SWITCHOVER TO PRIMARY tenant_name? + | SWITCHOVER TO STANDBY tenant_name? + ; + +recover_tenant_stmt + : ALTER SYSTEM RECOVER STANDBY tenant_name? recover_point_clause? + ; + +recover_point_clause + : UNTIL TIME COMP_EQ STRING_VALUE + | UNTIL SCN COMP_EQ INTNUM + | UNTIL UNLIMITED + | CANCEL + ; + +expr_list + : expr (Comma expr)* + ; + +expr_as_list + : expr_with_opt_alias (Comma expr_with_opt_alias)* + ; + +expr_with_opt_alias + : expr + | expr AS? (column_label|STRING_VALUE) + ; + +column_ref + : column_name + | (Dot?|relation_name Dot) (relation_name|mysql_reserved_keyword) Dot (column_name|mysql_reserved_keyword|Star) + ; + +complex_string_literal + : charset_introducer? STRING_VALUE + | charset_introducer PARSER_SYNTAX_ERROR + | STRING_VALUE string_val_list + | NATIONAL_LITERAL + ; + +charset_introducer + : UnderlineUTF8 + | UnderlineUTF8MB4 + | UnderlineBINARY + | UnderlineGBK + | UnderlineLATIN1 + | UnderlineGB18030 + | UnderlineGB18030_2022 + | UnderlineUTF16 + ; + +literal + : complex_string_literal + | DATE_VALUE + | TIMESTAMP_VALUE + | INTNUM + | HEX_STRING_VALUE + | APPROXNUM + | DECIMAL_VAL + | BOOL_VALUE + | NULLX + | PARSER_SYNTAX_ERROR + ; + +number_literal + : INTNUM + | DECIMAL_VAL + ; + +expr_const + : literal + | SYSTEM_VARIABLE + | QUESTIONMARK + | global_or_session_alias Dot column_name + ; + +conf_const + : STRING_VALUE + | DATE_VALUE + | TIMESTAMP_VALUE + | Minus? INTNUM + | APPROXNUM + | Minus? DECIMAL_VAL + | BOOL_VALUE + | NULLX + | SYSTEM_VARIABLE + | global_or_session_alias Dot column_name + ; + +global_or_session_alias + : GLOBAL_ALIAS + | SESSION_ALIAS + ; + +bool_pri + : predicate + | bool_pri (COMP_EQ|COMP_GE|COMP_GT|COMP_LE|COMP_LT|COMP_NE|COMP_NSEQ) predicate + | bool_pri IS not? NULLX + | bool_pri (COMP_EQ|COMP_GE|COMP_GT|COMP_LE|COMP_LT|COMP_NE) (ALL|ANY|SOME) LeftParen select_no_parens RightParen + ; + + +predicate + : bit_expr not? IN in_expr + | bit_expr not? BETWEEN bit_expr AND predicate + | bit_expr not? LIKE (simple_expr|string_val_list) ((ESCAPE simple_expr)?|ESCAPE string_val_list) + | bit_expr not? REGEXP (string_val_list|bit_expr) + | bit_expr MEMBER OF LeftParen simple_expr RightParen + | bit_expr + ; + +string_val_list + : STRING_VALUE+ + ; + +bit_expr + : INTERVAL expr date_unit Plus bit_expr + | simple_expr + | bit_expr (And|Caret|DIV|Div|MOD|Minus|Mod|Or|Plus|SHIFT_LEFT|SHIFT_RIGHT|Star) bit_expr + | bit_expr (Minus|Plus) INTERVAL expr date_unit + ; + +simple_expr + : simple_expr collation + | column_ref + | expr_const + | simple_expr CNNOP simple_expr + | (BINARY|Plus|Minus|Tilde|Not|NOT) simple_expr + | ROW? LeftParen expr_list RightParen + | EXISTS? select_with_parens + | MATCH LeftParen column_list RightParen AGAINST LeftParen STRING_VALUE ((IN NATURAL LANGUAGE MODE) | (IN BOOLEAN MODE))? RightParen + | case_expr + | func_expr + | window_function + | LeftBrace relation_name expr RightBrace + | USER_VARIABLE + | column_definition_ref (JSON_EXTRACT|JSON_EXTRACT_UNQUOTED) complex_string_literal + | relation_name Dot relation_name (Dot relation_name)? USER_VARIABLE + ; + +expr + : (NOT|USER_VARIABLE SET_VAR) expr + | LeftParen expr RightParen + | bool_pri (IS not? (BOOL_VALUE|UNKNOWN))? + | expr (AND|AND_OP|CNNOP|OR|XOR) expr + ; + +not + : NOT + ; + + +//sub_query_flag +// : ALL +// | ANY +// | SOME +// ; + +in_expr + : select_with_parens + | LeftParen expr_list RightParen + ; + +case_expr + : CASE expr? when_clause_list case_default? END + ; + +window_function + : func_name=COUNT LeftParen ALL? (Star|expr) RightParen OVER new_generalized_window_clause + | func_name=COUNT LeftParen DISTINCT expr_list RightParen OVER new_generalized_window_clause + | func_name=(APPROX_COUNT_DISTINCT|APPROX_COUNT_DISTINCT_SYNOPSIS|NTILE) LeftParen expr_list RightParen OVER new_generalized_window_clause + | func_name=(SUM|MAX|MIN|AVG|JSON_ARRAYAGG|APPROX_COUNT_DISTINCT_SYNOPSIS_MERGE) LeftParen (ALL | DISTINCT | UNIQUE)? expr RightParen OVER new_generalized_window_clause + | func_name=JSON_OBJECTAGG LeftParen expr Comma expr RightParen OVER new_generalized_window_clause + | func_name=(STD|STDDEV|VARIANCE|STDDEV_POP|STDDEV_SAMP|VAR_POP|VAR_SAMP|BIT_AND|BIT_OR|BIT_XOR) LeftParen ALL? expr RightParen OVER new_generalized_window_clause + | func_name=(GROUP_CONCAT|LISTAGG) LeftParen (DISTINCT | UNIQUE)? expr_list order_by? (SEPARATOR STRING_VALUE)? RightParen OVER new_generalized_window_clause + | func_name=(RANK|DENSE_RANK|PERCENT_RANK|ROW_NUMBER|CUME_DIST) LeftParen RightParen OVER new_generalized_window_clause + | func_name=(FIRST_VALUE|LAST_VALUE|LEAD|LAG) win_fun_first_last_params OVER new_generalized_window_clause + | func_name=NTH_VALUE LeftParen expr Comma expr RightParen (FROM first_or_last)? (respect_or_ignore NULLS)? OVER new_generalized_window_clause + | func_name=TOP_K_FRE_HIST LeftParen bit_expr Comma bit_expr Comma bit_expr RightParen OVER new_generalized_window_clause + | func_name=HYBRID_HIST LeftParen bit_expr Comma bit_expr RightParen OVER new_generalized_window_clause + ; + +first_or_last + : FIRST + | LAST + ; + +respect_or_ignore + : RESPECT + | IGNORE + ; + +win_fun_first_last_params + : LeftParen expr respect_or_ignore NULLS RightParen + | LeftParen expr RightParen (respect_or_ignore NULLS)? + ; + + +new_generalized_window_clause + : NAME_OB + | new_generalized_window_clause_with_blanket + ; + +new_generalized_window_clause_with_blanket + : LeftParen NAME_OB? generalized_window_clause RightParen + ; + +named_windows + : named_window (Comma named_window)* + ; + +named_window + : NAME_OB AS new_generalized_window_clause_with_blanket + ; + +generalized_window_clause + : (PARTITION BY expr_list)? order_by? win_window? + ; + +win_rows_or_range + : ROWS + | RANGE + ; + +win_preceding_or_following + : PRECEDING + | FOLLOWING + ; + +win_interval + : expr + | INTERVAL expr date_unit + ; + +win_bounding + : CURRENT ROW + | win_interval win_preceding_or_following + ; + +win_window + : win_rows_or_range BETWEEN win_bounding AND win_bounding + | win_rows_or_range win_bounding + ; + + +when_clause_list + : when_clause+ + ; + +when_clause + : WHEN expr THEN expr + ; + +case_default + : ELSE expr + //| empty + ; + +func_expr + : func_name=COUNT LeftParen ALL? (Star|expr) RightParen # simple_func_expr + | func_name=COUNT LeftParen (DISTINCT|UNIQUE) expr_list RightParen # simple_func_expr + | func_name=(APPROX_COUNT_DISTINCT|APPROX_COUNT_DISTINCT_SYNOPSIS|CHARACTER) LeftParen expr_list RightParen # simple_func_expr + | func_name=(SUM|MAX|MIN|AVG|JSON_ARRAYAGG) LeftParen (ALL | DISTINCT | UNIQUE)? expr RightParen # simple_func_expr + | func_name=(COUNT|STD|STDDEV|VARIANCE|STDDEV_POP|STDDEV_SAMP|VAR_POP|VAR_SAMP|BIT_AND|BIT_OR|BIT_XOR) LeftParen ALL? expr RightParen # simple_func_expr + | func_name=(GROUPING|ISNULL|DATE|YEAR|TIME|MONTH|WEEK|DAY|TIMESTAMP) LeftParen expr RightParen # simple_func_expr + | GROUP_CONCAT LeftParen (DISTINCT | UNIQUE)? expr_list order_by? (SEPARATOR STRING_VALUE)? RightParen # complex_func_expr + | func_name=TOP_K_FRE_HIST LeftParen bit_expr Comma bit_expr Comma bit_expr RightParen # simple_func_expr + | func_name=HYBRID_HIST LeftParen bit_expr Comma bit_expr RightParen # simple_func_expr + | func_name=IF LeftParen expr Comma expr Comma expr RightParen # simple_func_expr + | cur_timestamp_func # complex_func_expr + | sysdate_func # complex_func_expr + | cur_time_func # complex_func_expr + | cur_date_func # complex_func_expr + | utc_timestamp_func # complex_func_expr + | utc_time_func # complex_func_expr + | utc_date_func # complex_func_expr + | CAST LeftParen expr AS cast_data_type RightParen # complex_func_expr + | func_name=INSERT LeftParen expr Comma expr Comma expr Comma expr RightParen # simple_func_expr + | CONVERT LeftParen expr Comma cast_data_type RightParen # complex_func_expr + | CONVERT LeftParen expr USING charset_name RightParen # complex_func_expr + | POSITION LeftParen bit_expr IN expr RightParen # complex_func_expr + | substr_or_substring LeftParen substr_params RightParen # complex_func_expr + | TRIM LeftParen parameterized_trim RightParen # complex_func_expr + | func_name=(ADDDATE|SUBDATE|LEFT|TIMESTAMP|WEEK|LOG|MOD|JSON_OBJECTAGG) LeftParen expr Comma expr RightParen # simple_func_expr + | func_name=(QUARTER|SECOND|MINUTE|MICROSECOND|HOUR|ASCII|LOG|LN|APPROX_COUNT_DISTINCT_SYNOPSIS_MERGE) LeftParen expr RightParen # simple_func_expr + | GET_FORMAT LeftParen get_format_unit Comma expr RightParen # complex_func_expr + | (DATE_ADD|DATE_SUB|ADDDATE|SUBDATE) LeftParen date_params RightParen # complex_func_expr + | func_name=SUBDATE LeftParen expr Comma expr RightParen # simple_func_expr + | (TIMESTAMPDIFF|TIMESTAMPADD) LeftParen timestamp_params RightParen # complex_func_expr + | EXTRACT LeftParen date_unit FROM expr RightParen # complex_func_expr + | func_name=(DEFAULT|VALUES) LeftParen column_definition_ref RightParen # simple_func_expr + | CHARACTER LeftParen expr_list USING charset_name RightParen # complex_func_expr + | function_name LeftParen expr_as_list? RightParen # simple_func_expr + | relation_name Dot function_name LeftParen expr_as_list? RightParen # simple_func_expr + | sys_interval_func # complex_func_expr + | func_name=CALC_PARTITION_ID LeftParen bit_expr Comma bit_expr RightParen # simple_func_expr + | func_name=CALC_PARTITION_ID LeftParen bit_expr Comma bit_expr Comma bit_expr RightParen # simple_func_expr + | WEIGHT_STRING LeftParen expr (AS CHARACTER ws_nweights)? (LEVEL ws_level_list_or_range)? RightParen # complex_func_expr + | WEIGHT_STRING LeftParen expr AS BINARY ws_nweights RightParen # complex_func_expr + | WEIGHT_STRING LeftParen expr Comma INTNUM Comma INTNUM Comma INTNUM Comma INTNUM RightParen # complex_func_expr + | json_value_expr # complex_func_expr + | func_name=POINT LeftParen expr Comma expr RightParen # simple_func_expr + | func_name=LINESTRING LeftParen expr_list RightParen # simple_func_expr + | func_name=MULTIPOINT LeftParen expr_list RightParen # simple_func_expr + | func_name=MULTILINESTRING LeftParen expr_list RightParen # simple_func_expr + | func_name=POLYGON LeftParen expr_list RightParen # simple_func_expr + | func_name=MULTIPOLYGON LeftParen expr_list RightParen # simple_func_expr + | func_name=GEOMETRYCOLLECTION LeftParen expr_list? RightParen # simple_func_expr + | func_name=GEOMCOLLECTION LeftParen expr_list? RightParen # simple_func_expr + ; + +sys_interval_func + : INTERVAL LeftParen expr (Comma expr)+ RightParen + | CHECK LeftParen expr RightParen + ; + +utc_timestamp_func + : UTC_TIMESTAMP (LeftParen INTNUM? RightParen)? + ; + +utc_time_func + : UTC_TIME (LeftParen INTNUM? RightParen)? + ; + +utc_date_func + : UTC_DATE (LeftParen RightParen)? + ; + +sysdate_func + : SYSDATE LeftParen INTNUM? RightParen + ; + +cur_timestamp_func + : (now_synonyms_func|NOW) (LeftParen INTNUM? RightParen)? + ; + +now_synonyms_func + : CURRENT_TIMESTAMP + | LOCALTIME + | LOCALTIMESTAMP + ; + +cur_time_func + : (CURTIME|CURTIME|CURRENT_TIME) LeftParen INTNUM? RightParen + ; + +cur_date_func + : (CURDATE|CURRENT_DATE) LeftParen RightParen + | CURRENT_DATE + ; + +substr_or_substring + : SUBSTR + | SUBSTRING + ; + +substr_params + : expr Comma expr (Comma expr)? + | expr FROM expr (FOR expr)? + ; + +date_params + : expr Comma INTERVAL expr date_unit + ; + +timestamp_params + : date_unit Comma expr Comma expr + ; + +ws_level_list_or_range + : ws_level_list + | ws_level_range + ; + +ws_level_list + : ws_level_list_item (Comma ws_level_list_item)* + ; + +ws_level_list_item + : ws_level_number ws_level_flags + ; + +ws_level_range + : ws_level_number Minus ws_level_number + ; + +ws_level_number + : INTNUM + ; + +ws_level_flags + : empty + | ws_level_flag_desc ws_level_flag_reverse? + | ws_level_flag_reverse + ; + +ws_nweights + : LeftParen INTNUM RightParen + ; + +ws_level_flag_desc + : ASC + | DESC + ; + +ws_level_flag_reverse + : REVERSE + ; + +delete_stmt + : with_clause? delete_basic_stmt + ; + +delete_basic_stmt + : delete_with_opt_hint FROM tbl_name (WHERE opt_hint_value expr)? order_by? limit_clause? + | delete_with_opt_hint multi_delete_table (WHERE opt_hint_value expr)? + ; + +multi_delete_table + : relation_with_star_list FROM table_references + | FROM relation_with_star_list USING table_references + ; + +update_stmt + : with_clause? update_basic_stmt + ; + +update_basic_stmt + : update_with_opt_hint IGNORE? table_references SET update_asgn_list (WHERE opt_hint_value expr)? order_by? limit_clause? + ; + +update_asgn_list + : update_asgn_factor (Comma update_asgn_factor)* + ; + +update_asgn_factor + : column_definition_ref COMP_EQ expr_or_default + ; + +create_resource_stmt + : CREATE RESOURCE UNIT (IF not EXISTS)? relation_name (resource_unit_option | (opt_resource_unit_option_list Comma resource_unit_option))? + | CREATE RESOURCE POOL (IF not EXISTS)? relation_name (create_resource_pool_option | (opt_create_resource_pool_option_list Comma create_resource_pool_option))? + ; + +opt_resource_unit_option_list + : resource_unit_option + | empty + | opt_resource_unit_option_list Comma resource_unit_option + ; + +resource_unit_option + : (MIN_CPU|MIN_IOPS|MIN_MEMORY|MAX_CPU|MAX_MEMORY|MAX_IOPS|MAX_DISK_SIZE|MAX_SESSION_NUM|MEMORY_SIZE|IOPS_WEIGHT|LOG_DISK_SIZE) COMP_EQ? conf_const + ; + +opt_create_resource_pool_option_list + : create_resource_pool_option + | empty + | create_resource_pool_option (Comma create_resource_pool_option)* + ; + +create_resource_pool_option + : UNIT COMP_EQ? relation_name_or_string + | UNIT_NUM COMP_EQ? INTNUM + | ZONE_LIST COMP_EQ? LeftParen zone_list RightParen + | REPLICA_TYPE COMP_EQ? STRING_VALUE + ; + +alter_resource_pool_option_list + : alter_resource_pool_option (Comma alter_resource_pool_option)* + ; + +unit_id_list + : INTNUM (Comma INTNUM)* + ; + +alter_resource_pool_option + : UNIT COMP_EQ? relation_name_or_string + | UNIT_NUM COMP_EQ? INTNUM (DELETE UNIT opt_equal_mark LeftParen unit_id_list RightParen)? + | ZONE_LIST COMP_EQ? LeftParen zone_list RightParen + ; + +alter_resource_stmt + : ALTER RESOURCE UNIT relation_name (resource_unit_option | (opt_resource_unit_option_list Comma resource_unit_option))? + | ALTER RESOURCE POOL relation_name alter_resource_pool_option_list + | ALTER RESOURCE POOL relation_name SPLIT INTO LeftParen resource_pool_list RightParen ON LeftParen zone_list RightParen + | ALTER RESOURCE POOL MERGE LeftParen resource_pool_list RightParen INTO LeftParen resource_pool_list RightParen + | ALTER RESOURCE TENANT relation_name UNIT_NUM COMP_EQ? INTNUM (DELETE UNIT_GROUP opt_equal_mark LeftParen unit_id_list RightParen)? + ; + +drop_resource_stmt + : DROP RESOURCE (UNIT|POOL) (IF EXISTS)? relation_name + ; + +create_tenant_stmt + : CREATE TENANT (IF not EXISTS)? relation_name (tenant_option | (opt_tenant_option_list Comma tenant_option))? ((SET sys_var_and_val_list) | (SET VARIABLES sys_var_and_val_list) | (VARIABLES sys_var_and_val_list))? + ; + +create_standby_tenant_stmt + : CREATE STANDBY TENANT (IF not EXISTS)? relation_name log_restore_source_option? (tenant_option | (opt_tenant_option_list Comma tenant_option))? + ; + +log_restore_source_option + : LOG_RESTORE_SOURCE COMP_EQ? conf_const + ; + +opt_tenant_option_list + : tenant_option + | empty + | opt_tenant_option_list Comma tenant_option + ; + +tenant_option + : (LOGONLY_REPLICA_NUM|REPLICA_NUM|REWRITE_MERGE_VERSION|STORAGE_FORMAT_VERSION|STORAGE_FORMAT_WORK_VERSION|PROGRESSIVE_MERGE_NUM) COMP_EQ? INTNUM + | LOCALITY COMP_EQ? STRING_VALUE FORCE? + | PRIMARY_ZONE COMP_EQ? primary_zone_name + | RESOURCE_POOL_LIST COMP_EQ? LeftParen resource_pool_list RightParen + | ENABLE_ARBITRATION_SERVICE COMP_EQ? BOOL_VALUE + | ZONE_LIST COMP_EQ? LeftParen zone_list RightParen + | charset_key COMP_EQ? charset_name + | COLLATE COMP_EQ? collation_name + | read_only_or_write + | COMMENT COMP_EQ? STRING_VALUE + | default_tablegroup + | ENABLE_EXTENDED_ROWID COMP_EQ? BOOL_VALUE + ; + +zone_list + : STRING_VALUE (Comma? STRING_VALUE)* + ; + +resource_pool_list + : STRING_VALUE (Comma STRING_VALUE)* + ; + +alter_tenant_stmt + : ALTER TENANT relation_name SET? (tenant_option | (opt_tenant_option_list Comma tenant_option))? (VARIABLES sys_var_and_val_list)? + | ALTER TENANT ALL SET? (tenant_option | (opt_tenant_option_list Comma tenant_option))? (VARIABLES sys_var_and_val_list)? + | ALTER TENANT relation_name RENAME GLOBAL_NAME TO relation_name + | ALTER TENANT relation_name lock_spec_mysql57 + ; + +drop_tenant_stmt + : DROP TENANT (IF EXISTS)? relation_name (FORCE | PURGE)? + ; + +create_restore_point_stmt + : CREATE RESTORE POINT relation_name + ; + +drop_restore_point_stmt + : DROP RESTORE POINT relation_name + ; + +create_database_stmt + : CREATE database_key (IF not EXISTS)? database_factor database_option_list? + ; + +database_key + : DATABASE + | SCHEMA + ; + +database_factor + : relation_name + ; + +database_option_list + : database_option+ + ; + +databases_expr + : DATABASES COMP_EQ? STRING_VALUE + ; + +charset_key + : CHARSET + | CHARACTER SET + ; + +database_option + : DEFAULT? charset_key COMP_EQ? charset_name + | DEFAULT? COLLATE COMP_EQ? collation_name + | REPLICA_NUM COMP_EQ? INTNUM + | PRIMARY_ZONE COMP_EQ? primary_zone_name + | read_only_or_write + | default_tablegroup + | DATABASE_ID COMP_EQ? INTNUM + ; + +read_only_or_write + : READ ONLY + | READ WRITE + ; + +drop_database_stmt + : DROP database_key (IF EXISTS)? database_factor + ; + +alter_database_stmt + : ALTER database_key NAME_OB? SET? database_option_list + ; + +load_data_stmt + : load_data_with_opt_hint (LOCAL | REMOTE_OSS)? INFILE STRING_VALUE (IGNORE | REPLACE)? INTO TABLE relation_factor use_partition? (CHARACTER SET charset_name_or_default)? field_opt line_opt ((IGNORE INTNUM lines_or_rows) | (GENERATED INTNUM lines_or_rows))? ((LeftParen RightParen) | (LeftParen field_or_vars_list RightParen))? (SET load_set_list)? load_data_extended_option_list? + ; + +load_data_with_opt_hint + : LOAD DATA + | LOAD_DATA_HINT_BEGIN hint_list_with_end + ; + +lines_or_rows + : LINES + | ROWS + ; + +field_or_vars_list + : field_or_vars (Comma field_or_vars)* + ; + +field_or_vars + : column_definition_ref + | USER_VARIABLE + ; + +load_set_list + : load_set_element (Comma load_set_element)* + ; + +load_set_element + : column_definition_ref COMP_EQ expr_or_default + ; + +load_data_extended_option_list + : load_data_extended_option load_data_extended_option_list? + ; + +load_data_extended_option + : LOGFILE COMP_EQ? STRING_VALUE + | REJECT LIMIT COMP_EQ? INTNUM + | BADFILE COMP_EQ? STRING_VALUE + ; + +use_database_stmt + : USE database_factor + ; + +temporary_option + : (TEMPORARY | EXTERNAL)? + ; + +create_table_like_stmt + : CREATE temporary_option TABLE (IF not EXISTS)? relation_factor LIKE relation_factor + | CREATE temporary_option TABLE (IF not EXISTS)? relation_factor LeftParen LIKE relation_factor RightParen + ; + +create_table_stmt + : CREATE temporary_option TABLE (IF not EXISTS)? relation_factor LeftParen table_element_list RightParen table_option_list? opt_partition_option + | CREATE temporary_option TABLE (IF not EXISTS)? relation_factor LeftParen table_element_list RightParen table_option_list? opt_partition_option AS? select_stmt + | CREATE temporary_option TABLE (IF not EXISTS)? relation_factor table_option_list opt_partition_option AS? select_stmt + | CREATE temporary_option TABLE (IF not EXISTS)? relation_factor partition_option AS? select_stmt + | CREATE temporary_option TABLE (IF not EXISTS)? relation_factor select_stmt + | CREATE temporary_option TABLE (IF not EXISTS)? relation_factor AS select_stmt + ; + +ret_type + : STRING + | INTEGER + | REAL + | DECIMAL + | FIXED + | NUMERIC + ; + +create_function_stmt + : CREATE AGGREGATE? FUNCTION NAME_OB RETURNS ret_type SONAME STRING_VALUE + ; + +drop_function_stmt + : DROP FUNCTION (IF EXISTS)? relation_factor + ; + +drop_procedure_stmt + : DROP PROCEDURE (IF EXISTS)? relation_factor + ; + +drop_trigger_stmt + : DROP TRIGGER (IF EXISTS)? relation_factor + ; + +table_element_list + : table_element (Comma table_element)* + ; + +table_element + : column_definition + | out_of_line_index + | out_of_line_constraint + ; + +out_of_line_constraint + : (CONSTRAINT opt_constraint_name)? out_of_line_primary_index + | (CONSTRAINT opt_constraint_name)? out_of_line_unique_index + | (CONSTRAINT opt_constraint_name)? CHECK LeftParen expr RightParen check_state? + | (CONSTRAINT opt_constraint_name)? FOREIGN KEY index_name? LeftParen column_name_list RightParen references_clause + ; + +references_clause + : REFERENCES relation_factor LeftParen column_name_list RightParen (MATCH match_action)? (opt_reference_option_list reference_option)? + ; + +out_of_line_index + : key_or_index index_name? index_using_algorithm? LeftParen sort_column_list RightParen opt_index_options? (partition_option | auto_partition_option)? + | (FULLTEXT | SPATIAL) key_or_index? index_name? index_using_algorithm? LeftParen sort_column_list RightParen opt_index_options? (partition_option | auto_partition_option)? + ; + +out_of_line_primary_index + : PRIMARY KEY index_name? index_using_algorithm? LeftParen column_name_list RightParen opt_index_options? + ; + +out_of_line_unique_index + : UNIQUE key_or_index? index_name? index_using_algorithm? LeftParen sort_column_list RightParen opt_index_options? (partition_option | auto_partition_option)? + ; + +opt_reference_option_list + : opt_reference_option_list reference_option + | empty + ; + +reference_option + : ON (DELETE|UPDATE) reference_action + ; + +reference_action + : RESTRICT + | CASCADE + | SET NULLX + | NO ACTION + | SET DEFAULT + ; + +match_action + : SIMPLE + | FULL + | PARTIAL + ; + +column_definition + : column_definition_ref data_type opt_column_attribute_list? (FIRST | (BEFORE column_name) | (AFTER column_name))? + | column_definition_ref data_type (GENERATED opt_generated_option_list)? AS LeftParen expr RightParen (VIRTUAL | STORED)? opt_generated_column_attribute_list? (FIRST | (BEFORE column_name) | (AFTER column_name))? + ; + +opt_generated_option_list + : ALWAYS + ; + +opt_generated_column_attribute_list + : opt_generated_column_attribute_list generated_column_attribute + | generated_column_attribute + ; + +generated_column_attribute + : NOT NULLX + | NULLX + | UNIQUE KEY + | PRIMARY? KEY + | UNIQUE + | COMMENT STRING_VALUE + | ID INTNUM + | (CONSTRAINT opt_constraint_name)? CHECK LeftParen expr RightParen check_state? + | SRID INTNUM + ; + +column_definition_ref + : ((relation_name Dot)? relation_name Dot)? column_name + ; + +column_definition_list + : column_definition (Comma column_definition)* + ; + +cast_data_type + : binary_type_i[true] + | character_type_i[true] + | datetime_type_i[true] + | date_year_type_i + | float_type_i[true] + | number_type_i[true] + | json_type_i + | geo_type_i + | (SIGNED|UNSIGNED) INTEGER? + ; + +get_format_unit + : DATETIME + | TIMESTAMP + | DATE + | TIME + ; + +precision_int_num [int max_precision_count] + locals [int precision_count=1] + : LeftParen INTNUM ({$max_precision_count>$precision_count}? Comma INTNUM {$precision_count++;})* RightParen + ; + +precision_decimal_num + : LeftParen DECIMAL_VAL RightParen + ; + +data_type_precision [int max_int_precision_count] + : precision_int_num[max_int_precision_count] + | precision_decimal_num + ; + +data_type + : int_type_i + | float_type_i[false] + | number_type_i[false] + | bool_type_i + | datetime_type_i[false] + | date_year_type_i + | text_type_i + | character_type_i[false] + | blob_type_i + | binary_type_i[false] + | bit_type_i + | json_type_i + | collection_type_i + | geo_type_i + | STRING_VALUE + ; + +string_list + : text_string (Comma text_string)* + ; + +text_string + : STRING_VALUE + | PARSER_SYNTAX_ERROR + ; + +collection_type_i + : ENUM LeftParen string_list RightParen BINARY? (charset_key charset_name)? collation? + | SET LeftParen string_list RightParen BINARY? (charset_key charset_name)? collation? + ; + +json_type_i + : JSON + ; + +bit_type_i + : BIT precision_int_num[1]? + ; + +int_type_i + : (TINYINT | SMALLINT | MEDIUMINT | INTEGER | BIGINT) precision_int_num[1]? (UNSIGNED | SIGNED)? ZEROFILL? + ; + +float_type_i [boolean in_cast_data_type] + : {!$in_cast_data_type}? (FLOAT | DOUBLE PRECISION? | REAL PRECISION?) data_type_precision[2]? (UNSIGNED | SIGNED)? ZEROFILL? + | {$in_cast_data_type}? FLOAT precision_int_num[1]? + | {$in_cast_data_type}? DOUBLE + ; + +number_type_i [boolean in_cast_data_type] + : {$in_cast_data_type}? (NUMBER | DECIMAL | FIXED) precision_int_num[2]? + | {!$in_cast_data_type}? (NUMBER | DECIMAL | FIXED) precision_int_num[2]? (UNSIGNED | SIGNED)? ZEROFILL? + ; + +text_type_i + : (TINYTEXT | TEXT | MEDIUMTEXT VARCHAR? | LONGTEXT) string_length_i? BINARY? (charset_key charset_name)? collation? + ; + +character_type_i [boolean in_cast_data_type] + : {!$in_cast_data_type}? CHARACTER string_length_i? BINARY? (charset_key charset_name)? collation? + | {$in_cast_data_type}? CHARACTER string_length_i? BINARY? + | {$in_cast_data_type}? CHARACTER string_length_i? charset_key charset_name + | {!$in_cast_data_type}? NCHAR string_length_i? BINARY? + | {!$in_cast_data_type}? NATIONAL CHARACTER string_length_i? BINARY? + | {!$in_cast_data_type}? VARCHAR string_length_i BINARY? (charset_key charset_name)? collation? + | {!$in_cast_data_type}? NCHAR VARCHAR string_length_i BINARY? + | {!$in_cast_data_type}? NVARCHAR string_length_i BINARY? + | {!$in_cast_data_type}? NATIONAL VARCHAR string_length_i BINARY? + | {!$in_cast_data_type}? CHARACTER VARYING string_length_i BINARY? (charset_key charset_name)? + | {!$in_cast_data_type}? NATIONAL CHARACTER VARYING string_length_i BINARY? + ; + +bool_type_i + : BOOL + | BOOLEAN + ; + +geo_type_i + : POINT + | GEOMETRY + | LINESTRING + | POLYGON + | MULTIPOINT + | MULTILINESTRING + | MULTIPOLYGON + | GEOMETRYCOLLECTION + ; + +datetime_type_i [boolean in_cast_data_type] + : (DATETIME | TIME) precision_int_num[1]? + | {!$in_cast_data_type}? TIMESTAMP precision_int_num[1]? + ; + +date_year_type_i + : DATE + | YEAR precision_int_num[1]? + ; + +blob_type_i + : (TINYBLOB | BLOB | MEDIUMBLOB | LONGBLOB) string_length_i? + ; + +binary_type_i [boolean in_cast_data_type] + : BINARY string_length_i? + | {!$in_cast_data_type}? VARBINARY string_length_i + ; + +string_length_i + : LeftParen number_literal RightParen + ; + +collation_name + : NAME_OB + | STRING_VALUE + ; + +trans_param_name + : Quote STRING_VALUE Quote + ; + +trans_param_value + : Quote STRING_VALUE Quote + | INTNUM + ; + +charset_name + : NAME_OB + | STRING_VALUE + | BINARY + ; + +charset_name_or_default + : charset_name + | DEFAULT + ; + +collation + : COLLATE collation_name + ; + +opt_column_attribute_list + : opt_column_attribute_list column_attribute + | column_attribute + ; + +column_attribute + : not NULLX + | NULLX + | DEFAULT now_or_signed_literal + | ORIG_DEFAULT now_or_signed_literal + | AUTO_INCREMENT + | UNIQUE KEY + | PRIMARY? KEY + | UNIQUE + | COMMENT STRING_VALUE + | ON UPDATE cur_timestamp_func + | ID INTNUM + | (CONSTRAINT opt_constraint_name)? CHECK LeftParen expr RightParen check_state? + | SRID INTNUM + | COLLATE collation_name + ; + +now_or_signed_literal + : cur_timestamp_func + | signed_literal + ; + +signed_literal + : literal + | Plus number_literal + | Minus number_literal + ; + +table_option_list_space_seperated + : table_option+ + ; + +table_option_list + : table_option_list_space_seperated + | table_option Comma table_option_list + ; + +primary_zone_name + : DEFAULT + | RANDOM + | USER_VARIABLE + | relation_name_or_string + ; + +tablespace + : NAME_OB + ; + +locality_name + : STRING_VALUE + | DEFAULT + ; + +table_option + : SORTKEY LeftParen column_name_list RightParen + | (TABLE_MODE|DUPLICATE_SCOPE|COMMENT|COMPRESSION) COMP_EQ? STRING_VALUE + | LOCALITY COMP_EQ? locality_name FORCE? + | EXPIRE_INFO COMP_EQ? LeftParen expr RightParen + | (PROGRESSIVE_MERGE_NUM|BLOCK_SIZE|TABLE_ID|REPLICA_NUM + |STORAGE_FORMAT_VERSION|TABLET_SIZE|PCTFREE|MAX_USED_PART_ID) COMP_EQ? INTNUM + | ROW_FORMAT COMP_EQ? row_format_option + | USE_BLOOM_FILTER COMP_EQ? BOOL_VALUE + | DEFAULT? charset_key COMP_EQ? charset_name + | DEFAULT? COLLATE COMP_EQ? collation_name + | PRIMARY_ZONE COMP_EQ? primary_zone_name + | (TABLEGROUP|ENGINE_) COMP_EQ? relation_name_or_string + | AUTO_INCREMENT COMP_EQ? int_or_decimal + | read_only_or_write + | TABLESPACE tablespace + | parallel_option + | DELAY_KEY_WRITE COMP_EQ? INTNUM + | AVG_ROW_LENGTH COMP_EQ? INTNUM + | CHECKSUM COMP_EQ? INTNUM + | AUTO_INCREMENT_MODE COMP_EQ? STRING_VALUE + | ENABLE_EXTENDED_ROWID COMP_EQ? BOOL_VALUE + | LOCATION COMP_EQ? STRING_VALUE + | FORMAT COMP_EQ? LeftParen external_file_format_list RightParen + | PATTERN COMP_EQ? STRING_VALUE + ; + +parallel_option + : PARALLEL COMP_EQ? INTNUM + | NOPARALLEL + ; + +relation_name_or_string + : relation_name + | STRING_VALUE + | ALL + ; + +opt_equal_mark + : COMP_EQ? + ; + +partition_option + : hash_partition_option + | key_partition_option + | range_partition_option + | list_partition_option + ; + +opt_partition_option + : partition_option + | opt_column_partition_option + | auto_partition_option + ; + +auto_partition_option + : auto_partition_type PARTITION SIZE partition_size PARTITIONS AUTO + ; + +partition_size + : conf_const + | AUTO + ; + +auto_partition_type + : auto_range_type + ; + +auto_range_type + : PARTITION BY RANGE LeftParen expr? RightParen + | PARTITION BY RANGE COLUMNS LeftParen column_name_list RightParen + ; + +hash_partition_option + : PARTITION BY HASH LeftParen expr RightParen subpartition_option? (PARTITIONS INTNUM)? opt_hash_partition_list? + ; + +list_partition_option + : PARTITION BY BISON_LIST LeftParen expr RightParen subpartition_option? (PARTITIONS INTNUM)? opt_list_partition_list + | PARTITION BY BISON_LIST COLUMNS LeftParen column_name_list RightParen subpartition_option? (PARTITIONS INTNUM)? opt_list_partition_list + ; + +key_partition_option + : PARTITION BY KEY LeftParen column_name_list? RightParen subpartition_option? (PARTITIONS INTNUM)? opt_hash_partition_list? + ; + +range_partition_option + : PARTITION BY RANGE LeftParen expr RightParen subpartition_option? (PARTITIONS INTNUM)? opt_range_partition_list + | PARTITION BY RANGE COLUMNS LeftParen column_name_list RightParen subpartition_option? (PARTITIONS INTNUM)? opt_range_partition_list + ; + +opt_column_partition_option + : column_partition_option? + ; + +column_partition_option + : PARTITION BY COLUMN LeftParen vertical_column_name (Comma aux_column_list)? RightParen + ; + +aux_column_list + : vertical_column_name (Comma vertical_column_name)* + ; + +vertical_column_name + : column_name + | LeftParen column_name_list RightParen + ; + +column_name_list + : column_name (Comma column_name)* + ; + +subpartition_option + : subpartition_template_option + | subpartition_individual_option + ; + +subpartition_template_option + : SUBPARTITION BY RANGE LeftParen expr RightParen SUBPARTITION TEMPLATE opt_range_subpartition_list + | SUBPARTITION BY RANGE COLUMNS LeftParen column_name_list RightParen SUBPARTITION TEMPLATE opt_range_subpartition_list + | SUBPARTITION BY HASH LeftParen expr RightParen SUBPARTITION TEMPLATE opt_hash_subpartition_list + | SUBPARTITION BY BISON_LIST LeftParen expr RightParen SUBPARTITION TEMPLATE opt_list_subpartition_list + | SUBPARTITION BY BISON_LIST COLUMNS LeftParen column_name_list RightParen SUBPARTITION TEMPLATE opt_list_subpartition_list + | SUBPARTITION BY KEY LeftParen column_name_list RightParen SUBPARTITION TEMPLATE opt_hash_subpartition_list + ; + +subpartition_individual_option + : SUBPARTITION BY (RANGE|BISON_LIST) LeftParen expr RightParen + | SUBPARTITION BY (RANGE|BISON_LIST) COLUMNS LeftParen column_name_list RightParen + | SUBPARTITION BY HASH LeftParen expr RightParen (SUBPARTITIONS INTNUM)? + | SUBPARTITION BY KEY LeftParen column_name_list RightParen (SUBPARTITIONS INTNUM)? + ; + +opt_hash_partition_list + : LeftParen hash_partition_list RightParen + ; + +hash_partition_list + : hash_partition_element (Comma hash_partition_element)* + ; + +subpartition_list + : opt_hash_subpartition_list + | opt_range_subpartition_list + | opt_list_subpartition_list + ; + +hash_partition_element + : PARTITION relation_factor (ID INTNUM)? partition_attributes_option? subpartition_list? + ; + +opt_range_partition_list + : LeftParen range_partition_list RightParen + ; + +range_partition_list + : range_partition_element (Comma range_partition_element)* + ; + +range_partition_element + : PARTITION relation_factor VALUES LESS THAN range_partition_expr (ID INTNUM)? partition_attributes_option? subpartition_list? + ; + +opt_list_partition_list + : LeftParen list_partition_list RightParen + ; + +list_partition_list + : list_partition_element (Comma list_partition_element)* + ; + +list_partition_element + : PARTITION relation_factor VALUES IN list_partition_expr (ID INTNUM)? partition_attributes_option? subpartition_list? + ; + +opt_hash_subpartition_list + : LeftParen hash_subpartition_list RightParen + ; + +hash_subpartition_list + : hash_subpartition_element (Comma hash_subpartition_element)* + ; + +partition_attributes_option + : ENGINE_ COMP_EQ INNODB + ; + +hash_subpartition_element + : SUBPARTITION relation_factor partition_attributes_option? + ; + +opt_range_subpartition_list + : LeftParen range_subpartition_list RightParen + ; + +range_subpartition_list + : range_subpartition_element (Comma range_subpartition_element)* + ; + +range_subpartition_element + : SUBPARTITION relation_factor VALUES LESS THAN range_partition_expr partition_attributes_option? + ; + +opt_list_subpartition_list + : LeftParen list_subpartition_list RightParen + ; + +list_subpartition_list + : list_subpartition_element (Comma list_subpartition_element)* + ; + +list_subpartition_element + : SUBPARTITION relation_factor VALUES IN list_partition_expr partition_attributes_option? + ; + +list_partition_expr + : LeftParen (DEFAULT|list_expr) RightParen + ; + +list_expr + : expr (Comma expr)* + ; + +range_partition_expr + : LeftParen range_expr_list RightParen + | MAXVALUE + ; + +range_expr_list + : range_expr (Comma range_expr)* + ; + +range_expr + : expr + | MAXVALUE + ; + +int_or_decimal + : INTNUM + | DECIMAL_VAL + ; + +tg_hash_partition_option + : PARTITION BY HASH tg_subpartition_option (PARTITIONS INTNUM)? + ; + +tg_key_partition_option + : PARTITION BY KEY INTNUM tg_subpartition_option (PARTITIONS INTNUM)? + ; + +tg_range_partition_option + : PARTITION BY RANGE (COLUMNS INTNUM)? tg_subpartition_option (PARTITIONS INTNUM)? opt_range_partition_list + ; + +tg_list_partition_option + : PARTITION BY BISON_LIST (COLUMNS INTNUM)? tg_subpartition_option (PARTITIONS INTNUM)? opt_list_partition_list + ; + +tg_subpartition_option + : tg_subpartition_template_option + | tg_subpartition_individual_option + ; + +tg_subpartition_template_option + : SUBPARTITION BY RANGE (COLUMNS INTNUM)? SUBPARTITION TEMPLATE opt_range_subpartition_list + | SUBPARTITION BY BISON_LIST (COLUMNS INTNUM)? SUBPARTITION TEMPLATE opt_list_subpartition_list + | empty + ; + +tg_subpartition_individual_option + : SUBPARTITION BY (HASH|KEY INTNUM) (SUBPARTITIONS INTNUM)? + | SUBPARTITION BY RANGE (COLUMNS INTNUM)? + | SUBPARTITION BY BISON_LIST (COLUMNS INTNUM)? + ; + +row_format_option + : REDUNDANT + | COMPACT + | DYNAMIC + | COMPRESSED + | CONDENSED + | DEFAULT + ; + +external_file_format_list + : external_file_format (Comma? external_file_format)* + ; + +external_file_format + : format_key=(ENCODING|TYPE) COMP_EQ STRING_VALUE + | format_key=(ESCAPE|FIELD_OPTIONALLY_ENCLOSED_BY|FIELD_DELIMITER|LINE_DELIMITER) COMP_EQ expr + | format_key=SKIP_HEADER COMP_EQ INTNUM + | format_key=(SKIP_BLANK_LINES|TRIM_SPACE|EMPTY_FIELD_AS_NULL) COMP_EQ BOOL_VALUE + | format_key=NULL_IF_EXETERNAL COMP_EQ LeftParen expr_list RightParen + ; + +create_tablegroup_stmt + : CREATE TABLEGROUP (IF not EXISTS)? relation_name tablegroup_option_list? (tg_hash_partition_option | tg_key_partition_option | tg_range_partition_option | tg_list_partition_option)? + ; + +drop_tablegroup_stmt + : DROP TABLEGROUP (IF EXISTS)? relation_name + ; + +alter_tablegroup_stmt + : ALTER TABLEGROUP relation_name ADD TABLE? table_list + | ALTER TABLEGROUP relation_name (alter_tablegroup_actions|alter_tg_partition_option) + ; + +tablegroup_option_list_space_seperated + : tablegroup_option+ + ; + +tablegroup_option_list + : tablegroup_option_list_space_seperated + | tablegroup_option Comma tablegroup_option_list + ; + +tablegroup_option + : LOCALITY COMP_EQ? locality_name FORCE? + | PRIMARY_ZONE COMP_EQ? primary_zone_name + | (TABLEGROUP_ID|MAX_USED_PART_ID) COMP_EQ? INTNUM + | BINDING COMP_EQ? BOOL_VALUE + | SHARDING COMP_EQ? STRING_VALUE + ; + +alter_tablegroup_actions + : alter_tablegroup_action (Comma alter_tablegroup_action)* + ; + +alter_tablegroup_action + : SET? tablegroup_option_list_space_seperated + ; + +default_tablegroup + : DEFAULT? TABLEGROUP COMP_EQ? (NULLX|relation_name) + ; + +create_view_stmt + : CREATE (OR REPLACE)? view_attribute MATERIALIZED? VIEW view_name (LeftParen column_name_list RightParen)? (TABLE_ID COMP_EQ INTNUM)? AS view_select_stmt view_check_option? + | ALTER view_attribute VIEW view_name (LeftParen column_name_list RightParen)? (TABLE_ID COMP_EQ INTNUM)? AS view_select_stmt view_check_option? + ; + +view_attribute + : (ALGORITHM COMP_EQ view_algorithm)? (DEFINER COMP_EQ user)? (SQL SECURITY (DEFINER | INVOKER))? + | empty + ; + +view_check_option + : WITH CHECK OPTION + | WITH CASCADED CHECK OPTION + | WITH LOCAL CHECK OPTION + ; + +view_algorithm + : UNDEFINED + | MERGE + | TEMPTABLE + ; + +view_select_stmt + : select_stmt + ; + +view_name + : relation_factor + ; + +opt_tablet_id + : TABLET_ID COMP_EQ INTNUM + ; + +create_index_stmt + : CREATE (FULLTEXT | UNIQUE | SPATIAL)? INDEX (IF not EXISTS)? normal_relation_factor index_using_algorithm? ON relation_factor LeftParen sort_column_list RightParen opt_index_options? opt_partition_option + ; + +index_name + : relation_name + ; + +check_state + : NOT? ENFORCED + ; + +opt_constraint_name + : constraint_name? + ; + +constraint_name + : relation_name + ; + +sort_column_list + : sort_column_key (Comma sort_column_key)* + ; + +sort_column_key + : column_name (LeftParen INTNUM RightParen)? (ASC | DESC)? (ID INTNUM)? + | LeftParen expr RightParen (ASC | DESC)? (ID INTNUM)? + ; + +opt_index_options + : index_option+ + ; + +index_option + : GLOBAL + | LOCAL + | (BLOCK_SIZE|DATA_TABLE_ID|INDEX_TABLE_ID|VIRTUAL_COLUMN_ID|MAX_USED_PART_ID) COMP_EQ? INTNUM + | COMMENT STRING_VALUE + | (STORING|CTXCAT) LeftParen column_name_list RightParen + | WITH_ROWID + | WITH PARSER STRING_VALUE + | index_using_algorithm + | visibility_option + | parallel_option + ; + +index_using_algorithm + : USING (BTREE|HASH) + ; + +drop_table_stmt + : DROP (TEMPORARY | MATERIALIZED)? table_or_tables (IF EXISTS)? table_list (CASCADE | RESTRICT)? + ; + +table_or_tables + : TABLE + | TABLES + ; + +drop_view_stmt + : DROP MATERIALIZED? VIEW (IF EXISTS)? table_list (CASCADE | RESTRICT)? + ; + +table_list + : relation_factor (Comma relation_factor)* + ; + +drop_index_stmt + : DROP INDEX relation_name ON relation_factor + ; + +insert_stmt + : insert_with_opt_hint IGNORE? INTO? single_table_insert (ON DUPLICATE KEY UPDATE update_asgn_list)? + | replace_with_opt_hint IGNORE? INTO? single_table_insert + ; + +single_table_insert + : dml_table_name (SET update_asgn_list|values_clause) + | dml_table_name LeftParen column_list? RightParen values_clause + ; + +values_clause + : value_or_values insert_vals_list + | select_stmt + ; + +value_or_values + : VALUE + | VALUES + ; + +replace_with_opt_hint + : REPLACE + | REPLACE_HINT_BEGIN hint_list_with_end + ; + +insert_with_opt_hint + : INSERT + | INSERT_HINT_BEGIN hint_list_with_end + ; + +column_list + : column_definition_ref (Comma column_definition_ref)* + ; + +insert_vals_list + : LeftParen insert_vals RightParen + | insert_vals_list Comma LeftParen insert_vals RightParen + ; + +insert_vals + : expr_or_default + | empty + | insert_vals Comma expr_or_default + ; + +expr_or_default + : expr + | DEFAULT + ; + +select_stmt + : with_clause? (select_no_parens into_clause? |select_with_parens) + ; + + +select_with_parens + : LeftParen with_clause? (select_no_parens |select_with_parens) RightParen + ; + +select_no_parens + : select_clause (for_update_clause | opt_lock_in_share_mode)? + | select_clause_set (for_update_clause | opt_lock_in_share_mode)? + | select_clause_set_with_order_and_limit (for_update_clause | opt_lock_in_share_mode)? + ; + +no_table_select + : select_with_opt_hint query_expression_option_list? select_expr_list into_opt (FROM DUAL (WHERE opt_hint_value expr)? (GROUP BY groupby_clause)? (HAVING expr)? (WINDOW named_windows)?)? + ; + +select_clause + : no_table_select_with_order_and_limit + | simple_select_with_order_and_limit + | select_with_parens_with_order_and_limit + | table_values_clause + | table_values_clause_with_order_by_and_limit + ; + +select_clause_set_with_order_and_limit + : select_clause_set order_by + | select_clause_set order_by? limit_clause + ; + +select_clause_set + : select_clause_set order_by? limit_clause? set_type select_clause_set_right + | select_clause_set_left set_type select_clause_set_right + ; + +select_clause_set_right + : no_table_select + | simple_select + | select_with_parens + | table_values_clause + ; + +select_clause_set_left + : no_table_select_with_order_and_limit + | simple_select_with_order_and_limit + | select_clause_set_right + ; + +no_table_select_with_order_and_limit + : no_table_select order_by? limit_clause? + ; + +// +simple_select_with_order_and_limit + : simple_select order_by? limit_clause? + ; + +select_with_parens_with_order_and_limit + : select_with_parens order_by + | select_with_parens order_by? limit_clause + ; + +select_with_opt_hint + : SELECT + | SELECT_HINT_BEGIN hint_list_with_end + ; + +update_with_opt_hint + : UPDATE + | UPDATE_HINT_BEGIN hint_list_with_end + ; + +delete_with_opt_hint + : DELETE + | DELETE_HINT_BEGIN hint_list_with_end + ; + +simple_select + : select_with_opt_hint query_expression_option_list? select_expr_list into_opt FROM from_list (WHERE opt_hint_value expr)? (GROUP BY groupby_clause)? (HAVING expr)? (WINDOW named_windows)? + ; + +set_type_union + : UNION + ; + +set_type_other + : INTERSECT + | EXCEPT + | MINUS + ; + +set_type + : set_type_union set_expression_option + | set_type_other + ; + +set_expression_option + : (ALL | DISTINCT | UNIQUE)? + ; + +opt_hint_value + : HINT_VALUE? + ; + +limit_clause + : LIMIT limit_expr ((OFFSET limit_expr)?|Comma limit_expr) + ; + +into_clause + : INTO OUTFILE STRING_VALUE (charset_key charset_name)? field_opt line_opt + | INTO DUMPFILE STRING_VALUE + | INTO into_var_list + ; + +into_opt + : into_clause? + ; + +into_var_list + : into_var (Comma into_var)* + ; + +into_var + : USER_VARIABLE + | NAME_OB + | unreserved_keyword_normal + ; + +field_opt + : columns_or_fields field_term_list + | empty + ; + +field_term_list + : field_term+ + ; + +field_term + : ((OPTIONALLY? ENCLOSED|TERMINATED)|ESCAPED) BY STRING_VALUE + ; + +line_opt + : LINES line_term_list + | empty + ; + +line_term_list + : line_term+ + ; + +line_term + : (STARTING|TERMINATED) BY STRING_VALUE + ; + +hint_list_with_end + : (hint_options | (opt_hint_list Comma hint_options))? HINT_END + ; + +opt_hint_list + : hint_options + | empty + | opt_hint_list Comma hint_options + ; + +hint_options + : hint_option? + ; + +name_list + : NAME_OB + | name_list Comma? NAME_OB + ; + +hint_option + : (NO_REWRITE|HOTSPOT|ORDERED|USE_HASH_AGGREGATION|NO_USE_HASH_AGGREGATION|NO_USE_JIT|USE_LATE_MATERIALIZATION|USE_LATE_MATERIALIZATION + | NO_USE_LATE_MATERIALIZATION|TRACE_LOG|USE_PX|NO_USE_PX|NAME_OB|EOF|PARSER_SYNTAX_ERROR + | ENABLE_PARALLEL_DML| DISABLE_PARALLEL_DML|NO_PARALLEL|MONITOR) + | READ_CONSISTENCY LeftParen consistency_level RightParen + | INDEX_HINT LeftParen qb_name_option relation_factor_in_hint NAME_OB RightParen + | (QUERY_TIMEOUT|FROZEN_VERSION) LeftParen INTNUM RightParen + | TOPK LeftParen INTNUM INTNUM RightParen + | LOG_LEVEL LeftParen NAME_OB RightParen + | LOG_LEVEL LeftParen Quote STRING_VALUE Quote RightParen + | LEADING_HINT LeftParen qb_name_option relation_factor_in_leading_hint_list_entry RightParen + | LEADING_HINT LeftParen qb_name_option relation_factor_in_hint_list RightParen + | (FULL_HINT|PQ_MAP) LeftParen qb_name_option relation_factor_in_hint RightParen + | USE_PLAN_CACHE LeftParen use_plan_cache_type RightParen + | (USE_MERGE|NO_USE_MERGE|USE_HASH|NO_USE_HASH|USE_NL|PX_JOIN_FILTER|NO_PX_JOIN_FILTER + | NO_USE_NL|USE_BNL|NO_USE_BNL|USE_NL_MATERIALIZATION|NO_USE_NL_MATERIALIZATION) LeftParen qb_name_option relation_factor_in_use_join_hint_list RightParen + | (MERGE_HINT|NO_MERGE_HINT|NO_EXPAND|USE_CONCAT|UNNEST|NO_UNNEST|PLACE_GROUP_BY|NO_PLACE_GROUP_BY|NO_PRED_DEDUCE|INLINE|MATERIALIZE) (LeftParen qb_name_option RightParen)? + | USE_JIT LeftParen use_jit_type RightParen + | (STAT|TRACING) LeftParen tracing_num_list RightParen + | DOP LeftParen INTNUM Comma INTNUM RightParen + | TRANS_PARAM LeftParen trans_param_name Comma? trans_param_value RightParen + | FORCE_REFRESH_LOCATION_CACHE + | QB_NAME LeftParen NAME_OB RightParen + | (MAX_CONCURRENT|PARALLEL|LOAD_BATCH_SIZE) LeftParen INTNUM RightParen + | PQ_DISTRIBUTE LeftParen qb_name_option relation_factor_in_pq_hint Comma? distribute_method (Comma? distribute_method)? RightParen + ; + +consistency_level + : WEAK + | STRONG + | FROZEN + ; + +use_plan_cache_type + : NONE + | DEFAULT + ; + +use_jit_type + : AUTO + | FORCE + ; + +distribute_method + : ALL + | NONE + | PARTITION + | RANDOM + | RANDOM_LOCAL + | HASH + | BROADCAST + | LOCAL + | BC2HOST + | RANGE + | LIST + ; + +limit_expr + : INTNUM + | QUESTIONMARK + | column_ref + ; + +for_update_clause + : FOR UPDATE opt_for_update_wait + ; + +opt_lock_in_share_mode + : LOCK_ IN SHARE MODE + ; + +opt_for_update_wait + : empty + | WAIT DECIMAL_VAL + | WAIT INTNUM + | NOWAIT + | NO_WAIT + ; + +parameterized_trim + : (BOTH FROM)? expr + | BOTH? expr FROM expr + | (LEADING|TRAILING) expr? FROM expr + ; + +groupby_clause + : sort_list_for_group_by (WITH ROLLUP)? + ; + +sort_list_for_group_by + : sort_key_for_group_by (Comma sort_key_for_group_by)* + ; + +sort_key_for_group_by + : expr (ASC | DESC)? + ; + +order_by + : ORDER BY sort_list + ; + +sort_list + : sort_key (Comma sort_key)* + ; + +sort_key + : expr (ASC | DESC)? + ; + +query_expression_option_list + : query_expression_option+ + ; + +query_expression_option + : ALL + | DISTINCT + | UNIQUE + | SQL_CALC_FOUND_ROWS + | SQL_NO_CACHE + | SQL_CACHE + ; + +projection + : expr AS? (column_label|STRING_VALUE)? + | Star + ; + +select_expr_list + : projection (Comma projection)* + ; + +from_list + : table_references + ; + +table_references + : table_reference (Comma table_reference)* + | table_references_paren (Comma table_references_paren)* + ; + +table_references_paren + : table_reference (Comma table_reference)* + | LeftParen table_reference (Comma table_reference)* RightParen + | LeftParen table_references_paren (Comma table_reference)* RightParen + ; + +table_reference + : table_factor + | joined_table + ; + +table_factor + : tbl_name + | table_subquery + | select_with_parens use_flashback? + | TABLE LeftParen simple_expr RightParen (AS relation_name|relation_name?) + | LeftParen table_reference RightParen + | LeftBrace OJ table_reference RightBrace + | json_table_expr (AS? relation_name)? + ; + +tbl_name + : relation_factor use_partition? (sample_clause seed?|use_flashback?) relation_name? + | relation_factor use_partition? ((AS? relation_name|sample_clause?)|sample_clause (relation_name|seed relation_name?)) index_hint_list + | relation_factor use_partition? use_flashback? AS relation_name + | relation_factor use_partition? sample_clause seed? AS relation_name index_hint_list? + ; + +dml_table_name + : relation_factor use_partition? + ; + +seed + : SEED LeftParen INTNUM RightParen + ; + +sample_percent + : INTNUM + | DECIMAL_VAL + ; + +sample_clause + : SAMPLE BLOCK? (ALL | BASE | INCR)? LeftParen sample_percent RightParen + ; + +table_subquery + : select_with_parens use_flashback? AS? table_subquery_alias + ; + +table_subquery_alias + : relation_name + | relation_name LeftParen alias_name_list RightParen + ; + +use_partition + : PARTITION LeftParen name_list RightParen + ; + +use_flashback + : AS OF SNAPSHOT bit_expr + ; + +index_hint_type + : FORCE + | IGNORE + ; + +key_or_index + : KEY + | INDEX + ; + +index_hint_scope + : empty + | FOR ((JOIN|ORDER BY)|GROUP BY) + ; + +index_element + : NAME_OB + | PRIMARY + ; + +index_list + : index_element (Comma index_element)* + ; + +index_hint_definition + : USE key_or_index index_hint_scope LeftParen index_list? RightParen + | index_hint_type key_or_index index_hint_scope LeftParen index_list RightParen + ; + +index_hint_list + : index_hint_definition+ + ; + +relation_factor + : normal_relation_factor + | dot_relation_factor + ; + +relation_with_star_list + : relation_factor_with_star (Comma relation_factor_with_star)* + ; + +relation_factor_with_star + : relation_name (Dot relation_name)? (Dot Star)? + ; + +normal_relation_factor + : relation_name USER_VARIABLE? + | relation_name Dot relation_name USER_VARIABLE? + | relation_name Dot mysql_reserved_keyword + ; + +dot_relation_factor + : Dot (relation_name|mysql_reserved_keyword) + ; + +relation_factor_in_hint + : normal_relation_factor qb_name_option + ; + +qb_name_option + : At NAME_OB + | empty + ; + +relation_factor_in_hint_list + : relation_factor_in_hint (relation_sep_option relation_factor_in_hint)* + ; + +relation_sep_option + : Comma? + ; + +relation_factor_in_pq_hint + : relation_factor_in_hint + | LeftParen relation_factor_in_hint_list RightParen + ; + +relation_factor_in_leading_hint + : LeftParen relation_factor_in_hint_list RightParen + ; + +relation_factor_in_leading_hint_list + : relation_factor_in_leading_hint + | LeftParen (relation_factor_in_hint_list relation_sep_option)? relation_factor_in_leading_hint_list RightParen + | relation_factor_in_leading_hint_list relation_sep_option (relation_factor_in_hint|relation_factor_in_leading_hint) + | relation_factor_in_leading_hint_list relation_sep_option LeftParen relation_factor_in_hint_list relation_sep_option relation_factor_in_leading_hint_list RightParen + ; + +relation_factor_in_leading_hint_list_entry + : (relation_factor_in_hint_list relation_sep_option)? relation_factor_in_leading_hint_list + ; + +relation_factor_in_use_join_hint_list + : relation_factor_in_hint + | LeftParen relation_factor_in_hint_list RightParen + | relation_factor_in_use_join_hint_list relation_sep_option relation_factor_in_hint + | relation_factor_in_use_join_hint_list relation_sep_option LeftParen relation_factor_in_hint_list RightParen + ; + +tracing_num_list + : INTNUM (relation_sep_option tracing_num_list)? + ; + +join_condition + : ON expr + | USING LeftParen column_list RightParen + ; + +joined_table + : table_factor inner_join_type table_factor (ON expr)? + | table_factor inner_join_type table_factor USING LeftParen column_list RightParen + | table_factor outer_join_type table_factor join_condition? + | table_factor natural_join_type table_factor + | joined_table inner_join_type table_factor (ON expr)? + | joined_table inner_join_type table_factor USING LeftParen column_list RightParen + | joined_table outer_join_type table_factor join_condition? + | joined_table natural_join_type table_factor + ; + +natural_join_type + : NATURAL outer_join_type + | NATURAL INNER? JOIN + ; + +inner_join_type + : INNER? JOIN + | CROSS JOIN + | STRAIGHT_JOIN + ; + +outer_join_type + : (FULL|LEFT|RIGHT) OUTER? JOIN + ; + + +with_clause + : WITH RECURSIVE? with_list + ; + +with_list + : common_table_expr (Comma common_table_expr)* + ; + +common_table_expr + : relation_name (LeftParen alias_name_list RightParen)? AS LeftParen with_clause? (select_no_parens |select_with_parens) RightParen + ; + +alias_name_list + : column_alias_name (Comma column_alias_name)* + ; + +column_alias_name + : column_name + ; + +table_values_clause + : VALUES values_row_list + ; + +table_values_clause_with_order_by_and_limit + : table_values_clause order_by + | table_values_clause order_by? limit_clause + ; + +values_row_list + : row_value (Comma row_value)* + ; + +row_value + : ROW LeftParen insert_vals RightParen + ; + +analyze_stmt + : ANALYZE TABLE relation_factor UPDATE HISTOGRAM ON column_name_list WITH INTNUM BUCKETS + | ANALYZE TABLE relation_factor DROP HISTOGRAM ON column_name_list + | ANALYZE TABLE relation_factor use_partition? analyze_statistics_clause + ; + +analyze_statistics_clause + : COMPUTE STATISTICS opt_analyze_for_clause_list? + | ESTIMATE STATISTICS opt_analyze_for_clause_list? (SAMPLE INTNUM sample_option)? + ; + +opt_analyze_for_clause_list + : opt_analyze_for_clause_element + ; + +opt_analyze_for_clause_element + : FOR TABLE + | for_all + | for_columns + ; + +sample_option + : ROWS + | PERCENTAGE + ; + +for_all + : FOR ALL (INDEXED | HIDDEN_)? COLUMNS size_clause? + ; + +size_clause + : SIZE (AUTO|REPEAT|SKEWONLY) + | SIZE number_literal + ; + +for_columns + : FOR COLUMNS for_columns_list? + ; + +for_columns_list + : for_columns_item + | for_columns_list for_columns_item + | for_columns_list Comma for_columns_item + ; + +for_columns_item + : column_clause size_clause? + | size_clause + ; + +column_clause + : column_name + | LeftParen column_name_list RightParen + ; + +create_outline_stmt + : CREATE (OR REPLACE)? OUTLINE relation_name ON explainable_stmt (TO explainable_stmt)? + | CREATE (OR REPLACE)? OUTLINE relation_name ON STRING_VALUE USING HINT_HINT_BEGIN hint_list_with_end + ; + +alter_outline_stmt + : ALTER OUTLINE relation_name ADD explainable_stmt (TO explainable_stmt)? + ; + +drop_outline_stmt + : DROP OUTLINE relation_factor + ; + +explain_stmt + : explain_or_desc relation_factor (STRING_VALUE | column_name)? + | explain_or_desc explainable_stmt + | explain_or_desc PRETTY explainable_stmt + | explain_or_desc PRETTY_COLOR explainable_stmt + | explain_or_desc BASIC explainable_stmt + | explain_or_desc BASIC PRETTY explainable_stmt + | explain_or_desc BASIC PRETTY_COLOR explainable_stmt + | explain_or_desc OUTLINE explainable_stmt + | explain_or_desc OUTLINE PRETTY explainable_stmt + | explain_or_desc OUTLINE PRETTY_COLOR explainable_stmt + | explain_or_desc EXTENDED explainable_stmt + | explain_or_desc EXTENDED PRETTY explainable_stmt + | explain_or_desc EXTENDED PRETTY_COLOR explainable_stmt + | explain_or_desc EXTENDED_NOADDR explainable_stmt + | explain_or_desc EXTENDED_NOADDR PRETTY explainable_stmt + | explain_or_desc EXTENDED_NOADDR PRETTY_COLOR explainable_stmt + | explain_or_desc PLANREGRESS explainable_stmt + | explain_or_desc PLANREGRESS PRETTY explainable_stmt + | explain_or_desc PLANREGRESS PRETTY_COLOR explainable_stmt + | explain_or_desc PARTITIONS explainable_stmt + | explain_or_desc PARTITIONS PRETTY explainable_stmt + | explain_or_desc PARTITIONS PRETTY_COLOR explainable_stmt + | explain_or_desc SET STATEMENT_ID COMP_EQ literal explainable_stmt + | explain_or_desc INTO relation_name explainable_stmt + | explain_or_desc INTO relation_name SET STATEMENT_ID COMP_EQ literal explainable_stmt + | explain_or_desc FORMAT COMP_EQ format_name explainable_stmt + ; + +explain_or_desc + : EXPLAIN + | DESCRIBE + | DESC + ; + +explainable_stmt + : select_stmt + | delete_stmt + | insert_stmt + | update_stmt + ; + +format_name + : TRADITIONAL + | JSON + ; + +show_stmt + : SHOW FULL? TABLES (from_or_in database_factor)? ((LIKE STRING_VALUE) | (LIKE STRING_VALUE ESCAPE STRING_VALUE) | (WHERE expr))? + | SHOW databases_or_schemas STATUS? ((LIKE STRING_VALUE) | (LIKE STRING_VALUE ESCAPE STRING_VALUE) | (WHERE expr))? + | SHOW FULL? columns_or_fields from_or_in relation_factor (from_or_in database_factor)? ((LIKE STRING_VALUE) | (LIKE STRING_VALUE ESCAPE STRING_VALUE) | (WHERE expr))? + | SHOW (TABLE|PROCEDURE|FUNCTION|TRIGGERS) STATUS (from_or_in database_factor)? ((LIKE STRING_VALUE) | (LIKE STRING_VALUE ESCAPE STRING_VALUE) | (WHERE expr))? + | SHOW SERVER STATUS ((LIKE STRING_VALUE) | (LIKE STRING_VALUE ESCAPE STRING_VALUE) | (WHERE expr))? + | SHOW (GLOBAL | SESSION | LOCAL)? VARIABLES ((LIKE STRING_VALUE) | (LIKE STRING_VALUE ESCAPE STRING_VALUE) | (WHERE expr))? + | SHOW SCHEMA + | SHOW CREATE database_or_schema (IF not EXISTS)? database_factor + | SHOW CREATE (TABLE|VIEW|PROCEDURE|FUNCTION|TRIGGER) relation_factor + | SHOW (WARNINGS|ERRORS) ((LIMIT INTNUM Comma INTNUM) | (LIMIT INTNUM))? + | SHOW COUNT LeftParen Star RightParen (WARNINGS|ERRORS) + | SHOW GRANTS opt_for_grant_user + | SHOW charset_key ((LIKE STRING_VALUE) | (LIKE STRING_VALUE ESCAPE STRING_VALUE) | (WHERE expr))? + | SHOW (TRACE|COLLATION|PARAMETERS|TABLEGROUPS) ((LIKE STRING_VALUE) | (LIKE STRING_VALUE ESCAPE STRING_VALUE) | (WHERE expr))? + | SHOW TRACE FORMAT COMP_EQ STRING_VALUE ((LIKE STRING_VALUE) | (LIKE STRING_VALUE ESCAPE STRING_VALUE) | (WHERE expr))? + | SHOW index_or_indexes_or_keys from_or_in relation_factor (from_or_in database_factor)? (WHERE opt_hint_value expr)? + | SHOW FULL? PROCESSLIST + | SHOW (GLOBAL | SESSION | LOCAL)? STATUS ((LIKE STRING_VALUE) | (LIKE STRING_VALUE ESCAPE STRING_VALUE) | (WHERE expr))? + | SHOW TENANT STATUS? + | SHOW CREATE TENANT relation_name + | SHOW STORAGE? ENGINES + | SHOW PRIVILEGES + | SHOW QUERY_RESPONSE_TIME + | SHOW RECYCLEBIN + | SHOW CREATE TABLEGROUP relation_name + | SHOW RESTORE PREVIEW + | SHOW SEQUENCES ((LIKE STRING_VALUE) | (LIKE STRING_VALUE ESCAPE STRING_VALUE) | (WHERE expr))? (from_or_in database_factor)? + ; + +get_diagnostics_stmt + : get_condition_diagnostics_stmt + | get_statement_diagnostics_stmt + ; + +get_condition_diagnostics_stmt + : GET (CURRENT|STACKED)? DIAGNOSTICS CONDITION condition_arg condition_information_item_list + ; + +condition_arg + : INTNUM + | USER_VARIABLE + | STRING_VALUE + | BOOL_VALUE + | QUESTIONMARK + | column_name + ; + +condition_information_item_list + : condition_information_item (Comma condition_information_item)* + ; + +condition_information_item + : (QUESTIONMARK|USER_VARIABLE|column_name) COMP_EQ condition_information_item_name + ; + +condition_information_item_name + : CLASS_ORIGIN + | SUBCLASS_ORIGIN + | RETURNED_SQLSTATE + | MESSAGE_TEXT + | MYSQL_ERRNO + | CONSTRAINT_CATALOG + | CONSTRAINT_SCHEMA + | CONSTRAINT_NAME + | CATALOG_NAME + | SCHEMA_NAME + | TABLE_NAME + | COLUMN_NAME + | CURSOR_NAME + ; + +get_statement_diagnostics_stmt + : GET (CURRENT|STACKED)? DIAGNOSTICS statement_information_item_list + ; + +statement_information_item_list + : statement_information_item (Comma statement_information_item)* + ; + +statement_information_item + : (QUESTIONMARK|USER_VARIABLE|column_name) COMP_EQ statement_information_item_name + ; + +statement_information_item_name + : NUMBER + | ROW_COUNT + ; + +databases_or_schemas + : DATABASES + | SCHEMAS + ; + +opt_for_grant_user + : opt_for_user + | FOR CURRENT_USER (LeftParen RightParen)? + ; + +columns_or_fields + : COLUMNS + | FIELDS + ; + +database_or_schema + : DATABASE + | SCHEMA + ; + +index_or_indexes_or_keys + : INDEX + | INDEXES + | KEYS + ; + +from_or_in + : FROM + | IN + ; + +calibration_info_list + : empty + | STRING_VALUE + | calibration_info_list Comma STRING_VALUE + ; + +help_stmt + : HELP STRING_VALUE + | HELP NAME_OB + ; + +create_tablespace_stmt + : CREATE TABLESPACE tablespace permanent_tablespace + ; + +permanent_tablespace + : permanent_tablespace_options? + ; + +permanent_tablespace_option + : ENCRYPTION COMP_EQ? STRING_VALUE + ; + +drop_tablespace_stmt + : DROP TABLESPACE tablespace + ; + +alter_tablespace_actions + : alter_tablespace_action (Comma alter_tablespace_action)? + ; + +alter_tablespace_action + : SET? permanent_tablespace_option + ; + +alter_tablespace_stmt + : ALTER TABLESPACE tablespace alter_tablespace_actions + ; + +rotate_master_key_stmt + : ALTER INSTANCE ROTATE INNODB MASTER KEY + ; + +permanent_tablespace_options + : permanent_tablespace_option (Comma permanent_tablespace_option)* + ; + +create_user_stmt + : CREATE USER (IF not EXISTS)? user_specification_list require_specification? (WITH resource_option_list)? + ; + +user_specification_list + : user_specification (Comma user_specification)* + ; + +user_specification + : user USER_VARIABLE? + | user USER_VARIABLE? IDENTIFIED BY password + | user USER_VARIABLE? IDENTIFIED BY PASSWORD password + ; + +require_specification + : REQUIRE (NONE|SSL|X509) + | REQUIRE tls_option_list + ; + +resource_option_list + : resource_option+ + ; + +resource_option + : MAX_CONNECTIONS_PER_HOUR INTNUM + | MAX_USER_CONNECTIONS INTNUM + ; + +tls_option_list + : tls_option + | tls_option_list tls_option + | tls_option_list AND tls_option + ; + +tls_option + : (CIPHER|ISSUER|SUBJECT) STRING_VALUE + ; + +user + : STRING_VALUE + | NAME_OB + | unreserved_keyword + ; + +opt_host_name + : USER_VARIABLE? + ; + +user_with_host_name + : user USER_VARIABLE? + ; + +password + : STRING_VALUE + ; + +drop_user_stmt + : DROP USER user_list + ; + +user_list + : user_with_host_name (Comma user_with_host_name)* + ; + +set_password_stmt + : SET PASSWORD (FOR user opt_host_name)? COMP_EQ STRING_VALUE + | SET PASSWORD (FOR user opt_host_name)? COMP_EQ PASSWORD LeftParen password RightParen + | ALTER USER user_with_host_name IDENTIFIED BY password + | ALTER USER user_with_host_name require_specification + | ALTER USER user_with_host_name WITH resource_option_list + ; + +opt_for_user + : FOR user opt_host_name + | empty + ; + +rename_user_stmt + : RENAME USER rename_list + ; + +rename_info + : user USER_VARIABLE? TO user USER_VARIABLE? + ; + +rename_list + : rename_info (Comma rename_info)* + ; + +lock_user_stmt + : ALTER USER user_list ACCOUNT lock_spec_mysql57 + ; + +lock_spec_mysql57 + : LOCK_ + | UNLOCK + ; + +lock_tables_stmt + : LOCK_ table_or_tables lock_table_list + ; + +unlock_tables_stmt + : UNLOCK TABLES + ; + +lock_table_list + : lock_table (Comma lock_table)* + ; + +lock_table + : relation_factor lock_type + | relation_factor AS? relation_name lock_type + ; + +lock_type + : READ LOCAL? + | WRITE + | LOW_PRIORITY WRITE + ; + +create_sequence_stmt + : CREATE SEQUENCE (IF not EXISTS)? relation_factor sequence_option_list? + ; + +sequence_option_list + : sequence_option+ + ; + +sequence_option + : (INCREMENT BY|MAXVALUE) simple_num + | (MINVALUE|START WITH) simple_num + | NOMAXVALUE + | NOMINVALUE + | CYCLE + | NOCYCLE + | CACHE simple_num + | NOCACHE + | ORDER + | NOORDER + | RESTART + ; + +simple_num + : (INTNUM|DECIMAL_VAL) + | (Minus|Plus) (INTNUM|DECIMAL_VAL) + ; + +drop_sequence_stmt + : DROP SEQUENCE (IF EXISTS)? relation_factor + ; + +alter_sequence_stmt + : ALTER SEQUENCE relation_factor sequence_option_list? + ; + +create_dblink_stmt + : CREATE DATABASE LINK (IF not EXISTS)? relation_name CONNECT TO user USER_VARIABLE DATABASE database_factor IDENTIFIED BY password ip_port (CLUSTER STRING_VALUE)? + ; + +drop_dblink_stmt + : DROP DATABASE LINK (IF EXISTS)? relation_name + ; + +begin_stmt + : BEGIN HINT_VALUE? WORK? + | START HINT_VALUE? TRANSACTION ((WITH CONSISTENT SNAPSHOT) | transaction_access_mode | (WITH CONSISTENT SNAPSHOT Comma transaction_access_mode) | (transaction_access_mode Comma WITH CONSISTENT SNAPSHOT))? + ; + +xa_begin_stmt + : XA (BEGIN|START) STRING_VALUE + ; + +xa_end_stmt + : XA END STRING_VALUE + ; + +xa_prepare_stmt + : XA PREPARE STRING_VALUE + ; + +xa_commit_stmt + : XA COMMIT STRING_VALUE + ; + +xa_rollback_stmt + : XA ROLLBACK STRING_VALUE + ; + +commit_stmt + : COMMIT HINT_VALUE? WORK? + ; + +rollback_stmt + : ROLLBACK WORK? + | ROLLBACK HINT_VALUE WORK? + ; + +kill_stmt + : KILL (CONNECTION?|QUERY) expr + ; + +grant_stmt + : GRANT grant_privileges ON priv_level TO user_specification_list grant_options + ; + +grant_privileges + : priv_type_list + | ALL PRIVILEGES? + ; + +priv_type_list + : priv_type (Comma priv_type)* + ; + +priv_type + : ALTER TENANT? + | CREATE (RESOURCE POOL|USER?) + | DELETE + | DROP (DATABASE LINK)? + | GRANT OPTION + | INSERT + | UPDATE + | SELECT + | INDEX + | CREATE (RESOURCE UNIT|VIEW) + | SHOW VIEW + | SHOW DATABASES + | SUPER + | PROCESS + | USAGE + | FILEX + | ALTER SYSTEM + | REPLICATION SLAVE + | REPLICATION CLIENT + | CREATE DATABASE LINK + ; + +priv_level + : (Star|relation_name) (Dot Star)? + | relation_name Dot relation_name + ; + +grant_options + : WITH GRANT OPTION + | empty + ; + +revoke_stmt + : REVOKE grant_privileges ON priv_level FROM user_list + | REVOKE ALL PRIVILEGES? Comma GRANT OPTION FROM user_list + ; + +prepare_stmt + : PREPARE stmt_name FROM preparable_stmt + ; + +stmt_name + : column_label + ; + +preparable_stmt + : text_string + | USER_VARIABLE + ; + +variable_set_stmt + : SET var_and_val_list + ; + +sys_var_and_val_list + : sys_var_and_val (Comma sys_var_and_val)* + ; + +var_and_val_list + : var_and_val (Comma var_and_val)* + ; + +set_expr_or_default + : expr + | ON + | BINARY + | DEFAULT + ; + +var_and_val + : USER_VARIABLE (SET_VAR|to_or_eq) expr + | sys_var_and_val + | (SYSTEM_VARIABLE|scope_or_scope_alias column_name) to_or_eq set_expr_or_default + ; + +sys_var_and_val + : var_name (SET_VAR|to_or_eq) set_expr_or_default + ; + +scope_or_scope_alias + : GLOBAL + | SESSION + | GLOBAL_ALIAS Dot + | SESSION_ALIAS Dot + ; + +to_or_eq + : TO + | COMP_EQ + ; + +execute_stmt + : EXECUTE stmt_name (USING argument_list)? + ; + +argument_list + : argument (Comma argument)* + ; + +argument + : USER_VARIABLE + ; + +deallocate_prepare_stmt + : deallocate_or_drop PREPARE stmt_name + ; + +deallocate_or_drop + : DEALLOCATE + | DROP + ; + +truncate_table_stmt + : TRUNCATE TABLE? relation_factor + ; + +audit_stmt + : audit_or_noaudit audit_clause + ; + +audit_or_noaudit + : AUDIT + | NOAUDIT + ; + +audit_clause + : audit_operation_clause (auditing_by_user_clause|auditing_on_clause?) op_audit_tail_clause + ; + +audit_operation_clause + : audit_all_shortcut_list + | ALL STATEMENTS? + ; + +audit_all_shortcut_list + : audit_all_shortcut (Comma audit_all_shortcut)* + ; + +auditing_on_clause + : ON normal_relation_factor + | ON DEFAULT + ; + +audit_user_list + : audit_user_with_host_name (Comma audit_user_with_host_name)* + ; + +audit_user_with_host_name + : audit_user USER_VARIABLE? + ; + +audit_user + : STRING_VALUE + | NAME_OB + | unreserved_keyword_normal + ; + +auditing_by_user_clause + : BY audit_user_list + ; + +op_audit_tail_clause + : empty + | audit_by_session_access_option audit_whenever_option? + | audit_whenever_option + ; + +audit_by_session_access_option + : BY ACCESS + ; + +audit_whenever_option + : WHENEVER NOT? SUCCESSFUL + ; + +audit_all_shortcut + : ALTER SYSTEM? + | CLUSTER + | CONTEXT + | MATERIALIZED? VIEW + | NOT EXISTS + | OUTLINE + | EXECUTE? PROCEDURE + | PROFILE + | SESSION + | SYSTEM? AUDIT + | SYSTEM? GRANT + | ALTER? TABLE + | TABLESPACE + | TRIGGER + | GRANT? TYPE + | USER + | COMMENT TABLE? + | DELETE TABLE? + | GRANT PROCEDURE + | GRANT TABLE + | INSERT TABLE? + | SELECT TABLE? + | UPDATE TABLE? + | EXECUTE + | FLASHBACK + | INDEX + | RENAME + ; + +rename_table_stmt + : RENAME TABLE rename_table_actions + ; + +rename_table_actions + : rename_table_action (Comma rename_table_action)* + ; + +rename_table_action + : relation_factor TO relation_factor + ; + +alter_table_stmt + : ALTER EXTERNAL? TABLE relation_factor alter_table_actions? + ; + +alter_table_actions + : alter_table_action + | alter_table_actions Comma alter_table_action + ; + +alter_table_action + : SET? table_option_list_space_seperated + | CONVERT TO CHARACTER SET charset_name collation? + | alter_column_option + | alter_tablegroup_option + | RENAME TO? relation_factor + | alter_index_option + | alter_partition_option + | alter_constraint_option + | REFRESH + ; + +alter_constraint_option + : ADD out_of_line_constraint + | ADD LeftParen out_of_line_constraint RightParen + | DROP (CHECK | CONSTRAINT) LeftParen name_list RightParen + | DROP (CHECK | CONSTRAINT) constraint_name + | DROP FOREIGN KEY index_name + | DROP PRIMARY KEY + | ALTER (CHECK | CONSTRAINT) constraint_name check_state + ; + +alter_partition_option + : DROP (PARTITION|SUBPARTITION) drop_partition_name_list + | ADD PARTITION opt_partition_range_or_list + | modify_partition_info + | REORGANIZE PARTITION name_list INTO opt_partition_range_or_list + | TRUNCATE (PARTITION|SUBPARTITION) name_list + ; + +opt_partition_range_or_list + : opt_range_partition_list + | opt_list_partition_list + ; + +alter_tg_partition_option + : DROP (PARTITION|SUBPARTITION) drop_partition_name_list + | ADD PARTITION opt_partition_range_or_list + | modify_tg_partition_info + | REORGANIZE PARTITION name_list INTO opt_partition_range_or_list + | TRUNCATE PARTITION name_list + ; + +drop_partition_name_list + : name_list + | LeftParen name_list RightParen + ; + +modify_partition_info + : hash_partition_option + | key_partition_option + | range_partition_option + | list_partition_option + ; + +modify_tg_partition_info + : tg_hash_partition_option + | tg_key_partition_option + | tg_range_partition_option + | tg_list_partition_option + ; + +alter_index_option + : ADD out_of_line_index + | ADD LeftParen out_of_line_index RightParen + | DROP key_or_index index_name + | ALTER INDEX index_name (visibility_option | parallel_option) + | RENAME key_or_index index_name TO index_name + ; + +visibility_option + : VISIBLE + | INVISIBLE + ; + +alter_column_option + : ADD COLUMN? column_definition + | ADD COLUMN? LeftParen column_definition_list RightParen + | DROP column_definition_ref (CASCADE | RESTRICT)? + | DROP COLUMN column_definition_ref (CASCADE | RESTRICT)? + | ALTER COLUMN? column_definition_ref alter_column_behavior + | CHANGE COLUMN? column_definition_ref column_definition + | MODIFY COLUMN? column_definition + | RENAME COLUMN column_definition_ref TO column_name + ; + +alter_tablegroup_option + : DROP TABLEGROUP + ; + +alter_column_behavior + : SET DEFAULT signed_literal + | DROP DEFAULT + ; + +flashback_stmt + : FLASHBACK TABLE relation_factor TO BEFORE DROP (RENAME TO relation_factor)? + | FLASHBACK database_key database_factor TO BEFORE DROP (RENAME TO database_factor)? + | FLASHBACK TENANT relation_name TO BEFORE DROP (RENAME TO relation_name)? + ; + +purge_stmt + : PURGE (((INDEX|TABLE) relation_factor|(RECYCLEBIN|database_key database_factor))|TENANT relation_name) + ; + +optimize_stmt + : OPTIMIZE TABLE table_list + | OPTIMIZE TENANT (ALL|relation_name) + ; + +dump_memory_stmt + : DUMP (CHUNK|ENTITY) ALL + | DUMP ENTITY P_ENTITY COMP_EQ STRING_VALUE Comma SLOT_IDX COMP_EQ INTNUM + | DUMP CHUNK TENANT_ID COMP_EQ INTNUM Comma CTX_ID COMP_EQ relation_name_or_string + | DUMP CHUNK P_CHUNK COMP_EQ STRING_VALUE + | SET OPTION LEAK_MOD COMP_EQ STRING_VALUE + | SET OPTION LEAK_RATE COMP_EQ INTNUM + | DUMP MEMORY LEAK + ; + +alter_system_stmt + : ALTER SYSTEM BOOTSTRAP (CLUSTER cluster_role)? server_info_list (PRIMARY_CLUSTER_ID INTNUM PRIMARY_ROOTSERVICE_LIST STRING_VALUE)? + | ALTER SYSTEM FLUSH cache_type CACHE sql_id_expr? databases_expr? (TENANT COMP_EQ tenant_name_list)? flush_scope + | ALTER SYSTEM FLUSH SQL cache_type (TENANT COMP_EQ tenant_name_list)? flush_scope + | ALTER SYSTEM FLUSH KVCACHE tenant_name? cache_name? + | ALTER SYSTEM FLUSH DAG WARNINGS + | ALTER SYSTEM FLUSH ILOGCACHE file_id? + | ALTER SYSTEM ALTER PLAN BASELINE tenant_name? sql_id_expr? baseline_id_expr? SET baseline_asgn_factor + | ALTER SYSTEM LOAD PLAN BASELINE FROM PLAN CACHE (TENANT COMP_EQ tenant_name_list)? sql_id_expr? + | ALTER SYSTEM SWITCH REPLICA ls_role ls_server_or_server_or_zone_or_tenant + | ALTER SYSTEM SWITCH ROOTSERVICE partition_role server_or_zone + | ALTER SYSTEM alter_or_change_or_modify REPLICA partition_id_desc ip_port alter_or_change_or_modify change_actions FORCE? + | ALTER SYSTEM DROP REPLICA partition_id_desc ip_port (CREATE_TIMESTAMP opt_equal_mark INTNUM)? zone_desc? FORCE? + | ALTER SYSTEM migrate_action REPLICA partition_id_desc SOURCE COMP_EQ? STRING_VALUE DESTINATION COMP_EQ? STRING_VALUE FORCE? + | ALTER SYSTEM REPORT REPLICA server_or_zone? + | ALTER SYSTEM RECYCLE REPLICA server_or_zone? + | ALTER SYSTEM START MERGE zone_desc + | ALTER SYSTEM suspend_or_resume MERGE tenant_list_tuple? + | ALTER SYSTEM suspend_or_resume RECOVERY zone_desc? + | ALTER SYSTEM CLEAR MERGE ERROR_P tenant_list_tuple? + | ALTER SYSTEM ADD ARBITRATION SERVICE STRING_VALUE + | ALTER SYSTEM REMOVE ARBITRATION SERVICE STRING_VALUE + | ALTER SYSTEM REPLACE ARBITRATION SERVICE STRING_VALUE WITH STRING_VALUE + | ALTER SYSTEM CANCEL cancel_task_type TASK STRING_VALUE + | ALTER SYSTEM MAJOR FREEZE tenant_list_tuple? + | ALTER SYSTEM CHECKPOINT + | ALTER SYSTEM MINOR FREEZE ((tenant_list_tuple opt_tablet_id?) | (tenant_list_tuple ls opt_tablet_id?) | partition_id_desc)? (SERVER opt_equal_mark LeftParen server_list RightParen)? zone_desc? + | ALTER SYSTEM CHECKPOINT SLOG ((TENANT_ID opt_equal_mark INTNUM) | (TENANT opt_equal_mark relation_name_or_string))? ip_port + | ALTER SYSTEM CLEAR ROOTTABLE tenant_name? + | ALTER SYSTEM server_action SERVER server_list zone_desc? + | ALTER SYSTEM ADD ZONE relation_name_or_string add_or_alter_zone_options + | ALTER SYSTEM zone_action ZONE relation_name_or_string + | ALTER SYSTEM alter_or_change_or_modify ZONE relation_name_or_string SET? add_or_alter_zone_options + | ALTER SYSTEM REFRESH SCHEMA server_or_zone? + | ALTER SYSTEM REFRESH MEMORY STAT server_or_zone? + | ALTER SYSTEM WASH MEMORY FRAGMENTATION server_or_zone? + | ALTER SYSTEM REFRESH IO CALIBRATION (STORAGE opt_equal_mark STRING_VALUE)? (CALIBRATION_INFO opt_equal_mark LeftParen calibration_info_list RightParen)? server_or_zone? + | ALTER SYSTEM SET? alter_system_set_parameter_actions + | ALTER SYSTEM SET_TP alter_system_settp_actions server_or_zone? + | ALTER SYSTEM CLEAR LOCATION CACHE server_or_zone? + | ALTER SYSTEM REMOVE BALANCE TASK (TENANT COMP_EQ tenant_name_list)? (ZONE COMP_EQ zone_list)? (TYPE opt_equal_mark balance_task_type)? + | ALTER SYSTEM RELOAD GTS + | ALTER SYSTEM RELOAD UNIT + | ALTER SYSTEM RELOAD SERVER + | ALTER SYSTEM RELOAD ZONE + | ALTER SYSTEM MIGRATE UNIT COMP_EQ? INTNUM DESTINATION COMP_EQ? STRING_VALUE + | ALTER SYSTEM CANCEL MIGRATE UNIT INTNUM + | ALTER SYSTEM UPGRADE VIRTUAL SCHEMA + | ALTER SYSTEM RUN JOB STRING_VALUE server_or_zone? + | ALTER SYSTEM upgrade_action UPGRADE + | ALTER SYSTEM RUN UPGRADE JOB STRING_VALUE tenant_list_tuple? + | ALTER SYSTEM STOP UPGRADE JOB + | ALTER SYSTEM upgrade_action ROLLING UPGRADE + | ALTER SYSTEM REFRESH TIME_ZONE_INFO + | ALTER SYSTEM ENABLE SQL THROTTLE (FOR PRIORITY COMP_LE INTNUM)? opt_sql_throttle_using_cond + | ALTER SYSTEM DISABLE SQL THROTTLE + | ALTER SYSTEM SET DISK VALID ip_port + | ALTER SYSTEM SET NETWORK BANDWIDTH REGION relation_name_or_string TO relation_name_or_string conf_const + | ALTER SYSTEM ADD RESTORE SOURCE STRING_VALUE + | ALTER SYSTEM CLEAR RESTORE SOURCE + | ALTER SYSTEM RESTORE tenant_name FROM STRING_VALUE + | ALTER SYSTEM RESTORE table_list FOR relation_name (FROM STRING_VALUE)? ((UNTIL TIME COMP_EQ STRING_VALUE) | (UNTIL SCN COMP_EQ INTNUM))? WITH STRING_VALUE (ENCRYPTED BY STRING_VALUE)? (WITH KEY FROM STRING_VALUE opt_encrypt_key)? (DESCRIPTION opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM RESTORE relation_name (FROM STRING_VALUE)? ((UNTIL TIME COMP_EQ STRING_VALUE) | (UNTIL SCN COMP_EQ INTNUM))? WITH STRING_VALUE (ENCRYPTED BY STRING_VALUE)? (WITH KEY FROM STRING_VALUE opt_encrypt_key)? (DESCRIPTION opt_equal_mark STRING_VALUE)? PREVIEW? + | ALTER SYSTEM CHANGE TENANT change_tenant_name_or_tenant_id + | ALTER SYSTEM DROP TABLES IN SESSION INTNUM + | ALTER SYSTEM REFRESH TABLES IN SESSION INTNUM + | ALTER DISKGROUP relation_name ADD DISK STRING_VALUE (NAME opt_equal_mark relation_name_or_string)? ip_port zone_desc? + | ALTER DISKGROUP relation_name DROP DISK STRING_VALUE ip_port zone_desc? + | ALTER SYSTEM ARCHIVELOG (TENANT opt_equal_mark tenant_name_list)? (DESCRIPTION opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM NOARCHIVELOG (TENANT opt_equal_mark tenant_name_list)? (DESCRIPTION opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM BACKUP DATABASE (TO opt_equal_mark STRING_VALUE)? (DESCRIPTION opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM BACKUP INCREMENTAL DATABASE (TO opt_equal_mark STRING_VALUE)? (DESCRIPTION opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM BACKUP (TENANT opt_equal_mark tenant_name_list)? (TO opt_equal_mark STRING_VALUE)? (DESCRIPTION opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM BACKUP INCREMENTAL (TENANT opt_equal_mark tenant_name_list)? (TO opt_equal_mark STRING_VALUE)? (DESCRIPTION opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM BACKUP DATABASE (TO opt_equal_mark STRING_VALUE)? PLUS ARCHIVELOG (DESCRIPTION opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM BACKUP INCREMENTAL DATABASE (TO opt_equal_mark STRING_VALUE)? PLUS ARCHIVELOG (DESCRIPTION opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM BACKUP (TENANT opt_equal_mark tenant_name_list)? (TO opt_equal_mark STRING_VALUE)? PLUS ARCHIVELOG (DESCRIPTION opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM BACKUP INCREMENTAL (TENANT opt_equal_mark tenant_name_list)? (TO opt_equal_mark STRING_VALUE)? PLUS ARCHIVELOG (DESCRIPTION opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM BACKUP KEY (TO opt_equal_mark STRING_VALUE)? (ENCRYPTED BY STRING_VALUE)? + | ALTER SYSTEM BACKUP KEY tenant_list_tuple (TO opt_equal_mark STRING_VALUE)? (ENCRYPTED BY STRING_VALUE)? + | ALTER SYSTEM CANCEL BACKUP (TENANT opt_equal_mark tenant_name_list)? + | ALTER SYSTEM CANCEL RESTORE relation_name + | ALTER SYSTEM SUSPEND BACKUP + | ALTER SYSTEM RESUME BACKUP + | ALTER SYSTEM DELETE EXPIRED BACKUP (COPY INTNUM)? + | ALTER SYSTEM DELETE BACKUPSET INTNUM (COPY INTNUM)? + | ALTER SYSTEM VALIDATE DATABASE (COPY INTNUM)? + | ALTER SYSTEM VALIDATE BACKUPSET INTNUM (COPY INTNUM)? + | ALTER SYSTEM CANCEL VALIDATE INTNUM (COPY INTNUM)? + | ALTER SYSTEM DELETE OBSOLETE BACKUP + | ALTER SYSTEM CANCEL DELETE BACKUP + | ALTER SYSTEM CANCEL BACKUP BACKUPSET + | ALTER SYSTEM DELETE BACKUPPIECE INTNUM (COPY INTNUM)? + | ALTER SYSTEM CANCEL BACKUP BACKUPPIECE + | ALTER SYSTEM DELETE BACKUPROUND INTNUM (COPY INTNUM)? + | ALTER SYSTEM CANCEL ALL BACKUP FORCE + | ALTER SYSTEM DELETE BACKUPSET INTNUM (COPY INTNUM)? (TENANT opt_equal_mark tenant_name_list)? (DESCRIPTION opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM DELETE BACKUPPIECE INTNUM (COPY INTNUM)? (TENANT opt_equal_mark tenant_name_list)? (DESCRIPTION opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM DELETE OBSOLETE BACKUP (TENANT opt_equal_mark tenant_name_list)? (DESCRIPTION opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM CANCEL DELETE BACKUP (TENANT opt_equal_mark tenant_name_list)? (DESCRIPTION opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM ADD DELETE BACKUP policy_name (RECOVERY_WINDOW opt_equal_mark STRING_VALUE)? (REDUNDANCY opt_equal_mark INTNUM)? (BACKUP_COPIES opt_equal_mark INTNUM)? (TENANT opt_equal_mark tenant_name_list)? + | ALTER SYSTEM DROP DELETE BACKUP policy_name (TENANT opt_equal_mark tenant_name_list)? + | ALTER SYSTEM BACKUP BACKUPSET ALL ((TENANT_ID opt_equal_mark INTNUM) | (TENANT opt_equal_mark relation_name_or_string))? (BACKUP_BACKUP_DEST opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM BACKUP BACKUPSET COMP_EQ? INTNUM ((TENANT_ID opt_equal_mark INTNUM) | (TENANT opt_equal_mark relation_name_or_string))? (BACKUP_BACKUP_DEST opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM BACKUP BACKUPSET ALL NOT BACKED UP INTNUM TIMES ((TENANT_ID opt_equal_mark INTNUM) | (TENANT opt_equal_mark relation_name_or_string))? (BACKUP_BACKUP_DEST opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM START BACKUP ARCHIVELOG + | ALTER SYSTEM STOP BACKUP ARCHIVELOG + | ALTER SYSTEM BACKUP BACKUPPIECE ALL (WITH ACTIVE)? ((TENANT_ID opt_equal_mark INTNUM) | (TENANT opt_equal_mark relation_name_or_string))? (BACKUP_BACKUP_DEST opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM BACKUP BACKUPPIECE COMP_EQ? INTNUM (WITH ACTIVE)? ((TENANT_ID opt_equal_mark INTNUM) | (TENANT opt_equal_mark relation_name_or_string))? (BACKUP_BACKUP_DEST opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM BACKUP BACKUPPIECE ALL NOT BACKED UP INTNUM TIMES (WITH ACTIVE)? ((TENANT_ID opt_equal_mark INTNUM) | (TENANT opt_equal_mark relation_name_or_string))? (BACKUP_BACKUP_DEST opt_equal_mark STRING_VALUE)? + | SET ENCRYPTION ON IDENTIFIED BY STRING_VALUE ONLY + | SET DECRYPTION IDENTIFIED BY string_list + | ALTER SYSTEM BACKUP TENANT backup_tenant_name_list TO STRING_VALUE + ; + +opt_sql_throttle_using_cond + : USING sql_throttle_one_or_more_metrics + ; + +sql_throttle_one_or_more_metrics + : sql_throttle_metric sql_throttle_one_or_more_metrics? + ; + +sql_throttle_metric + : ((CPU|RT)|(NETWORK|QUEUE_TIME)) COMP_EQ int_or_decimal + | (IO|LOGICAL_READS) COMP_EQ INTNUM + ; + +change_tenant_name_or_tenant_id + : relation_name_or_string + | TENANT_ID COMP_EQ? INTNUM + ; + +cache_type + : ALL + | LOCATION + | CLOG + | ILOG + | COLUMN_STAT + | BLOCK_INDEX + | BLOCK + | ROW + | BLOOM_FILTER + | SCHEMA + | PLAN + | AUDIT + | PL + | PS + | LIB + ; + +balance_task_type + : AUTO + | MANUAL + | ALL + ; + +tenant_list_tuple + : TENANT COMP_EQ? LeftParen tenant_name_list RightParen + | TENANT COMP_EQ? tenant_name_list + ; + +tenant_name_list + : relation_name_or_string (Comma relation_name_or_string)* + ; + +backup_tenant_name_list + : COMP_EQ? tenant_name_list + ; + +flush_scope + : GLOBAL? + ; + +server_info_list + : server_info (Comma server_info)* + ; + +server_info + : REGION COMP_EQ? relation_name_or_string ZONE COMP_EQ? relation_name_or_string SERVER COMP_EQ? STRING_VALUE + | ZONE COMP_EQ? relation_name_or_string SERVER COMP_EQ? STRING_VALUE + ; + +server_action + : ADD + | CANCEL? DELETE + | START + | FORCE? STOP + | ISOLATE + ; + +server_list + : STRING_VALUE (Comma STRING_VALUE)* + ; + +zone_action + : DELETE + | START + | FORCE? STOP + | ISOLATE + ; + +ip_port + : SERVER COMP_EQ? STRING_VALUE + | HOST STRING_VALUE + ; + +zone_desc + : ZONE COMP_EQ? relation_name_or_string + ; + +policy_name + : POLICY COMP_EQ? STRING_VALUE + ; + +server_or_zone + : ip_port + | zone_desc + ; + +add_or_alter_zone_option + : REGION COMP_EQ? relation_name_or_string + | IDC COMP_EQ? relation_name_or_string + | ZONE_TYPE COMP_EQ? relation_name_or_string + ; + +add_or_alter_zone_options + : add_or_alter_zone_option + | empty + | add_or_alter_zone_options Comma add_or_alter_zone_option + ; + +alter_or_change_or_modify + : ALTER + | CHANGE + | MODIFY + ; + +partition_id_desc + : PARTITION_ID COMP_EQ? STRING_VALUE + ; + +ls + : LS COMP_EQ? INTNUM + ; + +ls_server_or_server_or_zone_or_tenant + : ls ip_port tenant_name + | ip_port tenant_name? + | zone_desc tenant_name? + ; + +migrate_action + : MOVE + | COPY + ; + +change_actions + : change_action change_actions? + ; + +change_action + : replica_type + | memstore_percent + ; + +replica_type + : REPLICA_TYPE COMP_EQ? STRING_VALUE + ; + +memstore_percent + : MEMSTORE_PERCENT COMP_EQ? INTNUM + ; + +suspend_or_resume + : SUSPEND + | RESUME + ; + +baseline_id_expr + : BASELINE_ID COMP_EQ? INTNUM + ; + +sql_id_expr + : SQL_ID COMP_EQ? STRING_VALUE + ; + +baseline_asgn_factor + : column_name COMP_EQ literal + ; + +tenant_name + : TENANT COMP_EQ? relation_name_or_string + ; + +cache_name + : CACHE COMP_EQ? relation_name_or_string + ; + +file_id + : FILE_ID COMP_EQ? INTNUM + ; + +cancel_task_type + : PARTITION MIGRATION + | empty + ; + +alter_system_set_parameter_actions + : alter_system_set_parameter_action (Comma alter_system_set_parameter_action)* + ; + +alter_system_set_parameter_action + : NAME_OB COMP_EQ conf_const (COMMENT STRING_VALUE)? ((SCOPE COMP_EQ MEMORY) | (SCOPE COMP_EQ SPFILE) | (SCOPE COMP_EQ BOTH))? server_or_zone? tenant_name? + | TABLET_SIZE COMP_EQ conf_const (COMMENT STRING_VALUE)? ((SCOPE COMP_EQ MEMORY) | (SCOPE COMP_EQ SPFILE) | (SCOPE COMP_EQ BOTH))? server_or_zone? tenant_name? + | CLUSTER_ID COMP_EQ conf_const (COMMENT STRING_VALUE)? ((SCOPE COMP_EQ MEMORY) | (SCOPE COMP_EQ SPFILE) | (SCOPE COMP_EQ BOTH))? server_or_zone? tenant_name? + | ROOTSERVICE_LIST COMP_EQ STRING_VALUE (COMMENT STRING_VALUE)? ((SCOPE COMP_EQ MEMORY) | (SCOPE COMP_EQ SPFILE) | (SCOPE COMP_EQ BOTH))? server_or_zone? tenant_name? + | BACKUP_BACKUP_DEST COMP_EQ STRING_VALUE (COMMENT STRING_VALUE)? ((SCOPE COMP_EQ MEMORY) | (SCOPE COMP_EQ SPFILE) | (SCOPE COMP_EQ BOTH))? server_or_zone? tenant_name? + | OBCONFIG_URL COMP_EQ STRING_VALUE (COMMENT STRING_VALUE)? ((SCOPE COMP_EQ MEMORY) | (SCOPE COMP_EQ SPFILE) | (SCOPE COMP_EQ BOTH))? server_or_zone? tenant_name? + | LOG_DISK_SIZE COMP_EQ STRING_VALUE (COMMENT STRING_VALUE)? ((SCOPE COMP_EQ MEMORY) | (SCOPE COMP_EQ SPFILE) | (SCOPE COMP_EQ BOTH))? server_or_zone? tenant_name? + | LOG_RESTORE_SOURCE COMP_EQ STRING_VALUE (COMMENT STRING_VALUE)? ((SCOPE COMP_EQ MEMORY) | (SCOPE COMP_EQ SPFILE) | (SCOPE COMP_EQ BOTH))? server_or_zone? tenant_name? + ; + +alter_system_settp_actions + : settp_option + | empty + | alter_system_settp_actions Comma settp_option + ; + +settp_option + : TP_NO COMP_EQ? INTNUM + | TP_NAME COMP_EQ? relation_name_or_string + | OCCUR COMP_EQ? INTNUM + | FREQUENCY COMP_EQ? INTNUM + | ERROR_CODE COMP_EQ? INTNUM + | MATCH COMP_EQ? INTNUM + ; + +cluster_role + : PRIMARY + | STANDBY + ; + +partition_role + : LEADER + | FOLLOWER + ; + +ls_role + : LEADER + | FOLLOWER + | DEFAULT + ; + +upgrade_action + : BEGIN + | END + ; + +method_opt + : method_list + ; + +method_list + : method+ + ; + +method + : for_all + | for_columns + ; + +set_names_stmt + : SET NAMES charset_name_or_default collation? + ; + +set_charset_stmt + : SET charset_key charset_name_or_default + ; + +set_transaction_stmt + : SET ((GLOBAL?|SESSION)|LOCAL) TRANSACTION transaction_characteristics + ; + +transaction_characteristics + : transaction_access_mode + | (transaction_access_mode Comma)? ISOLATION LEVEL isolation_level + | ISOLATION LEVEL isolation_level Comma transaction_access_mode + ; + +transaction_access_mode + : READ ONLY + | READ WRITE + ; + +isolation_level + : READ UNCOMMITTED + | READ COMMITTED + | REPEATABLE READ + | SERIALIZABLE + ; + +opt_encrypt_key + : empty + | ENCRYPTED BY STRING_VALUE + ; + +create_savepoint_stmt + : SAVEPOINT var_name + ; + +rollback_savepoint_stmt + : ROLLBACK WORK? TO var_name + | ROLLBACK TO SAVEPOINT var_name + ; + +release_savepoint_stmt + : RELEASE SAVEPOINT var_name + ; + +alter_cluster_stmt + : ALTER SYSTEM cluster_action VERIFY + | ALTER SYSTEM cluster_action cluster_define FORCE? + | ALTER SYSTEM alter_or_change_or_modify CLUSTER cluster_define SET? cluster_option_list + ; + +cluster_define + : cluster_name CLUSTER_ID COMP_EQ? conf_const + ; + +cluster_option_list + : cluster_option (Comma cluster_option_list)? + ; + +cluster_option + : ROOTSERVICE_LIST COMP_EQ? STRING_VALUE + | REDO_TRANSPORT_OPTIONS COMP_EQ? relation_name_or_string + ; + +cluster_action + : ADD CLUSTER + | REMOVE CLUSTER + | (DISABLE|ENABLE) CLUSTER SYNCHRONIZATION + ; + +switchover_cluster_stmt + : ALTER SYSTEM commit_switchover_clause FORCE? + ; + +commit_switchover_clause + : COMMIT TO SWITCHOVER TO PRIMARY (WITH SESSION SHUTDOWN)? + | COMMIT TO SWITCHOVER TO PHYSICAL STANDBY (WITH SESSION SHUTDOWN)? + | ACTIVATE PHYSICAL STANDBY CLUSTER + | CONVERT TO PHYSICAL STANDBY + | FAILOVER TO cluster_define + ; + +protection_mode_stmt + : ALTER SYSTEM SET STANDBY CLUSTER TO MAXIMIZE protection_mode_option + ; + +protection_mode_option + : AVAILABILITY + | PERFORMANCE + | PROTECTION + ; + +cluster_name + : relation_name + | STRING_VALUE + ; + +disconnect_cluster_stmt + : ALTER SYSTEM DISCONNECT STANDBY CLUSTER cluster_define SET CLUSTER_NAME cluster_name (OBCONFIG_URL STRING_VALUE)? FORCE? VERIFY? + ; + +var_name + : NAME_OB + | unreserved_keyword_normal + | new_or_old_column_ref + ; + +new_or_old + : NEW + | OLD + ; + +new_or_old_column_ref + : new_or_old Dot column_name + ; + +column_name + : NAME_OB + | unreserved_keyword + ; + +relation_name + : NAME_OB + | unreserved_keyword + ; + +function_name + : NAME_OB + | RANDOM + | DUMP + | CHARSET + | COLLATION + | KEY_VERSION + | USER + | DATABASE + | SCHEMA + | COALESCE + | REPEAT + | ROW_COUNT + | REVERSE + | RIGHT + | CURRENT_USER + | SYSTEM_USER + | SESSION_USER + | REPLACE + | TRUNCATE + | FORMAT + | NORMAL + ; + +column_label + : NAME_OB + | unreserved_keyword + ; + +date_unit + : DAY + | DAY_HOUR + | DAY_MICROSECOND + | DAY_MINUTE + | DAY_SECOND + | HOUR + | HOUR_MICROSECOND + | HOUR_MINUTE + | HOUR_SECOND + | MICROSECOND + | MINUTE + | MINUTE_MICROSECOND + | MINUTE_SECOND + | MONTH + | QUARTER + | SECOND + | SECOND_MICROSECOND + | WEEK + | YEAR + | YEAR_MONTH + ; + +json_table_expr + : JSON_TABLE LeftParen simple_expr Comma literal mock_jt_on_error_on_empty COLUMNS LeftParen jt_column_list RightParen RightParen + ; + +mock_jt_on_error_on_empty + : empty + ; + +jt_column_list + : json_table_column_def (Comma json_table_column_def)* + ; + +json_table_column_def + : json_table_ordinality_column_def + | json_table_exists_column_def + | json_table_value_column_def + | json_table_nested_column_def + ; + +json_table_ordinality_column_def + : column_name FOR ORDINALITY + ; + +json_table_exists_column_def + : column_name data_type collation? EXISTS PATH literal mock_jt_on_error_on_empty + ; + +json_table_value_column_def + : column_name data_type collation? PATH literal opt_value_on_empty_or_error_or_mismatch + ; + +json_table_nested_column_def + : NESTED PATH? literal COLUMNS LeftParen jt_column_list RightParen + ; + +opt_value_on_empty_or_error_or_mismatch + : opt_on_empty_or_error opt_on_mismatch + ; + +opt_on_mismatch + : empty + ; + +json_value_expr + : JSON_VALUE LeftParen simple_expr Comma complex_string_literal (RETURNING cast_data_type)? TRUNCATE? ASCII? (on_empty | on_error | (on_empty on_error))? RightParen + ; + +opt_on_empty_or_error + : empty + | on_empty on_error? + | on_error + ; + +on_empty + : json_on_response ON EMPTY + ; + +on_error + : json_on_response ON ERROR_P + ; + +json_on_response + : ERROR_P + | NULLX + | DEFAULT signed_literal + ; + +unreserved_keyword + : unreserved_keyword_normal + | unreserved_keyword_special + | unreserved_keyword_extra + ; + +unreserved_keyword_normal + : ACCOUNT + | ACTION + | ACTIVE + | ADDDATE + | AFTER + | AGAINST + | AGGREGATE + | ALGORITHM + | ALWAYS + | ANALYSE + | ANY + | APPROX_COUNT_DISTINCT + | APPROX_COUNT_DISTINCT_SYNOPSIS + | APPROX_COUNT_DISTINCT_SYNOPSIS_MERGE + | ARCHIVELOG + | ARBITRATION + | ASCII + | AT + | AUDIT + | AUTHORS + | AUTO + | AUTOEXTEND_SIZE + | AUTO_INCREMENT + | AUTO_INCREMENT_MODE + | AVG + | AVG_ROW_LENGTH + | BACKUP + | BACKUPSET + | BACKUP_COPIES + | BADFILE + | BASE + | BASELINE + | BASELINE_ID + | BASIC + | BALANCE + | BANDWIDTH + | BEGIN + | BINDING + | BINLOG + | BIT + | BIT_AND + | BIT_OR + | BIT_XOR + | BISON_LIST + | BLOCK + | BLOCK_SIZE + | BLOCK_INDEX + | BLOOM_FILTER + | BOOL + | BOOLEAN + | BOOTSTRAP + | BTREE + | BYTE + | BREADTH + | BUCKETS + | CACHE + | CALIBRATION + | CALIBRATION_INFO + | KVCACHE + | ILOGCACHE + | CALC_PARTITION_ID + | CANCEL + | CASCADED + | CAST + | CATALOG_NAME + | CHAIN + | CHANGED + | CHARSET + | CHECKSUM + | CHECKPOINT + | CHUNK + | CIPHER + | CLASS_ORIGIN + | CLEAN + | CLEAR + | CLIENT + | CLOSE + | CLOG + | CLUSTER + | CLUSTER_ID + | CLUSTER_NAME + | COALESCE + | CODE + | COLLATION + | COLUMN_FORMAT + | COLUMN_NAME + | COLUMN_STAT + | COLUMNS + | COMMENT + | COMMIT + | COMMITTED + | COMPACT + | COMPLETION + | COMPRESSED + | COMPRESSION + | COMPUTE + | CONCURRENT + | CONDENSED + | CONNECTION + | CONSISTENT + | CONSISTENT_MODE + | CONSTRAINT_CATALOG + | CONSTRAINT_NAME + | CONSTRAINT_SCHEMA + | CONTAINS + | CONTEXT + | CONTRIBUTORS + | COPY + | COUNT + | CPU + | CREATE_TIMESTAMP + | CTXCAT + | CTX_ID + | CUBE + | CUME_DIST + | CURDATE + | CURRENT + | CURSOR_NAME + | CURTIME + | CYCLE + | DAG + | DATA + | DATABASE_ID + | DATAFILE + | DATA_TABLE_ID + | DATE + | DATE_ADD + | DATE_SUB + | DATETIME + | DAY + | DEALLOCATE + | DECRYPTION + | DEFAULT_AUTH + | DEFINER + | DELAY + | DELAY_KEY_WRITE + | DENSE_RANK + | DEPTH + | DES_KEY_FILE + | DESCRIPTION + | DESTINATION + | DIAGNOSTICS + | DIRECTORY + | DISABLE + | DISCARD + | DISK + | DISKGROUP + | DISCONNECT + | DO + | DUMP + | DUMPFILE + | DUPLICATE + | DUPLICATE_SCOPE + | DYNAMIC + | DEFAULT_TABLEGROUP + | EFFECTIVE + | EMPTY + | EMPTY_FIELD_AS_NULL + | ENABLE + | ENABLE_ARBITRATION_SERVICE + | ENABLE_EXTENDED_ROWID + | ENCODING + | ENCRYPTED + | ENCRYPTION + | END + | ENDS + | ENFORCED + | ENGINE_ + | ENGINES + | ENUM + | ENTITY + | ERROR_CODE + | ERROR_P + | ERRORS + | ESCAPE + | ESTIMATE + | EVENT + | EVENTS + | EVERY + | EXCEPT + | EXCHANGE + | EXECUTE + | EXPANSION + | EXPIRE + | EXPIRED + | EXPIRE_INFO + | EXPORT + | EXTENDED + | EXTENDED_NOADDR + | EXTENT_SIZE + | EXTERNAL + | FAILOVER + | EXTRACT + | FAST + | FAULTS + | FLASHBACK + | FIELDS + | FIELD_DELIMITER + | FIELD_OPTIONALLY_ENCLOSED_BY + | FILEX + | FILE_ID + | FINAL_COUNT + | FIRST + | FIRST_VALUE + | FIXED + | FLUSH + | FOLLOWER + | FOLLOWING + | FORMAT + | FROZEN + | FOUND + | FRAGMENTATION + | FREEZE + | FREQUENCY + | FUNCTION + | FULL + | GENERAL + | GEOMETRY + | GEOMCOLLECTION + | GEOMETRYCOLLECTION + | GET_FORMAT + | GLOBAL + | GLOBAL_NAME + | GRANTS + | GROUPING + | GROUP_CONCAT + | GTS + | HANDLER + | HASH + | HELP + | HISTOGRAM + | HOST + | HOSTS + | HOUR + | HYBRID_HIST + | ID + | IDC + | IDENTIFIED + | IGNORE_SERVER_IDS + | ILOG + | IMPORT + | INDEXES + | INDEX_TABLE_ID + | INCR + | INFO + | INITIAL_SIZE + | INNODB + | INSERT_METHOD + | INSTALL + | INSTANCE + | INTERSECT + | INVOKER + | INCREMENT + | INCREMENTAL + | IO + | IOPS_WEIGHT + | IO_THREAD + | IPC + | ISNULL + | ISOLATION + | ISOLATE + | ISSUER + | JOB + | JSON + | JSON_VALUE + | JSON_ARRAYAGG + | JSON_OBJECTAGG + | KEY_BLOCK_SIZE + | KEY_VERSION + | LAG + | LANGUAGE + | LAST + | LAST_VALUE + | LEAD + | LEADER + | LEAK + | LEAK_MOD + | LEAK_RATE + | LEAVES + | LESS + | LEVEL + | LINE_DELIMITER + | LINESTRING + | LIST_ + | LISTAGG + | LN + | LOCAL + | LOCALITY + | LOCKED + | LOCKS + | LOG + | LOGFILE + | LOGONLY_REPLICA_NUM + | LOGS + | LOG_RESTORE_SOURCE + | MAJOR + | MANUAL + | MASTER + | MASTER_AUTO_POSITION + | MASTER_CONNECT_RETRY + | MASTER_DELAY + | MASTER_HEARTBEAT_PERIOD + | MASTER_HOST + | MASTER_LOG_FILE + | MASTER_LOG_POS + | MASTER_PASSWORD + | MASTER_PORT + | MASTER_RETRY_COUNT + | MASTER_SERVER_ID + | MASTER_SSL + | MASTER_SSL_CA + | MASTER_SSL_CAPATH + | MASTER_SSL_CERT + | MASTER_SSL_CIPHER + | MASTER_SSL_CRL + | MASTER_SSL_CRLPATH + | MASTER_SSL_KEY + | MASTER_USER + | MAX + | MAX_CONNECTIONS_PER_HOUR + | MAX_CPU + | LOG_DISK_SIZE + | MAX_IOPS + | MEMORY_SIZE + | MAX_QUERIES_PER_HOUR + | MAX_ROWS + | MAX_SIZE + | MAX_UPDATES_PER_HOUR + | MAX_USER_CONNECTIONS + | MEDIUM + | MEMBER + | MEMORY + | MEMTABLE + | MERGE + | MESSAGE_TEXT + | MEMSTORE_PERCENT + | META + | MICROSECOND + | MIGRATE + | MIGRATION + | MIN + | MINVALUE + | MIN_CPU + | MIN_IOPS + | MINOR + | MIN_ROWS + | MINUTE + | MINUS + | MODE + | MODIFY + | MONTH + | MOVE + | MULTILINESTRING + | MULTIPOINT + | MULTIPOLYGON + | MUTEX + | MYSQL_ERRNO + | MAX_USED_PART_ID + | NAME + | NAMES + | NATIONAL + | NCHAR + | NDB + | NDBCLUSTER + | NEW + | NEXT + | NO + | NOARCHIVELOG + | NOAUDIT + | NOCACHE + | NOCYCLE + | NODEGROUP + | NOMINVALUE + | NOMAXVALUE + | NONE + | NOORDER + | NOPARALLEL + | NORMAL + | NOW + | NOWAIT + | NO_WAIT + | NTILE + | NTH_VALUE + | NUMBER + | NULL_IF_EXETERNAL + | NULLS + | NVARCHAR + | OCCUR + | OF + | OFF + | OFFSET + | OLD + | OLD_PASSWORD + | OLD_KEY + | OJ + | OVER + | OBCONFIG_URL + | ONE + | ONE_SHOT + | ONLY + | OPEN + | OPTIONS + | ORIG_DEFAULT + | REMOTE_OSS + | OUTLINE + | OWNER + | PACK_KEYS + | PAGE + | PARALLEL + | PARAMETERS + | PARSER + | PARTIAL + | PARTITION_ID + | LS + | PARTITIONING + | PARTITIONS + | PATTERN + | PERCENT_RANK + | PAUSE + | PERCENTAGE + | PHASE + | PHYSICAL + | PL + | PLANREGRESS + | PLUGIN + | PLUGIN_DIR + | PLUGINS + | PLUS + | POINT + | POLICY + | POLYGON + | POOL + | PORT + | POSITION + | PRECEDING + | PREPARE + | PRESERVE + | PRETTY + | PRETTY_COLOR + | PREV + | PRIMARY_ZONE + | PRIVILEGES + | PROCESS + | PROCESSLIST + | PROFILE + | PROFILES + | PROGRESSIVE_MERGE_NUM + | PROXY + | PS + | PUBLIC + | PCTFREE + | P_ENTITY + | P_CHUNK + | QUARTER + | QUERY + | QUERY_RESPONSE_TIME + | QUEUE_TIME + | QUICK + | RANK + | READ_ONLY + | REBUILD + | RECOVER + | RECOVERY + | RECOVERY_WINDOW + | RECURSIVE + | RECYCLE + | RECYCLEBIN + | ROTATE + | ROW_NUMBER + | REDO_BUFFER_SIZE + | REDOFILE + | REDUNDANCY + | REDUNDANT + | REFRESH + | REGION + | REJECT + | RELAY + | RELAYLOG + | RELAY_LOG_FILE + | RELAY_LOG_POS + | RELAY_THREAD + | RELOAD + | REMOVE + | REORGANIZE + | REPAIR + | REPEATABLE + | REPLICA + | REPLICA_NUM + | REPLICA_TYPE + | REPLICATION + | REPORT + | RESET + | RESOURCE + | RESOURCE_POOL_LIST + | RESPECT + | RESTART + | RESTORE + | RESUME + | RETURNED_SQLSTATE + | RETURNING + | RETURNS + | REVERSE + | ROLLBACK + | ROLLING + | ROLLUP + | ROOT + | ROOTSERVICE + | ROOTSERVICE_LIST + | ROOTTABLE + | ROUTINE + | ROW + | ROW_COUNT + | ROW_FORMAT + | ROWS + | RTREE + | RUN + | SAMPLE + | SAVEPOINT + | SCHEDULE + | SCHEMA_NAME + | SCN + | SCOPE + | SECOND + | SECURITY + | SEED + | SEQUENCE + | SEQUENCES + | SERIAL + | SERIALIZABLE + | SERVER + | SERVER_IP + | SERVER_PORT + | SERVER_TYPE + | SERVICE + | SESSION + | SESSION_USER + | SET_MASTER_CLUSTER + | SET_SLAVE_CLUSTER + | SET_TP + | SHARDING + | SHARE + | SHUTDOWN + | SIGNED + | SIZE + | SIMPLE + | SKIP_BLANK_LINES + | SKIP_HEADER + | SLAVE + | SLOW + | SNAPSHOT + | SOCKET + | SOME + | SONAME + | SOUNDS + | SOURCE + | SPFILE + | SPLIT + | SQL_AFTER_GTIDS + | SQL_AFTER_MTS_GAPS + | SQL_BEFORE_GTIDS + | SQL_BUFFER_RESULT + | SQL_CACHE + | SQL_ID + | SQL_NO_CACHE + | SQL_THREAD + | SQL_TSI_DAY + | SQL_TSI_HOUR + | SQL_TSI_MINUTE + | SQL_TSI_MONTH + | SQL_TSI_QUARTER + | SQL_TSI_SECOND + | SQL_TSI_WEEK + | SQL_TSI_YEAR + | SRID + | STACKED + | STANDBY + | START + | STARTS + | STAT + | STATISTICS + | STATS_AUTO_RECALC + | STATS_PERSISTENT + | STATS_SAMPLE_PAGES + | STATUS + | STATEMENTS + | STD + | STDDEV + | STDDEV_POP + | STDDEV_SAMP + | STOP + | STORAGE + | STORAGE_FORMAT_VERSION + | STORING + | STRONG + | STRING + | SUBCLASS_ORIGIN + | SUBDATE + | SUBJECT + | SUBPARTITION + | SUBPARTITIONS + | SUBSTR + | SUBSTRING + | SUCCESSFUL + | SUM + | SUPER + | SUSPEND + | SWAPS + | SWITCH + | SWITCHES + | SWITCHOVER + | SYSTEM + | SYSTEM_USER + | SYSDATE + | TABLE_CHECKSUM + | TABLE_MODE + | TABLEGROUPS + | TABLE_ID + | TABLE_NAME + | TABLES + | TABLESPACE + | TABLET + | TABLET_ID + | TABLET_SIZE + | TABLET_MAX_SIZE + | TASK + | TEMPLATE + | TEMPORARY + | TEMPTABLE + | TENANT + | TENANT_ID + | SLOT_IDX + | TEXT + | THAN + | TIME + | TIMESTAMP + | TIMESTAMPADD + | TIMESTAMPDIFF + | TIME_ZONE_INFO + | TP_NAME + | TP_NO + | TRACE + | TRANSACTION + | TRADITIONAL + | TRIGGERS + | TRIM + | TRIM_SPACE + | TRUNCATE + | TYPE + | TYPES + | TABLEGROUP_ID + | TOP_K_FRE_HIST + | UNCOMMITTED + | UNDEFINED + | UNDO_BUFFER_SIZE + | UNDOFILE + | UNICODE + | UNKNOWN + | UNINSTALL + | UNIT + | UNIT_GROUP + | UNIT_NUM + | UNLOCKED + | UNTIL + | UNUSUAL + | UPGRADE + | USE_BLOOM_FILTER + | USE_FRM + | USER + | USER_RESOURCES + | UNBOUNDED + | UNLIMITED + | VALID + | VALIDATE + | VALUE + | VARIANCE + | VARIABLES + | VAR_POP + | VAR_SAMP + | VERBOSE + | VIRTUAL_COLUMN_ID + | MATERIALIZED + | VIEW + | VERIFY + | WAIT + | WARNINGS + | WASH + | WEAK + | WEEK + | WEIGHT_STRING + | WHENEVER + | WINDOW + | WORK + | WRAPPER + | X509 + | XA + | XML + | YEAR + | ZONE + | ZONE_LIST + | ZONE_TYPE + | LOCATION + | PLAN + | VISIBLE + | INVISIBLE + | ACTIVATE + | SYNCHRONIZATION + | THROTTLE + | PRIORITY + | RT + | NETWORK + | LOGICAL_READS + | REDO_TRANSPORT_OPTIONS + | MAXIMIZE + | AVAILABILITY + | PERFORMANCE + | PROTECTION + | OBSOLETE + | HIDDEN_ + | INDEXED + | SKEWONLY + | BACKUPPIECE + | PREVIEW + | BACKUP_BACKUP_DEST + | BACKUPROUND + | UP + | TIMES + | BACKED + | NAMESPACE + | LIB + | LINK + | MY_NAME + | CONNECT + | STATEMENT_ID + ; + +unreserved_keyword_special + : PASSWORD + ; + +unreserved_keyword_extra + : ACCESS + ; + +mysql_reserved_keyword + : ACCESSIBLE + | ADD + | ALTER + | ANALYZE + | AND + | AS + | ASC + | ASENSITIVE + | BEFORE + | BETWEEN + | BIGINT + | BINARY + | BLOB + | BY + | CALL + | CASCADE + | CASE + | CHANGE + | CHAR + | CHARACTER + | CHECK + | COLLATE + | COLUMN + | CONDITION + | CONSTRAINT + | CONTINUE + | CONVERT + | CREATE + | CROSS + | CURRENT_DATE + | CURRENT_TIME + | CURRENT_TIMESTAMP + | CURRENT_USER + | CURSOR + | DATABASE + | DATABASES + | DAY_HOUR + | DAY_MICROSECOND + | DAY_MINUTE + | DAY_SECOND + | DECLARE + | DECIMAL + | DEFAULT + | DELAYED + | DELETE + | DESC + | DESCRIBE + | DETERMINISTIC + | DISTINCTROW + | DIV + | DOUBLE + | DROP + | DUAL + | EACH + | ELSE + | ELSEIF + | ENCLOSED + | ESCAPED + | EXISTS + | EXIT + | EXPLAIN + | FETCH + | FLOAT + | FLOAT4 + | FLOAT8 + | FOR + | FORCE + | FOREIGN + | FULLTEXT + | GENERATED + | GET + | GRANT + | GROUP + | HAVING + | HIGH_PRIORITY + | HOUR_MICROSECOND + | HOUR_MINUTE + | HOUR_SECOND + | IF + | IGNORE + | IN + | INDEX + | INFILE + | INNER + | INOUT + | INSENSITIVE + | INSERT + | INT + | INT1 + | INT2 + | INT3 + | INT4 + | INT8 + | INTEGER + | INTERVAL + | INTO + | IO_AFTER_GTIDS + | IO_BEFORE_GTIDS + | IS + | ITERATE + | JOIN + | KEY + | KEYS + | KILL + | LEAVE + | LEFT + | LIKE + | LIMIT + | LINEAR + | LINES + | LOAD + | LOCALTIME + | LOCALTIMESTAMP + | LONG + | LONGBLOB + | LONGTEXT + | LOOP + | LOW_PRIORITY + | MASTER_BIND + | MASTER_SSL_VERIFY_SERVER_CERT + | MATCH + | MAXVALUE + | MEDIUMBLOB + | MEDIUMINT + | MEDIUMTEXT + | MIDDLEINT + | MINUTE_MICROSECOND + | MINUTE_SECOND + | MOD + | MODIFIES + | NATURAL + | NOT + | NO_WRITE_TO_BINLOG + | NUMERIC + | ON + | OPTIMIZE + | OPTION + | OPTIONALLY + | OR + | ORDER + | OUT + | OUTER + | OUTFILE + | PARTITION + | PRECISION + | PRIMARY + | PROCEDURE + | PURGE + | RANGE + | READ + | READS + | READ_WRITE + | REAL + | REFERENCES + | REGEXP + | RELEASE + | RENAME + | REPEAT + | REPLACE + | REQUIRE + | RESIGNAL + | RESTRICT + | RETURN + | REVOKE + | RIGHT + | RLIKE + | SCHEMA + | SCHEMAS + | SECOND_MICROSECOND + | SENSITIVE + | SEPARATOR + | SET + | SHOW + | SIGNAL + | SMALLINT + | SPATIAL + | SPECIFIC + | SQL + | SQLEXCEPTION + | SQLSTATE + | SQLWARNING + | SQL_BIG_RESULT + | SQL_SMALL_RESULT + | SSL + | STARTING + | STORED + | STRAIGHT_JOIN + | TABLE + | TERMINATED + | THEN + | TINYBLOB + | TINYINT + | TINYTEXT + | TO + | TRIGGER + | UNDO + | UNION + | UNLOCK + | UNSIGNED + | UPDATE + | USAGE + | USE + | USING + | UTC_DATE + | UTC_TIME + | UTC_TIMESTAMP + | VALUES + | VARBINARY + | VARCHAR + | VARCHARACTER + | VARYING + | VIRTUAL + | WHERE + | WHILE + | WITH + | WRITE + | XOR + | YEAR_MONTH + | ZEROFILL + ; + +empty + : + ; + +forward_expr + : expr EOF + ; + +forward_sql_stmt + : stmt EOF + ; + + diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/antlr4/com/aliyun/fastmodel/transform/oceanbase/oracle/parser/OBLexer.g4 b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/antlr4/com/aliyun/fastmodel/transform/oceanbase/oracle/parser/OBLexer.g4 new file mode 100644 index 0000000..4e1eade --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/antlr4/com/aliyun/fastmodel/transform/oceanbase/oracle/parser/OBLexer.g4 @@ -0,0 +1,4972 @@ +/* + * Copyright (c) 2023 OceanBase. + * + * Licensed 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. + */ + +lexer grammar OBLexer; +@members { +public boolean inRangeOperator = false; +} + +M_SIZE + : M + ; + +E_SIZE + : E + ; + +T_SIZE + : T + ; + +K_SIZE + : K + ; + +G_SIZE + : G + ; + +P_SIZE + : P + ; + +HIDE + : H I D E + ; + +DEFAULTS + : D E F A U L T S + ; + +ACCESS + : ( A C C E S S ) + ; + +ADD + : ( A D D ) + ; + +NAMESPACE + : N A M E S P A C E + ; + +ALL + : ( A L L ) + ; + +ALTER + : ( A L T E R ) + ; + +AND + : ( A N D ) + ; + +ANY + : ( A N Y ) + ; + +AS + : ( A S ) + ; + +ASC + : ( A S C ) + ; + +XMLATTRIBUTES + : X M L A T T R I B U T E S + ; + +AUDIT + : ( A U D I T ) + ; + +JSON_OBJECT_VALUE + : '\'' ([A-Za-z0-9$_ ]* | [A-Za-z][A-Za-z0-9$_#]*) '\'' ' '* ':' ([A-Za-z$_]+ | [A-Za-z][A-Za-z0-9$_#]* | [0-9]+) + ; + +VALUE + : V A L U E + ; + +BETWEEN + : ( B E T W E E N ) + ; + +BLOB + : ( B L O B ) + ; + +BY + : ( B Y ) + ; + +BINARY_DOUBLE + : ( B I N A R Y '_' D O U B L E ) + ; + +BINARY_FLOAT + : ( B I N A R Y '_' F L O A T ) + ; + +CHAR + : ( C H A R ) + ; + +CHECK + : ( C H E C K ) + ; + +CIPHER + : ( C I P H E R ) + ; + +CLOB + : ( C L O B ) + ; + +CLUSTER + : ( C L U S T E R ) + ; + +COLUMN + : ( C O L U M N ) + ; + +COMMENT + : ( C O M M E N T ) + ; + +COMPRESS + : ( C O M P R E S S ) + ; + +CONNECT + : ( C O N N E C T ) + ; + +CREATE + : ( C R E A T E ) + ; + +CURRENT + : ( C U R R E N T ) + ; + +DATE + : ( D A T E ) + ; + +DECIMAL + : ( D E C I M A L ) + ; + +DEFAULT + : ( D E F A U L T ) + ; + +DELETE + : ( D E L E T E ) + ; + +DESC + : ( D E S C ) + ; + +DISTINCT + : ( D I S T I N C T ) + ; + +DOT + : D O T + ; + +DROP + : ( D R O P ) + ; + +MULTISET + : M U L T I S E T + ; + +JSON_ARRAYAGG + : J S O N '_' A R R A Y A G G + ; + +ARRAY + : A R R A Y + ; + +JSON_ARRAY + : J S O N '_' A R R A Y + ; + +JSON_EMPTY + : J S O N '_' E M P T Y + ; + +PASSING + : P A S S I N G + ; + +ELSE + : ( E L S E ) + ; + +EXCLUSIVE + : ( E X C L U S I V E ) + ; + +EXISTS + : ( E X I S T S ) + ; + +EXCLUDE + : ( E X C L U D E ) + ; + +FILE_KEY + : ( F I L E ) + ; + +FLOAT + : ( F L O A T ) + ; + +FOR + : ( F O R ) + ; + +FROM + : ( F R O M ) + ; + +GRANT + : ( G R A N T ) + ; + +GROUP + : ( G R O U P ) + ; + +HAVING + : ( H A V I N G ) + ; + +HOST + : ( H O S T ) + ; + +ABSENT + : A B S E N T + ; + +IDENTIFIED + : ( I D E N T I F I E D ) + ; + +IMMEDIATE + : ( I M M E D I A T E ) + ; + +IN + : ( I N ) + ; + +INCREMENT + : ( I N C R E M E N T ) + ; + +INCLUDE + : ( I N C L U D E ) + ; + +INDEX + : ( I N D E X ) + ; + +INITIAL_ + : ( I N I T I A L ) + ; + +INSERT + : ( I N S E R T ) + ; + +FIELD_DELIMITER + : F I E L D '_' D E L I M I T E R + ; + +INTEGER + : ( I N T E G E R ) + ; + +INTERSECT + : ( I N T E R S E C T ) + ; + +INTO + : ( I N T O ) + ; + +ORDINALITY + : O R D I N A L I T Y + ; + +IS + : ( I S ) + ; + +ISSUER + : ( I S S U E R ) + ; + +LEVEL + : ( L E V E L ) + ; + +LIKE + : ( L I K E ) + ; + +LOCK + : ( L O C K ) + ; + +LONG + : ( L O N G ) + ; + +MAXEXTENTS + : ( M A X E X T E N T S ) + ; + +MINUS + : ( M I N U S ) + ; + +MODE + : ( M O D E ) + ; + +MODIFY + : ( M O D I F Y ) + ; + +NOAUDIT + : ( N O A U D I T ) + ; + +NOCOMPRESS + : ( N O C O M P R E S S ) + ; + +NOT + : ( N O T ) + ; + +NOTFOUND + : ( N O T F O U N D ) + ; + +NOWAIT + : ( N O W A I T ) + ; + +NULLX + : ( N U L L ) + ; + +MISSING + : M I S S I N G + ; + +NUMBER + : ( N U M B E R ) + ; + +OF + : ( O F ) + ; + +OFFLINE + : ( O F F L I N E ) + ; + +ON + : ( O N ) + ; + +ONLINE + : ( O N L I N E ) + ; + +OPTION + : ( O P T I O N ) + ; + +OR + : ( O R ) + ; + +ORDER + : ( O R D E R ) + ; + +PCTFREE + : ( P C T F R E E ) + ; + +PIVOT + : ( P I V O T ) + ; + +PRIOR + : ( P R I O R ) + ; + +PRIVILEGES + : ( P R I V I L E G E S ) + ; + +PUBLIC + : ( P U B L I C ) + ; + +RAW + : ( R A W ) + ; + +REAL + : ( R E A L ) + ; + +RENAME + : ( R E N A M E ) + ; + +RESOURCE + : ( R E S O U R C E ) + ; + +REVOKE + : ( R E V O K E ) + ; + +ROW + : ( R O W ) + ; + +ROWID + : ( R O W I D ) + ; + +ROWLABEL + : ( R O W L A B E L ) + ; + +ACTIVATE + : A C T I V A T E + ; + +ROWNUM + : ( R O W N U M ) + ; + +ROWS + : ( R O W S ) + ; + +START + : ( S T A R T ) + ; + +SELECT + : ( S E L E C T ) + ; + +SESSION + : ( S E S S I O N ) + ; + +SET + : ( S E T ) + ; + +SETS + : ( S E T S ) + ; + +SHARE + : ( S H A R E ) + ; + +SIZE + : ( S I Z E ) + ; + +SMALLINT + : ( S M A L L I N T ) + ; + +SUCCESSFUL + : ( S U C C E S S F U L ) + ; + +SYNONYM + : ( S Y N O N Y M ) + ; + +SYSDATE + : ( S Y S D A T E ) + ; + +SYSTIMESTAMP + : ( S Y S T I M E S T A M P ) + ; + +TABLE + : ( T A B L E ) + ; + +THEN + : ( T H E N ) + ; + +TO + : ( T O ) + ; + +TRIGGER + : ( T R I G G E R ) + ; + +UID + : ( U I D ) + ; + +UNION + : ( U N I O N ) + ; + +UNIQUE + : ( U N I Q U E ) + ; + +UNPIVOT + : ( U N P I V O T ) + ; + +UPDATE + : ( U P D A T E ) + ; + +USER + : ( U S E R ) + ; + +VALIDATE + : ( V A L I D A T E ) + ; + +VALUES + : ( V A L U E S ) + ; + +VARCHAR + : ( V A R C H A R ) + | ( V A R C H A R A C T E R ) + ; + +VARCHAR2 + : ( V A R C H A R '2') + ; + +VIEW + : ( V I E W ) + ; + +WHENEVER + : ( W H E N E V E R ) + ; + +WHERE + : ( W H E R E ) + ; + +REDUNDANCY + : R E D U N D A N C Y + ; + +WITH + : ( W I T H ) + ; + +STANDBY + : S T A N D B Y + ; + +WITHOUT + : W I T H O U T + ; + +WITHIN + : ( W I T H I N ) + ; + +ACCESSIBLE + : ( A C C E S S I B L E ) + ; + +AGAINST + : ( A G A I N S T ) + ; + +ALWAYS + : ( A L W A Y S ) + ; + +ANALYZE + : ( A N A L Y Z E ) + ; + +ASENSITIVE + : ( A S E N S I T I V E ) + ; + +BEFORE + : ( B E F O R E ) + ; + +BINARY + : ( B I N A R Y ) + ; + +BOTH + : ( B O T H ) + ; + +BULK + : ( B U L K ) + ; + +CALL + : ( C A L L ) + ; + +CASCADE + : ( C A S C A D E ) + ; + +CASE + : ( C A S E ) + ; + +CHANGE + : ( C H A N G E ) + ; + +CHARACTER + : ( C H A R A C T E R ) + ; + +CONSTRAINT + : ( C O N S T R A I N T ) + ; + +CONTINUE + : ( C O N T I N U E ) + ; + +COLLATE + : ( C O L L A T E ) + ; + +COLLECT + : ( C O L L E C T ) + ; + +CROSS + : ( C R O S S ) + ; + +CYCLE + : ( C Y C L E ) + ; + +CURRENT_DATE + : ( C U R R E N T '_' D A T E ) + ; + +CURRENT_TIMESTAMP + : ( C U R R E N T '_' T I M E S T A M P ) + ; + +CURRENT_USER + : ( C U R R E N T '_' U S E R ) + ; + +CURSOR + : ( C U R S O R ) + ; + +DAY_HOUR + : ( D A Y '_' H O U R ) + ; + +DAY_MICROSECOND + : ( D A Y '_' M I C R O S E C O N D ) + ; + +DAY_MINUTE + : ( D A Y '_' M I N U T E ) + ; + +DAY_SECOND + : ( D A Y '_' S E C O N D ) + ; + +DATABASE + : ( D A T A B A S E ) + ; + +DATABASES + : ( D A T A B A S E S ) + ; + +DEC + : ( D E C ) + ; + +DECLARE + : ( D E C L A R E ) + ; + +DELAYED + : ( D E L A Y E D ) + ; + +DISTINCTROW + : ( D I S T I N C T R O W ) + ; + +DOUBLE + : ( D O U B L E ) + ; + +DUAL + : ( D U A L ) + | ('SYS.DUAL') + ; + +EACH + : ( E A C H ) + ; + +ENCLOSED + : ( E N C L O S E D ) + ; + +ELSEIF + : ( E L S E I F ) + ; + +ESCAPED + : ( E S C A P E D ) + ; + +ALLOW + : A L L O W + ; + +EXIT + : ( E X I T ) + ; + +EXPLAIN + : ( E X P L A I N ) + ; + +FETCH + : ( F E T C H ) + ; + +EVALNAME + : E V A L N A M E + ; + +FLOAT4 + : ( F L O A T '4') + ; + +FLOAT8 + : ( F L O A T '8') + ; + +FORCE + : ( F O R C E ) + ; + +FULL + : ( F U L L ) + ; + +GET + : ( G E T ) + ; + +GENERATED + : ( G E N E R A T E D ) + ; + +HIGH_PRIORITY + : ( H I G H '_' P R I O R I T Y ) + ; + +HOUR_MICROSECOND + : ( H O U R '_' M I C R O S E C O N D ) + ; + +HOUR_MINUTE + : ( H O U R '_' M I N U T E ) + ; + +HOUR_SECOND + : ( H O U R '_' S E C O N D ) + ; + +ID + : ( I D ) + ; + +IF + : ( I F ) + ; + +IFIGNORE + : ( I F I G N O R E ) + ; + +INNER + : ( I N N E R ) + ; + +INFILE + : ( I N F I L E ) + ; + +INOUT + : ( I N O U T ) + ; + +INSENSITIVE + : ( I N S E N S I T I V E ) + ; + +INT1 + : ( I N T '1') + ; + +INT2 + : ( I N T '2') + ; + +LIB + : L I B + ; + +INT3 + : ( I N T '3') + ; + +INT4 + : ( I N T '4') + ; + +INT8 + : ( I N T '8') + ; + +INTERVAL + : ( I N T E R V A L ) + ; + +IO_AFTER_GTIDS + : ( I O '_' A F T E R '_' G T I D S ) + ; + +IO_BEFORE_GTIDS + : ( I O '_' B E F O R E '_' G T I D S ) + ; + +ITERATE + : ( I T E R A T E ) + ; + +JOIN + : ( J O I N ) + ; + +KEYS + : ( K E Y S ) + ; + +KILL + : ( K I L L ) + ; + +LANGUAGE + : ( L A N G U A G E ) + ; + +LEADING + : ( L E A D I N G ) + ; + +LEAVE + : ( L E A V E ) + ; + +LEFT + : ( L E F T ) + ; + +LINEAR + : ( L I N E A R ) + ; + +LINES + : ( L I N E S ) + ; + +BADFILE + : B A D F I L E + ; + +LOG_DISK_SIZE + : L O G '_' D I S K '_' S I Z E + ; + +LOAD + : ( L O A D ) + ; + +LOCALTIMESTAMP + : ( L O C A L T I M E S T A M P ) + ; + +LONGBLOB + : ( L O N G B L O B ) + ; + +SWITCHOVER + : S W I T C H O V E R + ; + +LONGTEXT + : ( L O N G T E X T ) + ; + +LOOP + : ( L O O P ) + ; + +LOW_PRIORITY + : ( L O W '_' P R I O R I T Y ) + ; + +MASTER_BIND + : ( M A S T E R '_' B I N D ) + ; + +MASTER_SSL_VERIFY_SERVER_CERT + : ( M A S T E R '_' S S L '_' V E R I F Y '_' S E R V E R '_' C E R T ) + ; + +MATCH + : ( M A T C H ) + ; + +MAXVALUE + : ( M A X V A L U E ) + ; + +MEDIUMBLOB + : ( M E D I U M B L O B ) + ; + +MEDIUMINT + : ( M E D I U M I N T ) + ; + +MERGE + : ( M E R G E ) + ; + +REJECT + : R E J E C T + ; + +MEDIUMTEXT + : ( M E D I U M T E X T ) + ; + +MIDDLEINT + : ( M I D D L E I N T ) + ; + +MINUTE_MICROSECOND + : ( M I N U T E '_' M I C R O S E C O N D ) + ; + +MINUTE_SECOND + : ( M I N U T E '_' S E C O N D ) + ; + +MOD + : ( M O D ) + ; + +MODIFIES + : ( M O D I F I E S ) + ; + +MOVEMENT + : ( M O V E M E N T ) + ; + +NATURAL + : ( N A T U R A L ) + ; + +NOCYCLE + : ( N O C Y C L E ) + ; + +NO_WRITE_TO_BINLOG + : ( N O '_' W R I T E '_' T O '_' B I N L O G ) + ; + +NUMERIC + : ( N U M E R I C ) + ; + +OPTIMIZE + : ( O P T I M I Z E ) + ; + +OPTIONALLY + : ( O P T I O N A L L Y ) + ; + +OUT + : ( O U T ) + ; + +OUTER + : ( O U T E R ) + ; + +IOPS_WEIGHT + : I O P S '_' W E I G H T + ; + +OUTFILE + : ( O U T F I L E ) + ; + +PARSER + : ( P A R S E R ) + ; + +PROCEDURE + : ( P R O C E D U R E ) + ; + +PURGE + : ( P U R G E ) + ; + +PARTITION + : ( P A R T I T I O N ) + ; + +RANGE + : ( R A N G E ) + ; + +PLUS + : P L U S + ; + +READ + : ( R E A D ) + ; + +READ_WRITE + : ( R E A D '_' W R I T E ) + ; + +READS + : ( R E A D S ) + ; + +RELEASE + : ( R E L E A S E ) + ; + +REFERENCES + : ( R E F E R E N C E S ) + ; + +REPLACE + : ( R E P L A C E ) + ; + +REPEAT + : ( R E P E A T ) + ; + +REQUIRE + : ( R E Q U I R E ) + ; + +RESIGNAL + : ( R E S I G N A L ) + ; + +RESTRICT + : ( R E S T R I C T ) + ; + +RETURN + : ( R E T U R N ) + ; + +RIGHT + : ( R I G H T ) + ; + +SCALARS + : S C A L A R S + ; + +SECOND_MICROSECOND + : ( S E C O N D '_' M I C R O S E C O N D ) + ; + +SCHEMA + : ( S C H E M A ) + ; + +SCHEMAS + : ( S C H E M A S ) + ; + +SEPARATOR + : ( S E P A R A T O R ) + ; + +SENSITIVE + : ( S E N S I T I V E ) + ; + +SIGNAL + : ( S I G N A L ) + ; + +SPATIAL + : ( S P A T I A L ) + ; + +SPECIFIC + : ( S P E C I F I C ) + ; + +SQL + : ( S Q L ) + ; + +SQLEXCEPTION + : ( S Q L E X C E P T I O N ) + ; + +SQLSTATE + : ( S Q L S T A T E ) + ; + +SQLWARNING + : ( S Q L W A R N I N G ) + ; + +SQL_BIG_RESULT + : ( S Q L '_' B I G '_' R E S U L T ) + ; + +SQL_CALC_FOUND_ROWS + : ( S Q L '_' C A L C '_' F O U N D '_' R O W S ) + ; + +SQL_SMALL_RESULT + : ( S Q L '_' S M A L L '_' R E S U L T ) + ; + +SEARCH + : ( S E A R C H ) + ; + +SSL + : ( S S L ) + ; + +STARTING + : ( S T A R T I N G ) + ; + +STATEMENTS + : ( S T A T E M E N T S ) + ; + +STORED + : ( S T O R E D ) + ; + +STRAIGHT_JOIN + : ( S T R A I G H T '_' J O I N ) + ; + +TERMINATED + : ( T E R M I N A T E D ) + ; + +TINYBLOB + : ( T I N Y B L O B ) + ; + +TINYTEXT + : ( T I N Y T E X T ) + ; + +TABLEGROUP + : ( T A B L E G R O U P ) + ; + +TRAILING + : ( T R A I L I N G ) + ; + +TIMEZONE_HOUR + : ( T I M E Z O N E '_' H O U R ) + ; + +TIMEZONE_MINUTE + : ( T I M E Z O N E '_' M I N U T E ) + ; + +TIMEZONE_REGION + : ( T I M E Z O N E '_' R E G I O N ) + ; + +TIMEZONE_ABBR + : ( T I M E Z O N E '_' A B B R ) + ; + +UNDO + : ( U N D O ) + ; + +UNLOCK + : ( U N L O C K ) + ; + +LINE_DELIMITER + : L I N E '_' D E L I M I T E R + ; + +USE + : ( U S E ) + ; + +USING + : ( U S I N G ) + ; + +UTC_DATE + : ( U T C '_' D A T E ) + ; + +UTC_TIMESTAMP + : ( U T C '_' T I M E S T A M P ) + ; + +VARYING + : ( V A R Y I N G ) + ; + +VIRTUAL + : ( V I R T U A L ) + ; + +WHEN + : ( W H E N ) + ; + +WHILE + : ( W H I L E ) + ; + +WRITE + : ( W R I T E ) + ; + +XOR + : ( X O R ) + ; + +X509 + : ( X '5''0''9') + ; + +YEAR_MONTH + : ( Y E A R '_' M O N T H ) + ; + +ZEROFILL + : ( Z E R O F I L L ) + ; + +GLOBAL_ALIAS + : ('@''@' G L O B A L ) + ; + +SESSION_ALIAS + : ('@''@' S E S S I O N ) + | ('@''@' L O C A L ) + ; + +STRONG + : ( S T R O N G ) + ; + +WEAK + : ( W E A K ) + ; + +FROZEN + : ( F R O Z E N ) + ; + +EXCEPT + : ( E X C E P T ) + ; + +ISNULL + : ( I S N U L L ) + ; + +RETURNING + : ( R E T U R N I N G ) + ; + +ISOPEN + : ( I S O P E N ) + ; + +ROWCOUNT + : ( R O W C O U N T ) + ; + +BULK_ROWCOUNT + : ( B U L K '_' R O W C O U N T ) + ; + +ERROR_INDEX + : ( E R R O R '_' I N D E X ) + ; + +BULK_EXCEPTIONS + : ( B U L K '_' E X C E P T I O N S ) + ; + +PARAM_ASSIGN_OPERATOR + : ('=>') + ; + +COLUMN_OUTER_JOIN_SYMBOL + : (('('|[\uff08])([ \t\n\r\f]+|('--'(~[\n\r])*))*'+'([ \t\n\r\f]+|('--'(~[\n\r])*))*(')'|[\uff09])) + ; + +DATA_TABLE_ID + : ( D A T A '_' T A B L E '_' I D ) + ; + +WARNINGS + : W A R N I N G S + ; + +LOWER_JOIN + : L O W E R '_' J O I N + ; + +GROUPS + : G R O U P S + ; + +CONNECT_BY_ISCYCLE + : C O N N E C T '_' B Y '_' I S C Y C L E + ; + +FORMAT + : F O R M A T + ; + +MINVALUE + : M I N V A L U E + ; + +EXTRA + : E X T R A + ; + +EMPTY_FIELD_AS_NULL + : E M P T Y '_' F I E L D '_' A S '_' N U L L + ; + +UNINSTALL + : U N I N S T A L L + ; + +UNDOFILE + : U N D O F I L E + ; + +MASTER_SSL_CA + : M A S T E R '_' S S L '_' C A + ; + +YEAR + : Y E A R + ; + +STOP + : S T O P + ; + +STORAGE_FORMAT_WORK_VERSION + : S T O R A G E '_' F O R M A T '_' W O R K '_' V E R S I O N + ; + +DISABLE_PARALLEL_DML + : D I S A B L E '_' P A R A L L E L '_' D M L + ; + +PACKAGE_KEY + : P A C K A G E '_' K E Y + ; + +PACKAGE + : P A C K A G E + ; + +AT + : A T + ; + +RELAY_LOG_POS + : R E L A Y '_' L O G '_' P O S + ; + +POOL + : P O O L + ; + +ZONE_TYPE + : Z O N E '_' T Y P E + ; + +LOCATION + : L O C A T I O N + ; + +WEIGHT_STRING + : W E I G H T '_' S T R I N G + ; + +MAXLOGMEMBERS + : M A X L O G M E M B E R S + ; + +CHANGED + : C H A N G E D + ; + +MASTER_SSL_CAPATH + : M A S T E R '_' S S L '_' C A P A T H + ; + +PRECISION + : P R E C I S I O N + ; + +ROLE + : R O L E + ; + +JSON_QUERY + : J S O N '_' Q U E R Y + ; + +REWRITE_MERGE_VERSION + : R E W R I T E '_' M E R G E '_' V E R S I O N + ; + +NTH_VALUE + : N T H '_' V A L U E + ; + +SERIAL + : S E R I A L + ; + +REDACTION + : R E D A C T I O N + ; + +QUEUE_TIME + : Q U E U E '_' T I M E + ; + +PROGRESSIVE_MERGE_NUM + : P R O G R E S S I V E '_' M E R G E '_' N U M + ; + +TABLET_MAX_SIZE + : T A B L E T '_' M A X '_' S I Z E + ; + +ILOGCACHE + : I L O G C A C H E + ; + +AUTHORS + : A U T H O R S + ; + +MIGRATE + : M I G R A T E + ; + +DIV + : D I V + ; + +CONSISTENT + : C O N S I S T E N T + ; + +SUSPEND + : S U S P E N D + ; + +SYSKM + : S Y S K M + ; + +REMOTE_OSS + : R E M O T E '_' O S S + ; + +SECURITY + : S E C U R I T Y + ; + +SET_SLAVE_CLUSTER + : S E T '_' S L A V E '_' C L U S T E R + ; + +FAST + : F A S T + ; + +KEYSTORE + : K E Y S T O R E + ; + +TRUNCATE + : T R U N C A T E + ; + +CONSTRAINT_SCHEMA + : C O N S T R A I N T '_' S C H E M A + ; + +MASTER_SSL_CERT + : M A S T E R '_' S S L '_' C E R T + ; + +TABLE_NAME + : T A B L E '_' N A M E + ; + +PRIORITY + : P R I O R I T Y + ; + +DO + : D O + ; + +MASTER_RETRY_COUNT + : M A S T E R '_' R E T R Y '_' C O U N T + ; + +EXCEPTIONS + : E X C E P T I O N S + ; + +REPLICA + : R E P L I C A + ; + +KILL_EXPR + : K I L L '_' E X P R + ; + +UROWID + : U R O W I D + ; + +ADMIN + : A D M I N + ; + +CONNECT_BY_ISLEAF + : C O N N E C T '_' B Y '_' I S L E A F + ; + +NCHAR_CS + : N C H A R '_' C S + ; + +OLD_KEY + : O L D '_' K E Y + ; + +DISABLE + : D I S A B L E + ; + +STRICT + : S T R I C T + ; + +PORT + : P O R T + ; + +MAXDATAFILES + : M A X D A T A F I L E S + ; + +EXEC + : E X E C + ; + +NOVALIDATE + : N O V A L I D A T E + ; + +REBUILD + : R E B U I L D + ; + +FOLLOWER + : F O L L O W E R + ; + +LIST + : L I S T + ; + +LOWER_OVER + : L O W E R '_' O V E R + ; + +ROOT + : R O O T + ; + +REDOFILE + : R E D O F I L E + ; + +MASTER_SERVER_ID + : M A S T E R '_' S E R V E R '_' I D + ; + +NCHAR + : N C H A R + ; + +KEY_BLOCK_SIZE + : K E Y '_' B L O C K '_' S I Z E + ; + +NOLOGGING + : N O L O G G I N G + ; + +SEQUENCE + : S E Q U E N C E + ; + +PRETTY + : P R E T T Y + ; + +PRETTY_COLOR + : P R E T T Y '_' C O L O R + ; + +COLUMNS + : C O L U M N S + ; + +MIGRATION + : M I G R A T I O N + ; + +SUBPARTITION + : S U B P A R T I T I O N + ; + +DML + : D M L + ; + +MYSQL_DRIVER + : M Y S Q L '_' D R I V E R + ; + +GO + : G O + ; + +ROW_NUMBER + : R O W '_' N U M B E R + ; + +COMPRESSION + : C O M P R E S S I O N + ; + +BIT + : B I T + ; + +MAX_DISK_SIZE + : M A X '_' D I S K '_' S I Z E + ; + +SAMPLE + : S A M P L E + ; + +PCTUSED + : P C T U S E D + ; + +UNLOCKED + : U N L O C K E D + ; + +CLASS_ORIGIN + : C L A S S '_' O R I G I N + ; + +ACTION + : A C T I O N + ; + +REDUNDANT + : R E D U N D A N T + ; + +MAXLOGFILES + : M A X L O G F I L E S + ; + +UPGRADE + : U P G R A D E + ; + +TEMPTABLE + : T E M P T A B L E + ; + +EXTERNALLY + : E X T E R N A L L Y + ; + +RECYCLEBIN + : R E C Y C L E B I N + ; + +PROFILES + : P R O F I L E S + ; + +TIMESTAMP_VALUE + : T I M E S T A M P '_' V A L U E + ; + +ERRORS + : E R R O R S + ; + +BINARY_DOUBLE_NAN + : B I N A R Y '_' D O U B L E '_' N A N + ; + +LEAVES + : L E A V E S + ; + +UNDEFINED + : U N D E F I N E D + ; + +EVERY + : E V E R Y + ; + +BYTE + : B Y T E + ; + +SHARDING + : S H A R D I N G + ; + +FLUSH + : F L U S H + ; + +MIN_ROWS + : M I N '_' R O W S + ; + +ERROR_P + : E R R O R '_' P + ; + +MAX_USER_CONNECTIONS + : M A X '_' U S E R '_' C O N N E C T I O N S + ; + +FIELDS + : F I E L D S + ; + +MAX_CPU + : M A X '_' C P U + ; + +LOCKED + : L O C K E D + ; + +DOP + : D O P + ; + +IO + : I O + ; + +BTREE + : B T R E E + ; + +APPROXNUM + : A P P R O X N U M + ; + +HASH + : H A S H + ; + +REGR_INTERCEPT + : R E G R '_' I N T E R C E P T + ; + +OPTIMAL + : O P T I M A L + ; + +CONNECT_BY_ROOT + : C O N N E C T '_' B Y '_' R O O T + ; + +OLTP + : O L T P + ; + +SYSOPER + : S Y S O P E R + ; + +GOTO + : G O T O + ; + +COLLATION + : C O L L A T I O N + ; + +MASTER + : M A S T E R + ; + +ENCRYPTION + : E N C R Y P T I O N + ; + +INSERTING + : I N S E R T I N G + ; + +MAX + : M A X + ; + +TRANSACTION + : T R A N S A C T I O N + ; + +SQL_TSI_MONTH + : S Q L '_' T S I '_' M O N T H + ; + +BECOME + : B E C O M E + ; + +IGNORE + : I G N O R E + ; + +MAX_QUERIES_PER_HOUR + : M A X '_' Q U E R I E S '_' P E R '_' H O U R + ; + +OFF + : O F F + ; + +MIN_IOPS + : M I N '_' I O P S + ; + +NVARCHAR + : N V A R C H A R + ; + +PAUSE + : P A U S E + ; + +QUICK + : Q U I C K + ; + +DUPLICATE + : D U P L I C A T E + ; + +XMLTYPE + : X M L T Y P E + ; + +USAGE + : U S A G E + ; + +FIELD_OPTIONALLY_ENCLOSED_BY + : F I E L D '_' O P T I O N A L L Y '_' E N C L O S E D '_' B Y + ; + +WAIT + : W A I T + ; + +DES_KEY_FILE + : D E S '_' K E Y '_' F I L E + ; + +ENGINES + : E N G I N E S + ; + +RETURNS + : R E T U R N S + ; + +MASTER_USER + : M A S T E R '_' U S E R + ; + +SOCKET + : S O C K E T + ; + +SIBLINGS + : S I B L I N G S + ; + +MASTER_DELAY + : M A S T E R '_' D E L A Y + ; + +FILE_ID + : F I L E '_' I D + ; + +FIRST + : F I R S T + ; + +TABLET + : T A B L E T + ; + +CLIENT + : C L I E N T + ; + +PRIVATE + : P R I V A T E + ; + +TABLES + : T A B L E S + ; + +ENGINE_ + : E N G I N E + ; + +TRADITIONAL + : T R A D I T I O N A L + ; + +BOOTSTRAP + : B O O T S T R A P + ; + +STDDEV + : S T D D E V + ; + +DATAFILE + : D A T A F I L E + ; + +INVOKER + : I N V O K E R + ; + +LAYER + : L A Y E R + ; + +DEPTH + : D E P T H + ; + +THREAD + : T H R E A D + ; + +TRIGGERS + : T R I G G E R S + ; + +COLUMN_NAME + : C O L U M N '_' N A M E + ; + +ENABLE_PARALLEL_DML + : E N A B L E '_' P A R A L L E L '_' D M L + ; + +RESET + : R E S E T + ; + +EVENT + : E V E N T + ; + +COALESCE + : C O A L E S C E + ; + +RESPECT + : R E S P E C T + ; + +STATUS + : S T A T U S + ; + +UNBOUNDED + : U N B O U N D E D + ; + +REGR_SLOPE + : R E G R '_' S L O P E + ; + +WRAPPER + : W R A P P E R + ; + +TIMESTAMP + : T I M E S T A M P + ; + +EXTENT + : E X T E N T + ; + +PARTITIONS + : P A R T I T I O N S + ; + +SUBSTR + : S U B S T R + ; + +FILEX + : F I L E X + ; + +UNIT + : U N I T + ; + +LOWER_ON + : L O W E R '_' O N + ; + +SWITCH + : S W I T C H + ; + +LESS + : L E S S + ; + +BODY + : B O D Y + ; + +DIAGNOSTICS + : D I A G N O S T I C S + ; + +REDO_BUFFER_SIZE + : R E D O '_' B U F F E R '_' S I Z E + ; + +NO + : N O + ; + +MAJOR + : M A J O R + ; + +ACTIVE + : A C T I V E + ; + +TIES + : T I E S + ; + +ROUTINE + : R O U T I N E + ; + +ROLLBACK + : R O L L B A C K + ; + +FOLLOWING + : F O L L O W I N G + ; + +READ_ONLY + : R E A D '_' O N L Y + ; + +MEMBER + : M E M B E R + ; + +PARTITION_ID + : P A R T I T I O N '_' I D + ; + +SHARED + : S H A R E D + ; + +EXTERNAL + : E X T E R N A L + ; + +DUMP + : D U M P + ; + +APPROX_COUNT_DISTINCT_SYNOPSIS + : A P P R O X '_' C O U N T '_' D I S T I N C T '_' S Y N O P S I S + ; + +GROUPING + : G R O U P I N G + ; + +PRIMARY + : P R I M A R Y + ; + +ARCHIVELOG + : A R C H I V E L O G + ; + +MATCHED + : M A T C H E D + ; + +MAX_CONNECTIONS_PER_HOUR + : M A X '_' C O N N E C T I O N S '_' P E R '_' H O U R + ; + +FAILED_LOGIN_ATTEMPTS + : F A I L E D '_' L O G I N '_' A T T E M P T S + ; + +ENCODING + : E N C O D I N G + ; + +SECOND + : S E C O N D + ; + +UNKNOWN + : U N K N O W N + ; + +POINT + : P O I N T + ; + +MEMSTORE_PERCENT + : M E M S T O R E '_' P E R C E N T + ; + +POLYGON + : P O L Y G O N + ; + +ORA_ROWSCN + : O R A '_' R O W S C N + ; + +OLD + : O L D + ; + +TABLE_ID + : T A B L E '_' I D + ; + +CONTEXT + : C O N T E X T + ; + +FINAL_COUNT + : F I N A L '_' C O U N T + ; + +MASTER_CONNECT_RETRY + : M A S T E R '_' C O N N E C T '_' R E T R Y + ; + +POSITION + : P O S I T I O N + ; + +DISCARD + : D I S C A R D + ; + +PATTERN + : P A T T E R N + ; + +RECOVERY_WINDOW + : R E C O V E R Y '_' W I N D O W + ; + +RECOVER + : R E C O V E R + ; + +PREV + : P R E V + ; + +PROCESS + : P R O C E S S + ; + +ERROR + : E R R O R + ; + +DEALLOCATE + : D E A L L O C A T E + ; + +OLD_PASSWORD + : O L D '_' P A S S W O R D + ; + +CONTROLFILE + : C O N T R O L F I L E + ; + +LISTAGG + : L I S T A G G + ; + +SLOW + : S L O W + ; + +SUM + : S U M + ; + +OPTIONS + : O P T I O N S + ; + +MIN + : M I N + ; + +ROLES + : R O L E S + ; + +UPDATING + : U P D A T I N G + ; + +KEY + : K E Y + ; + +RT + : R T + ; + +RELOAD + : R E L O A D + ; + +ONE + : O N E + ; + +DELAY_KEY_WRITE + : D E L A Y '_' K E Y '_' W R I T E + ; + +ORIG_DEFAULT + : O R I G '_' D E F A U L T + ; + +INDEXED + : I N D E X E D + ; + +RLIKE + : R L I K E + ; + +SQL_TSI_HOUR + : S Q L '_' T S I '_' H O U R + ; + +TIMESTAMPDIFF + : T I M E S T A M P D I F F + ; + +RESTORE + : R E S T O R E + ; + +OFFSET + : O F F S E T + ; + +TEMPORARY + : T E M P O R A R Y + ; + +VARIANCE + : V A R I A N C E + ; + +SNAPSHOT + : S N A P S H O T + ; + +JSON_EXISTS + : J S O N '_' E X I S T S + ; + +STATISTICS + : S T A T I S T I C S + ; + +COBOL + : C O B O L + ; + +SERVER_TYPE + : S E R V E R '_' T Y P E + ; + +COMMITTED + : C O M M I T T E D + ; + +PERCENT + : P E R C E N T + ; + +RATIO_TO_REPORT + : R A T I O '_' T O '_' R E P O R T + ; + +SUBJECT + : S U B J E C T + ; + +DBTIMEZONE + : D B T I M E Z O N E + ; + +INDEXES + : I N D E X E S + ; + +FREEZE + : F R E E Z E + ; + +SCOPE + : S C O P E + ; + +OUTLINE_DEFAULT_TOKEN + : O U T L I N E '_' D E F A U L T '_' T O K E N + ; + +IDC + : I D C + ; + +SYS_CONNECT_BY_PATH + : S Y S '_' C O N N E C T '_' B Y '_' P A T H + ; + +ONE_SHOT + : O N E '_' S H O T + ; + +ACCOUNT + : A C C O U N T + ; + +LOCALITY + : L O C A L I T Y + ; + +ARCHIVE + : A R C H I V E + ; + +CONSTRAINTS + : C O N S T R A I N T S + ; + +REVERSE + : R E V E R S E + ; + +CLUSTER_ID + : C L U S T E R '_' I D + ; + +NOARCHIVELOG + : N O A R C H I V E L O G + ; + +WM_CONCAT + : W M '_' C O N C A T + ; + +MAX_SIZE + : M A X '_' S I Z E + ; + +COVAR_SAMP + : C O V A R '_' S A M P + ; + +PAGE + : P A G E + ; + +NAME + : N A M E + ; + +ADMINISTER + : A D M I N I S T E R + ; + +ROW_COUNT + : R O W '_' C O U N T + ; + +LAST + : L A S T + ; + +LOGONLY_REPLICA_NUM + : L O G O N L Y '_' R E P L I C A '_' N U M + ; + +DELAY + : D E L A Y + ; + +SUBDATE + : S U B D A T E + ; + +INCREMENTAL + : I N C R E M E N T A L + ; + +QUOTA + : Q U O T A + ; + +VERIFY + : V E R I F Y + ; + +CONTAINS + : C O N T A I N S + ; + +GENERAL + : G E N E R A L + ; + +VISIBLE + : V I S I B L E + ; + +REGR_COUNT + : R E G R '_' C O U N T + ; + +SIGNED + : S I G N E D + ; + +SERVER + : S E R V E R + ; + +NEXT + : N E X T + ; + +GLOBAL + : G L O B A L + ; + +ENDS + : E N D S + ; + +ROOTSERVICE_LIST + : R O O T S E R V I C E '_' L I S T + ; + +SHOW + : S H O W + ; + +SHUTDOWN + : S H U T D O W N + ; + +VERBOSE + : V E R B O S E + ; + +JSON_EQUAL + : J S O N '_' E Q U A L + ; + +CLUSTER_NAME + : C L U S T E R '_' N A M E + ; + +MASTER_PORT + : M A S T E R '_' P O R T + ; + +MYSQL_ERRNO + : M Y S Q L '_' E R R N O + ; + +XA + : X A + ; + +TIME + : T I M E + ; + +REUSE + : R E U S E + ; + +NOMINVALUE + : N O M I N V A L U E + ; + +DATETIME + : D A T E T I M E + ; + +BOOL + : B O O L + ; + +DIRECTORY + : D I R E C T O R Y + ; + +SECTION + : S E C T I O N + ; + +PERCENTILE_CONT + : P E R C E N T I L E '_' C O N T + ; + +VALID + : V A L I D + ; + +MASTER_SSL_KEY + : M A S T E R '_' S S L '_' K E Y + ; + +MASTER_PASSWORD + : M A S T E R '_' P A S S W O R D + ; + +PLAN + : P L A N + ; + +MULTIPOLYGON + : M U L T I P O L Y G O N + ; + +STDDEV_SAMP + : S T D D E V '_' S A M P + ; + +USE_BLOOM_FILTER + : U S E '_' B L O O M '_' F I L T E R + ; + +LOCAL + : L O C A L + ; + +CONSTRAINT_CATALOG + : C O N S T R A I N T '_' C A T A L O G + ; + +DICTIONARY + : D I C T I O N A R Y + ; + +SYSDBA + : S Y S D B A + ; + +EXCHANGE + : E X C H A N G E + ; + +GRANTS + : G R A N T S + ; + +CAST + : C A S T + ; + +SERVER_PORT + : S E R V E R '_' P O R T + ; + +SQL_CACHE + : S Q L '_' C A C H E + ; + +MAX_USED_PART_ID + : M A X '_' U S E D '_' P A R T '_' I D + ; + +RELY + : R E L Y + ; + +INSTANCE + : I N S T A N C E + ; + +HYBRID_HIST + : H Y B R I D '_' H I S T + ; + +FUNCTION + : F U N C T I O N + ; + +NAN_VALUE + : N A N '_' V A L U E + ; + +INVISIBLE + : I N V I S I B L E + ; + +BINARY_DOUBLE_INFINITY + : B I N A R Y '_' D O U B L E '_' I N F I N I T Y + ; + +REGR_SXX + : R E G R '_' S X X + ; + +REGR_SXY + : R E G R '_' S X Y + ; + +DENSE_RANK + : D E N S E '_' R A N K + ; + +COUNT + : C O U N T + ; + +SQL_CALC_FOUND_ROW + : S Q L '_' C A L C '_' F O U N D '_' R O W + ; + +TREAT + : T R E A T + ; + +TYPENAME + : T Y P E N A M E + ; + +MY_NAME + : M Y '_' N A M E + ; + +NAMES + : N A M E S + ; + +LOWER_THAN_NEG + : L O W E R '_' T H A N '_' N E G + ; + +MAX_ROWS + : M A X '_' R O W S + ; + +ISOLATION + : I S O L A T I O N + ; + +REPLICATION + : R E P L I C A T I O N + ; + +REGR_SYY + : R E G R '_' S Y Y + ; + +INITIALIZED + : I N I T I A L I Z E D + ; + +REMOVE + : R E M O V E + ; + +STATS_AUTO_RECALC + : S T A T S '_' A U T O '_' R E C A L C + ; + +CONSISTENT_MODE + : C O N S I S T E N T '_' M O D E + ; + +SUBMULTISET + : S U B M U L T I S E T + ; + +SEGMENT + : S E G M E N T + ; + +UNCOMMITTED + : U N C O M M I T T E D + ; + +CURRENT_SCHEMA + : C U R R E N T '_' S C H E M A + ; + +OWN + : O W N + ; + +NO_WAIT + : N O '_' W A I T + ; + +BACKUP_COPIES + : B A C K U P '_' C O P I E S + ; + +UNIT_NUM + : U N I T '_' N U M + ; + +PERCENTAGE + : P E R C E N T A G E + ; + +MAX_IOPS + : M A X '_' I O P S + ; + +SPFILE + : S P F I L E + ; + +REPEATABLE + : R E P E A T A B L E + ; + +PCTINCREASE + : P C T I N C R E A S E + ; + +COMPLETION + : C O M P L E T I O N + ; + +ROOTTABLE + : R O O T T A B L E + ; + +ZONE + : Z O N E + ; + +REGR_AVGY + : R E G R '_' A V G Y + ; + +REGR_AVGX + : R E G R '_' A V G X + ; + +TEMPLATE + : T E M P L A T E + ; + +INCLUDING + : I N C L U D I N G + ; + +DATE_SUB + : D A T E '_' S U B + ; + +EXPIRE_INFO + : E X P I R E '_' I N F O + ; + +EXPIRE + : E X P I R E + ; + +KEEP + : K E E P + ; + +ENABLE + : E N A B L E + ; + +HOSTS + : H O S T S + ; + +SCHEMA_NAME + : S C H E M A '_' N A M E + ; + +SHRINK + : S H R I N K + ; + +EXPANSION + : E X P A N S I O N + ; + +REORGANIZE + : R E O R G A N I Z E + ; + +TRIM_SPACE + : T R I M '_' S P A C E + ; + +BLOCK_SIZE + : B L O C K '_' S I Z E + ; + +INNER_PARSE + : I N N E R '_' P A R S E + ; + +MINOR + : M I N O R + ; + +RESTRICTED + : R E S T R I C T E D + ; + +GLOBALLY + : G L O B A L L Y + ; + +RESUME + : R E S U M E + ; + +INT + : I N T + ; + +STATS_PERSISTENT + : S T A T S '_' P E R S I S T E N T + ; + +NODEGROUP + : N O D E G R O U P + ; + +PARTITIONING + : P A R T I T I O N I N G + ; + +MAXTRANS + : M A X T R A N S + ; + +SUPER + : S U P E R + ; + +JSON_OBJECT + : J S O N '_' O B J E C T + ; + +COMMIT + : C O M M I T + ; + +DETERMINISTIC + : D E T E R M I N I S T I C + ; + +SAVEPOINT + : S A V E P O I N T + ; + +UNTIL + : U N T I L + ; + +NVARCHAR2 + : N V A R C H A R '2' + ; + +MEMTABLE + : M E M T A B L E + ; + +CHARSET + : C H A R S E T + ; + +FREELIST + : F R E E L I S T + ; + +MOVE + : M O V E + ; + +XML + : X M L + ; + +PASSWORD_LIFE_TIME + : P A S S W O R D '_' L I F E '_' T I M E + ; + +IPC + : I P C + ; + +PATH + : P A T H + ; + +TRIM + : T R I M + ; + +RANK + : R A N K + ; + +VAR_POP + : V A R '_' P O P + ; + +DEFAULT_AUTH + : D E F A U L T '_' A U T H + ; + +EXTENT_SIZE + : E X T E N T '_' S I Z E + ; + +BINLOG + : B I N L O G + ; + +CLOG + : C L O G + ; + +GEOMETRYCOLLECTION + : G E O M E T R Y C O L L E C T I O N + ; + +STORAGE + : S T O R A G E + ; + +MEDIUM + : M E D I U M + ; + +XMLPARSE + : X M L P A R S E + ; + +WELLFORMED + : W E L L F O R M E D + ; + +DOCUMENT + : D O C U M E N T + ; + +XMLAGG + : X M L A G G + ; + +USE_FRM + : U S E '_' F R M + ; + +CLIENT_VERSION + : C L I E N T '_' V E R S I O N + ; + +MASTER_HEARTBEAT_PERIOD + : M A S T E R '_' H E A R T B E A T '_' P E R I O D + ; + +DELETING + : D E L E T I N G + ; + +SUBPARTITIONS + : S U B P A R T I T I O N S + ; + +CUBE + : C U B E + ; + +REGR_R2 + : R E G R '_' R '2' + ; + +BALANCE + : B A L A N C E + ; + +POLICY + : P O L I C Y + ; + +QUERY + : Q U E R Y + ; + +THROTTLE + : T H R O T T L E + ; + +SQL_TSI_QUARTER + : S Q L '_' T S I '_' Q U A R T E R + ; + +SPACE + : S P A C E + ; + +REPAIR + : R E P A I R + ; + +MASTER_SSL_CIPHER + : M A S T E R '_' S S L '_' C I P H E R + ; + +KEY_VERSION + : K E Y '_' V E R S I O N + ; + +CATALOG_NAME + : C A T A L O G '_' N A M E + ; + +NDBCLUSTER + : N D B C L U S T E R + ; + +CONNECTION + : C O N N E C T I O N + ; + +COMPACT + : C O M P A C T + ; + +INCR + : I N C R + ; + +CANCEL + : C A N C E L + ; + +SIMPLE + : S I M P L E + ; + +BEGIN + : B E G I N + ; + +VARIABLES + : V A R I A B L E S + ; + +FREELISTS + : F R E E L I S T S + ; + +SQL_TSI_WEEK + : S Q L '_' T S I '_' W E E K + ; + +SYSTEM + : S Y S T E M + ; + +SQLERROR + : S Q L E R R O R + ; + +ROOTSERVICE + : R O O T S E R V I C E + ; + +PLUGIN_DIR + : P L U G I N '_' D I R + ; + +ASCII + : A S C I I + ; + +INFO + : I N F O + ; + +SQL_THREAD + : S Q L '_' T H R E A D + ; + +SKIP_HEADER + : S K I P '_' H E A D E R + ; + +TYPES + : T Y P E S + ; + +LEADER + : L E A D E R + ; + +LOWER_KEY + : L O W E R '_' K E Y + ; + +FOUND + : F O U N D + ; + +EXTRACT + : E X T R A C T + ; + +PERCENTILE_DISC + : P E R C E N T I L E '_' D I S C + ; + +XMLCAST + : X M L C A S T + ; + +XMLSERIALIZE + : X M L S E R I A L I Z E + ; + +FIXED + : F I X E D + ; + +CACHE + : C A C H E + ; + +RETURNED_SQLSTATE + : R E T U R N E D '_' S Q L S T A T E + ; + +END + : E N D + ; + +PRESERVE + : P R E S E R V E + ; + +ASIS + : A S I S + ; + +SQL_BUFFER_RESULT + : S Q L '_' B U F F E R '_' R E S U L T + ; + +LOCK_ + : L O C K + ; + +JSON + : J S O N + ; + +SOME + : S O M E + ; + +INDEX_TABLE_ID + : ( I N D E X '_' T A B L E '_' I D ) + ; + +FREQUENCY + : F R E Q U E N C Y + ; + +PQ_MAP + : P Q '_' M A P + ; + +MANUAL + : M A N U A L + ; + +LOCKS + : L O C K S + ; + +SYSBACKUP + : S Y S B A C K U P + ; + +GEOMETRY + : G E O M E T R Y + ; + +NO_PARALLEL + : N O '_' P A R A L L E L + ; + +STORAGE_FORMAT_VERSION + : S T O R A G E '_' F O R M A T '_' V E R S I O N + ; + +VERSION + : V E R S I O N + ; + +INDENT + : I N D E N T + ; + +ISOLATION_LEVEL + : I S O L A T I O N '_' L E V E L + ; + +OVER + : O V E R + ; + +MAX_SESSION_NUM + : M A X '_' S E S S I O N '_' N U M + ; + +USER_RESOURCES + : U S E R '_' R E S O U R C E S + ; + +DESTINATION + : D E S T I N A T I O N + ; + +SONAME + : S O N A M E + ; + +OUTLINE + : O U T L I N E + ; + +MASTER_LOG_FILE + : M A S T E R '_' L O G '_' F I L E + ; + +WMSYS + : W M S Y S + ; + +NOMAXVALUE + : N O M A X V A L U E + ; + +ESTIMATE + : E S T I M A T E + ; + +SLAVE + : S L A V E + ; + +GTS + : G T S + ; + +SKIP_BLANK_LINES + : S K I P '_' B L A N K '_' L I N E S + ; + +EXPORT + : E X P O R T + ; + +TEXT + : T E X T + ; + +AVG_ROW_LENGTH + : A V G '_' R O W '_' L E N G T H + ; + +FLASHBACK + : F L A S H B A C K + ; + +SESSION_USER + : S E S S I O N '_' U S E R + ; + +TABLEGROUPS + : T A B L E G R O U P S + ; + +REPLICA_TYPE + : R E P L I C A '_' T Y P E + ; + +AGGREGATE + : A G G R E G A T E + ; + +PERCENT_RANK + : P E R C E N T '_' R A N K + ; + +ENUM + : E N U M + ; + +NATIONAL + : N A T I O N A L + ; + +RECYCLE + : R E C Y C L E + ; + +REGION + : R E G I O N + ; + +MATERIALIZE + : M A T E R I A L I Z E + ; + +FORTRAN + : F O R T R A N + ; + +MUTEX + : M U T E X + ; + +PARALLEL + : P A R A L L E L + ; + +NOPARALLEL + : N O P A R A L L E L + ; + +LOWER_PARENS + : L O W E R '_' P A R E N S + ; + +MONITOR + : M O N I T O R + ; + +NDB + : N D B + ; + +SYSTEM_USER + : S Y S T E M '_' U S E R + ; + +MAX_UPDATES_PER_HOUR + : M A X '_' U P D A T E S '_' P E R '_' H O U R + ; + +R_SKIP + : S K I P + ; + +CONCURRENT + : C O N C U R R E N T + ; + +DUMPFILE + : D U M P F I L E + ; + +COMPILE + : C O M P I L E + ; + +COMPRESSED + : C O M P R E S S E D + ; + +LINESTRING + : L I N E S T R I N G + ; + +EXEMPT + : E X E M P T + ; + +DYNAMIC + : D Y N A M I C + ; + +CHAIN + : C H A I N + ; + +NEG + : N E G + ; + +LAG + : L A G + ; + +NEW + : N E W + ; + +BASELINE_ID + : B A S E L I N E '_' I D + ; + +HIGH + : H I G H + ; + +LAX + : L A X + ; + +SQL_TSI_YEAR + : S Q L '_' T S I '_' Y E A R + ; + +THAN + : T H A N + ; + +CPU + : C P U + ; + +LOGS + : L O G S + ; + +SERIALIZABLE + : S E R I A L I Z A B L E + ; + +DBA_RECYCLEBIN + : D B A '_' R E C Y C L E B I N + ; + +BACKUP + : B A C K U P + ; + +LOGFILE + : L O G F I L E + ; + +ROW_FORMAT + : R O W '_' F O R M A T + ; + +ALLOCATE + : A L L O C A T E + ; + +SET_MASTER_CLUSTER + : S E T '_' M A S T E R '_' C L U S T E R + ; + +MAXLOGHISTORY + : M A X L O G H I S T O R Y + ; + +MINUTE + : M I N U T E + ; + +SWAPS + : S W A P S + ; + +RESETLOGS + : R E S E T L O G S + ; + +DESCRIBE + : D E S C R I B E + ; + +NORESETLOGS + : N O R E S E T L O G S + ; + +TASK + : T A S K + ; + +IO_THREAD + : I O '_' T H R E A D + ; + +BC2HOST + : B C '2' H O S T + ; + +PARAMETERS + : P A R A M E T E R S + ; + +OBJECT + : O B J E C T + ; + +TABLESPACE + : T A B L E S P A C E + ; + +AUTO + : A U T O + ; + +REGEXP_LIKE + : R E G E X P '_' L I K E + ; + +MODULE + : M O D U L E + ; + +PASSWORD + : P A S S W O R D + ; + +SQLCODE + : S Q L C O D E + ; + +SORT + : S O R T + ; + +LOWER_THAN_BY_ACCESS_SESSION + : L O W E R '_' T H A N '_' B Y '_' A C C E S S '_' S E S S I O N + ; + +MESSAGE_TEXT + : M E S S A G E '_' T E X T + ; + +DISK + : D I S K + ; + +FAULTS + : F A U L T S + ; + +HOUR + : H O U R + ; + +REFRESH + : R E F R E S H + ; + +COLUMN_STAT + : C O L U M N '_' S T A T + ; + +PLI + : P L I + ; + +UNIT_GROUP + : U N I T '_' G R O U P + ; + +ERROR_CODE + : E R R O R '_' C O D E + ; + +UPDATEXML + : U P D A T E X M L + ; + +PHASE + : P H A S E + ; + +PROFILE + : P R O F I L E + ; + +NORELY + : N O R E L Y + ; + +LAST_VALUE + : L A S T '_' V A L U E + ; + +RESTART + : R E S T A R T + ; + +TRACE + : T R A C E + ; + +LOGICAL_READS + : L O G I C A L '_' R E A D S + ; + +MANAGEMENT + : M A N A G E M E N T + ; + +DATE_ADD + : D A T E '_' A D D + ; + +BLOCK_INDEX + : B L O C K '_' I N D E X + ; + +DEBUG + : D E B U G + ; + +SERVER_IP + : S E R V E R '_' I P + ; + +SESSIONTIMEZONE + : S E S S I O N T I M E Z O N E + ; + +CODE + : C O D E + ; + +PLUGINS + : P L U G I N S + ; + +ADDDATE + : A D D D A T E + ; + +PASSWORD_LOCK_TIME + : P A S S W O R D '_' L O C K '_' T I M E + ; + +TRANSLATE + : T R A N S L A T E + ; + +COLUMN_FORMAT + : C O L U M N '_' F O R M A T + ; + +MAX_MEMORY + : M A X '_' M E M O R Y + ; + +CLEAN + : C L E A N + ; + +NESTED + : N E S T E D + ; + +MASTER_SSL + : M A S T E R '_' S S L + ; + +CLEAR + : C L E A R + ; + +SORTKEY + : S O R T K E Y + ; + +CHECKSUM + : C H E C K S U M + ; + +INSTALL + : I N S T A L L + ; + +MONTH + : M O N T H + ; + +AFTER + : A F T E R + ; + +MAXINSTANCES + : M A X I N S T A N C E S + ; + +CLOSE + : C L O S E + ; + +JSON_OBJECTAGG + : J S O N '_' O B J E C T A G G + ; + +SET_TP + : S E T '_' T P + ; + +OWNER + : O W N E R + ; + +BLOOM_FILTER + : B L O O M '_' F I L T E R + ; + +ILOG + : I L O G + ; + +META + : M E T A + ; + +PASSWORD_VERIFY_FUNCTION + : P A S S W O R D '_' V E R I F Y '_' F U N C T I O N + ; + +LOWEST_PARENS + : L O W E S T '_' P A R E N S + ; + +IDENTITY + : I D E N T I T Y + ; + +STARTS + : S T A R T S + ; + +PLANREGRESS + : P L A N R E G R E S S + ; + +AUTOEXTEND_SIZE + : A U T O E X T E N D '_' S I Z E + ; + +SOURCE + : S O U R C E + ; + +POW + : P O W + ; + +IGNORE_SERVER_IDS + : I G N O R E '_' S E R V E R '_' I D S + ; + +REPLICA_NUM + : R E P L I C A '_' N U M + ; + +LOWER_THAN_COMP + : L O W E R '_' T H A N '_' C O M P + ; + +BINDING + : B I N D I N G + ; + +MICROSECOND + : M I C R O S E C O N D + ; + +INDICATOR + : I N D I C A T O R + ; + +UNDO_BUFFER_SIZE + : U N D O '_' B U F F E R '_' S I Z E + ; + +EXTENDED_NOADDR + : E X T E N D E D '_' N O A D D R + ; + +JSON_MERGEPATCH + : J S O N '_' M E R G E P A T C H + ; + +SPLIT + : S P L I T + ; + +BASELINE + : B A S E L I N E + ; + +MEMORY + : M E M O R Y + ; + +COVAR_POP + : C O V A R '_' P O P + ; + +SEED + : S E E D + ; + +DESCRIPTION + : D E S C R I P T I O N + ; + +RTREE + : R T R E E + ; + +MEDIAN + : M E D I A N + ; + +UNLIMITED + : U N L I M I T E D + ; + +STDDEV_POP + : S T D D E V '_' P O P + ; + +UNDER + : U N D E R + ; + +RUN + : R U N + ; + +SQL_AFTER_GTIDS + : S Q L '_' A F T E R '_' G T I D S + ; + +OPEN + : O P E N + ; + +REFERENCING + : R E F E R E N C I N G + ; + +SQL_TSI_DAY + : S Q L '_' T S I '_' D A Y + ; + +MANAGE + : M A N A G E + ; + +RELAY_THREAD + : R E L A Y '_' T H R E A D + ; + +BREADTH + : B R E A D T H + ; + +NOCACHE + : N O C A C H E + ; + +DISALLOW + : D I S A L L O W + ; + +PRIVILEGE + : P R I V I L E G E + ; + +PRIMARY_ROOTSERVICE_LIST + : P R I M A R Y '_' R O O T S E R V I C E '_' L I S T + ; + +UNUSUAL + : U N U S U A L + ; + +RELAYLOG + : R E L A Y L O G + ; + +SQL_BEFORE_GTIDS + : S Q L '_' B E F O R E '_' G T I D S + ; + +PRIMARY_ZONE + : P R I M A R Y '_' Z O N E + ; + +TABLE_CHECKSUM + : T A B L E '_' C H E C K S U M + ; + +ZONE_LIST + : Z O N E '_' L I S T + ; + +DATABASE_ID + : D A T A B A S E '_' I D + ; + +TP_NO + : T P '_' N O + ; + +NETWORK + : N E T W O R K + ; + +LOWER_THAN_TO + : L O W E R '_' T H A N '_' T O + ; + +HIDDEN_ + : H I D D E N + ; + +BOOLEAN + : B O O L E A N + ; + +AVG + : A V G + ; + +MULTILINESTRING + : M U L T I L I N E S T R I N G + ; + +APPROX_COUNT_DISTINCT_SYNOPSIS_MERGE + : A P P R O X '_' C O U N T '_' D I S T I N C T '_' S Y N O P S I S '_' M E R G E + ; + +NOW + : N O W + ; + +PROXY + : P R O X Y + ; + +DUPLICATE_SCOPE + : D U P L I C A T E '_' S C O P E + ; + +STATS_SAMPLE_PAGES + : S T A T S '_' S A M P L E '_' P A G E S + ; + +TABLET_SIZE + : T A B L E T '_' S I Z E + ; + +BASE + : B A S E + ; + +FOREIGN + : F O R E I G N + ; + +KVCACHE + : K V C A C H E + ; + +RELAY + : R E L A Y + ; + +MINEXTENTS + : M I N E X T E N T S + ; + +CONTRIBUTORS + : C O N T R I B U T O R S + ; + +MEMORY_SIZE + : M E M O R Y '_' S I Z E + ; + +EMPTY + : E M P T Y + ; + +PARTIAL + : P A R T I A L + ; + +REPORT + : R E P O R T + ; + +ESCAPE + : E S C A P E + ; + +MASTER_AUTO_POSITION + : M A S T E R '_' A U T O '_' P O S I T I O N + ; + +CALC_PARTITION_ID + : C A L C '_' P A R T I T I O N '_' I D + ; + +TP_NAME + : T P '_' N A M E + ; + +SQL_AFTER_MTS_GAPS + : S Q L '_' A F T E R '_' M T S '_' G A P S + ; + +EFFECTIVE + : E F F E C T I V E + ; + +FIRST_VALUE + : F I R S T '_' V A L U E + ; + +SQL_TSI_MINUTE + : S Q L '_' T S I '_' M I N U T E + ; + +UNICODE + : U N I C O D E + ; + +QUARTER + : Q U A R T E R + ; + +ANALYSE + : A N A L Y S E + ; + +DEFINER + : D E F I N E R + ; + +NONE + : N O N E + ; + +PROCESSLIST + : P R O C E S S L I S T + ; + +TYPE + : T Y P E + ; + +CHAR_CS + : C H A R '_' C S + ; + +INSERT_METHOD + : I N S E R T '_' M E T H O D + ; + +EXTENDED + : E X T E N D E D + ; + +LISTS + : L I S T S + ; + +LOG + : L O G + ; + +TIME_ZONE_INFO + : T I M E '_' Z O N E '_' I N F O + ; + +TIMESTAMPADD + : T I M E S T A M P A D D + ; + +DISMOUNT + : D I S M O U N T + ; + +BINARY_FLOAT_INFINITY + : B I N A R Y '_' F L O A T '_' I N F I N I T Y + ; + +GET_FORMAT + : G E T '_' F O R M A T + ; + +LOW + : L O W + ; + +PREPARE + : P R E P A R E + ; + +WORK + : W O R K + ; + +MATERIALIZED + : M A T E R I A L I Z E D + ; + +HANDLER + : H A N D L E R + ; + +CUME_DIST + : C U M E '_' D I S T + ; + +NOSORT + : N O S O R T + ; + +INITIAL_SIZE + : I N I T I A L '_' S I Z E + ; + +RELAY_LOG_FILE + : R E L A Y '_' L O G '_' F I L E + ; + +STORING + : S T O R I N G + ; + +IMPORT + : I M P O R T + ; + +MIN_MEMORY + : M I N '_' M E M O R Y + ; + +HELP + : H E L P + ; + +CREATE_TIMESTAMP + : C R E A T E '_' T I M E S T A M P + ; + +COMPUTE + : C O M P U T E + ; + +RANDOM + : R A N D O M + ; + +SOUNDS + : S O U N D S + ; + +TABLE_MODE + : T A B L E '_' M O D E + ; + +COPY + : C O P Y + ; + +SQL_NO_CACHE + : S Q L '_' N O '_' C A C H E + ; + +MISMATCH + : M I S M A T C H + ; + +EXECUTE + : E X E C U T E + ; + +PRECEDING + : P R E C E D I N G + ; + +SWITCHES + : S W I T C H E S + ; + +PACK_KEYS + : P A C K '_' K E Y S + ; + +ENABLE_EXTENDED_ROWID + : E N A B L E '_' E X T E N D E D '_' R O W I D + ; + +SQL_ID + : S Q L '_' I D + ; + +NOORDER + : N O O R D E R + ; + +CHECKPOINT + : C H E C K P O I N T + ; + +DAY + : D A Y + ; + +AUTHORIZATION + : A U T H O R I Z A T I O N + ; + +LEAD + : L E A D + ; + +JSON_TABLE + : J S O N '_' T A B L E + ; + +JSON_VALUE + : J S O N '_' V A L U E + ; + +DBA + : D B A + ; + +EVENTS + : E V E N T S + ; + +RECURSIVE + : R E C U R S I V E + ; + +ONLY + : O N L Y + ; + +TABLEGROUP_ID + : T A B L E G R O U P '_' I D + ; + +GROUP_ID + : G R O U P '_' I D + ; + +GROUPING_ID + : G R O U P I N G '_' I D + ; + +TOP_K_FRE_HIST + : T O P '_' K '_' F R E '_' H I S T + ; + +MASTER_SSL_CRL + : M A S T E R '_' S S L '_' C R L + ; + +RESOURCE_POOL_LIST + : R E S O U R C E '_' P O O L '_' L I S T + ; + +TRACING + : T R A C I N G + ; + +NTILE + : N T I L E + ; + +NULL_IF_EXETERNAL + : N U L L '_' I F '_' E X E T E R N A L + ; + +SKEWONLY + : S K E W O N L Y + ; + +IS_TENANT_SYS_POOL + : I S '_' T E N A N T '_' S Y S '_' P O O L + ; + +INLINE + : I N L I N E + ; + +MOUNT + : M O U N T + ; + +SCHEDULE + : S C H E D U L E + ; + +JOB + : J O B + ; + +MASTER_LOG_POS + : M A S T E R '_' L O G '_' P O S + ; + +SUBCLASS_ORIGIN + : S U B C L A S S '_' O R I G I N + ; + +MULTIPOINT + : M U L T I P O I N T + ; + +INFINITE_VALUE + : I N F I N I T E '_' V A L U E + ; + +BLOCK + : B L O C K + ; + +SQL_TSI_SECOND + : S Q L '_' T S I '_' S E C O N D + ; + +ROLLUP + : R O L L U P + ; + +CORR + : C O R R + ; + +MIN_CPU + : M I N '_' C P U + ; + +OCCUR + : O C C U R + ; + +ACCESSED + : A C C E S S E D + ; + +DATA + : D A T A + ; + +BINARY_FLOAT_NAN + : B I N A R Y '_' F L O A T '_' N A N + ; + +MASTER_HOST + : M A S T E R '_' H O S T + ; + +PASSWORD_GRACE_TIME + : P A S S W O R D '_' G R A C E '_' T I M E + ; + +VAR_SAMP + : V A R '_' S A M P + ; + +ALGORITHM + : A L G O R I T H M + ; + +CONSTRAINT_NAME + : C O N S T R A I N T '_' N A M E + ; + +LIMIT + : L I M I T + ; + +APPROX_COUNT_DISTINCT + : A P P R O X '_' C O U N T '_' D I S T I N C T + ; + +DDL + : D D L + ; + +BASIC + : B A S I C + ; + +DEFAULT_TABLEGROUP + : D E F A U L T '_' T A B L E G R O U P + ; + +CONTENTS + : C O N T E N T S + ; + +CONTENT + : C O N T E N T + ; + +XMLELEMENT + : X M L E L E M E N T + ; + +ENTITYESCAPING + : E N T I T Y E S C A P I N G + ; + +EXTRACTVALUE + : E X T R A C T V A L U E + ; + +NOENTITYESCAPING + : N O E N T I T Y E S C A P I N G + ; + +NOSCHEMACHECK + : N O S C H E M A C H E C K + ; + +SCHEMACHECK + : S C H E M A C H E C K + ; + +NO_PX_JOIN_FILTER + : N O '_' P X '_' J O I N '_' F I L T E R + ; + +STATEMENT_ID + : S T A T E M E N T '_' I D + ; + +HIGHER_THAN_TO + : H I G H E R '_' T H A N '_' T O + ; + +LINK + : L I N K + ; + +WEEK + : W E E K + ; + +UNCONDITIONAL + : U N C O N D I T I O N A L + ; + +CONDITIONAL + : C O N D I T I O N A L + ; + +NULLS + : N U L L S + ; + +MASTER_SSL_CRLPATH + : M A S T E R '_' S S L '_' C R L P A T H + ; + +CASCADED + : C A S C A D E D + ; + +PLUGIN + : P L U G I N + ; + +ENCRYPTED + : E N C R Y P T E D + ; + +TENANT + : T E N A N T + ; + +INITRANS + : I N I T R A N S + ; + +SCN + : S C N + ; + +LNNVL + : ( L N N V L ) + ; + +INTNUM + : [0-9]+ + ; + +DECIMAL_VAL + : ([0-9]+ E [-+]?[0-9]+ F | [0-9]+'.'[0-9]* E [-+]?[0-9]+ F | '.'[0-9]+ E [-+]?[0-9]+ F ) + | ([0-9]+ E [-+]?[0-9]+ D | [0-9]+'.'[0-9]* E [-+]?[0-9]+ D | '.'[0-9]+ E [-+]?[0-9]+ D ) + | ([0-9]+ E [-+]?[0-9]+ | [0-9]+'.'[0-9]* E [-+]?[0-9]+ | '.'[0-9]+ E [-+]?[0-9]+) + | ([0-9]+'.'[0-9]* F | [0-9]+ F | '.'[0-9]+ F ) + | ([0-9]+'.'[0-9]* D | [0-9]+ D | '.'[0-9]+ D ) + | ([0-9]+'.'[0-9]* | '.'[0-9]+) + ; + +BOOL_VALUE + : T R U E + | F A L S E + ; + +At + : '@' + ; + +LeftBracket + : '[' + ; + +LeftBrace + : '{' + ; + +RightBracket + : ']' + ; + +RightBrace + : '}' + ; + +DATE_VALUE + : D A T E ([ \t\n\r\f]+|('--'(~[\n\r])*))?'\''(~['])*'\'' + | T I M E S T A M P ([ \t\n\r\f]+|('--'(~[\n\r])*))?'\''(~['])*'\'' + ; + +INTERVAL_VALUE + : I N T E R V A L ([ \t\n\r\f]+|('--'(~[\n\r])*))?'\''(~['])*'\''[ \t\n\r\f]*( Y E A R | M O N T H )[ \t\n\r\f]*('('|[\uff08])[ \t\n\r\f]*[0-9]+[ \t\n\r\f]*(')'|[\uff09])? + | I N T E R V A L ([ \t\n\r\f]+|('--'(~[\n\r])*))?'\''(~['])*'\''[ \t\n\r\f]*( Y E A R | M O N T H )([ \t\n\r\f]*('('|[\uff08])[ \t\n\r\f]*[0-9]+[ \t\n\r\f]*(')'|[\uff09])[ \t\n\r\f]*|[ \t\n\r\f]+) T O [ \t\n\r\f]+( Y E A R | M O N T H ) + | I N T E R V A L ([ \t\n\r\f]+|('--'(~[\n\r])*))?'\''(~['])*'\''[ \t\n\r\f]*( D A Y | H O U R | M I N U T E | S E C O N D )[ \t\n\r\f]*('('|[\uff08])[ \t\n\r\f]*[0-9]+[ \t\n\r\f]*(')'|[\uff09])? + | I N T E R V A L ([ \t\n\r\f]+|('--'(~[\n\r])*))?'\''(~['])*'\''[ \t\n\r\f]* S E C O N D [ \t\n\r\f]*('('|[\uff08])[ \t\n\r\f]*[0-9]+[ \t\n\r\f]*','[ \t\n\r\f]*[0-9]+[ \t\n\r\f]*(')'|[\uff09]) + | I N T E R V A L ([ \t\n\r\f]+|('--'(~[\n\r])*))?'\''(~['])*'\''[ \t\n\r\f]*( D A Y | H O U R | M I N U T E | S E C O N D )([ \t\n\r\f]*('('|[\uff08])[ \t\n\r\f]*[0-9]+[ \t\n\r\f]*(')'|[\uff09])[ \t\n\r\f]*|[ \t\n\r\f]+) T O [ \t\n\r\f]+( D A Y | H O U R | M I N U T E | S E C O N D [ \t\n\r\f]*('('|[\uff08])[ \t\n\r\f]*[0-9]+[ \t\n\r\f]*(')'|[\uff09])?) + ; + +HINT_VALUE + : '/''*' H I N T '+'(~[*])+'*''/' + ; + +Comma + : [,] + ; + +Plus + : [+] + ; + +And + : [&] + ; + +Or + : [|] + ; + +Star + : [*] + ; + +Not + : [!] + ; + +LeftParen + : [(] + ; + +Minus + : [-] + ; + +Div + : [/] + ; + +Caret + : [^] + ; + +Colon + : [:] + ; + +Dot + : [.] + ; + +Mod + : [%] + ; + +RightParen + : [)] + ; + +Tilde + : [~] + ; + +DELIMITER + : [;] + ; + +CNNOP + : '||' + ; + +AND_OP + : '&&' + ; + +COMP_EQ + : '=' + ; + +SET_VAR + : ':=' + ; + +COMP_GT + : '>' + ; + +COMP_GE + : '>=' + ; + +COMP_LE + : '<=' + ; + +COMP_LT + : '<' + ; + +COMP_NE + : '!=' | '<>' | '^=' + ; + +SHIFT_LEFT + : '<<' + ; + +SHIFT_RIGHT + : '>>' + ; + +COMP_NE_PL + : '~=' + ; + +POW_PL + : '**' + ; + +QUESTIONMARK + : '?' + | ':'[0-9]+ + | ':'(([A-Za-z]|~[\u0000-\u007F\uD800-\uDBFF])([A-Za-z0-9$_#]|~[\u0000-\u007F\uD800-\uDBFF])*) + ; + +SYSTEM_VARIABLE + : ('@''@'[A-Za-z_][A-Za-z0-9_]*) + ; + +USER_VARIABLE + : ('@'[A-Za-z0-9_.$]*)|('@'['"]['"A-Za-z0-9_.$/%]*) + ; + +PARSER_SYNTAX_ERROR + : X '\''([0-9A-F])*'\'' + | '.' + ; + +PLSQL_VARIABLE + : ('$''$'[A-Za-z_][A-Za-z0-9_$#]*) + ; + +MULTISET_OP + : ( M U L T I S E T [ \t\n\r\f]+( U N I O N | I N T E R S E C T | E X C E P T )) + ; + +A_ + : A + ; + +NAME_OB + : (([A-Za-z]|~[\u0000-\u007F\uD800-\uDBFF])([A-Za-z0-9$_#]|~[\u0000-\u007F\uD800-\uDBFF])*) + | '"' (~["]|('""'))* '"' + ; + +CHAR_STRING_PERL + : Q '\'' (QS_ANGLE | QS_BRACE | QS_BRACK | QS_PAREN | QS_EXCLAM | QS_SHARP | QS_QUOTE | QS_DQUOTE) '\'' -> type(STRING_VALUE); + +STRING_VALUE + : ('N'|'n')?('Q'|'q')? '\'' (~[']|('\'\''))* '\'' + ; + +In_c_comment + : '/*' .*? '*/' -> channel(1) + ; + +ANTLR_SKIP + : '--'[ \t]* .*? '\n' -> channel(1) + ; + +Blank + : [ \t\r\n] -> channel(1) ; + + +fragment A : [aA]; +fragment B : [bB]; +fragment C : [cC]; +fragment D : [dD]; +fragment E : [eE]; +fragment F : [fF]; +fragment G : [gG]; +fragment H : [hH]; +fragment I : [iI]; +fragment J : [jJ]; +fragment K : [kK]; +fragment L : [lL]; +fragment M : [mM]; +fragment N : [nN]; +fragment O : [oO]; +fragment P : [pP]; +fragment Q : [qQ]; +fragment R : [rR]; +fragment S : [sS]; +fragment T : [tT]; +fragment U : [uU]; +fragment V : [vV]; +fragment W : [wW]; +fragment X : [xX]; +fragment Y : [yY]; +fragment Z : [zZ]; +fragment QS_ANGLE : '<' .*? '>'; +fragment QS_BRACE : '{' .*? '}'; +fragment QS_BRACK : '[' .*? ']'; +fragment QS_PAREN : '(' .*? ')'; +fragment QS_EXCLAM : '!' .*? '!'; +fragment QS_SHARP : '#' .*? '#'; +fragment QS_QUOTE : '\'' .*? '\''; +fragment QS_DQUOTE : '"' .*? '"'; diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/antlr4/com/aliyun/fastmodel/transform/oceanbase/oracle/parser/OBParser.g4 b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/antlr4/com/aliyun/fastmodel/transform/oceanbase/oracle/parser/OBParser.g4 new file mode 100644 index 0000000..7c4e6ee --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/antlr4/com/aliyun/fastmodel/transform/oceanbase/oracle/parser/OBParser.g4 @@ -0,0 +1,5739 @@ +/* + * Copyright (c) 2023 OceanBase. + * + * Licensed 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. + */ + +parser grammar OBParser; + + +options { tokenVocab=OBLexer; } + +@parser::members { +public boolean is_pl_parse_ = false; +public boolean is_pl_parse_expr_ = false; +} + + +// start rule: sql_stmt + +sql_stmt + : stmt_list + ; + +stmt_list + : EOF + | DELIMITER + | stmt EOF + | stmt DELIMITER EOF? + ; + +stmt + : select_stmt + | insert_stmt + | merge_stmt + | create_table_stmt + | alter_database_stmt + | update_stmt + | delete_stmt + | drop_table_stmt + | drop_view_stmt + | explain_stmt + | create_outline_stmt + | alter_outline_stmt + | drop_outline_stmt + | show_stmt + | prepare_stmt + | variable_set_stmt + | execute_stmt + | call_stmt + | alter_table_stmt + | alter_index_stmt + | alter_system_stmt + | audit_stmt + | deallocate_prepare_stmt + | create_user_stmt + | alter_user_stmt + | alter_user_profile_stmt + | drop_user_stmt + | set_password_stmt + | lock_user_stmt + | grant_stmt + | revoke_stmt + | begin_stmt + | commit_stmt + | rollback_stmt + | create_index_stmt + | drop_index_stmt + | kill_stmt + | help_stmt + | create_view_stmt + | create_tenant_stmt + | alter_tenant_stmt + | drop_tenant_stmt + | create_restore_point_stmt + | drop_restore_point_stmt + | create_resource_stmt + | alter_resource_stmt + | drop_resource_stmt + | set_names_stmt + | set_charset_stmt + | create_tablegroup_stmt + | drop_tablegroup_stmt + | alter_tablegroup_stmt + | rename_table_stmt + | truncate_table_stmt + | set_transaction_stmt + | create_synonym_stmt + | drop_synonym_stmt + | create_directory_stmt + | drop_directory_stmt + | create_keystore_stmt + | alter_keystore_stmt + | create_tablespace_stmt + | drop_tablespace_stmt + | alter_tablespace_stmt + | create_savepoint_stmt + | rollback_savepoint_stmt + | lock_tables_stmt + | lock_table_stmt + | unlock_tables_stmt + | flashback_stmt + | purge_stmt + | create_sequence_stmt + | alter_sequence_stmt + | drop_sequence_stmt + | alter_session_stmt + | analyze_stmt + | set_comment_stmt + | pl_expr_stmt + | shrink_space_stmt + | load_data_stmt + | create_dblink_stmt + | drop_dblink_stmt + | create_role_stmt + | drop_role_stmt + | alter_role_stmt + | set_role_stmt + | create_profile_stmt + | alter_profile_stmt + | drop_profile_stmt + | method_opt + | drop_package_stmt + | drop_procedure_stmt + | drop_function_stmt + | drop_trigger_stmt + | drop_type_stmt + | create_context_stmt + | drop_context_stmt + | switchover_tenant_stmt + | recover_tenant_stmt + ; + +drop_package_stmt + : DROP PACKAGE BODY? relation_factor + ; + +drop_procedure_stmt + : DROP PROCEDURE (IF EXISTS)? relation_factor + ; + +drop_function_stmt + : DROP FUNCTION (IF EXISTS)? relation_factor + ; + +drop_trigger_stmt + : DROP TRIGGER relation_factor + ; + +drop_type_stmt + : DROP TYPE BODY? relation_factor (FORCE | VALIDATE)? + ; + +pl_expr_stmt + : DO expr + ; + +expr_list + : bit_expr (Comma bit_expr)* + ; + +column_ref + : column_name + | LEVEL + | ROWNUM + | oracle_pl_non_reserved_words + ; + +oracle_pl_non_reserved_words + : ACCESS + | ADD + | AUDIT + | CHAR + | COLUMN + | COMMENT + | CURRENT + | DATE + | DECIMAL + | FILE_KEY + | FLOAT + | IMMEDIATE + | INCREMENT + | INITIAL_ + | INTEGER + | LONG + | MAXEXTENTS + | MODIFY + | NOAUDIT + | NOTFOUND + | NUMBER + | OFFLINE + | ONLINE + | PCTFREE + | PRIVILEGES + | RAW + | RENAME + | ROW + | ROWLABEL + | ROWS + | SESSION + | SET + | SMALLINT + | SUCCESSFUL + | SYNONYM + | TRIGGER + | VALIDATE + | VARCHAR + | VARCHAR2 + | WHENEVER + | DUAL + ; + +complex_string_literal + : STRING_VALUE + ; + +js_literal + : literal + ; + +literal + : complex_string_literal + | DATE_VALUE + | TIMESTAMP_VALUE + | INTNUM + | APPROXNUM + | DECIMAL_VAL + | NULLX + | INTERVAL_VALUE + ; + +number_literal + : INTNUM + | DECIMAL_VAL + ; + +expr_const + : literal + | SYSTEM_VARIABLE + | QUESTIONMARK + | (GLOBAL_ALIAS|SESSION_ALIAS) Dot column_name + ; + +conf_const + : STRING_VALUE + | DATE_VALUE + | TIMESTAMP_VALUE + | Minus? INTNUM + | APPROXNUM + | Minus? DECIMAL_VAL + | BOOL_VALUE + | NULLX + | SYSTEM_VARIABLE + | (GLOBAL_ALIAS|SESSION_ALIAS) Dot column_name + ; + +bool_pri + : bit_expr IS not? (NULLX|is_nan_inf_value) + | bit_expr IS NOT? (JSON FORMAT)? is_json_constrain + | bit_expr ((((COMP_EQ|COMP_GE)|(COMP_LE|COMP_LT)) SOME|((COMP_GT|COMP_NE) SOME|COMP_NE_PL))|(((COMP_GE|COMP_GT? COMP_EQ)|(COMP_LE|COMP_LT COMP_EQ?))|((COMP_LT? COMP_GT|COMP_NE)|(Caret|Not) COMP_EQ)) sub_query_flag?) bit_expr + | predicate + ; + +is_json_constrain + : JSON strict_opt? ((scalars_opt unique_keys_opt?)?|unique_keys_opt scalars_opt?) + | JSON LeftParen strict_opt scalars_opt? unique_keys_opt? RightParen + | JSON LeftParen strict_opt? unique_keys_opt scalars_opt RightParen + | JSON LeftParen scalars_opt strict_opt? unique_keys_opt? RightParen + | JSON scalars_opt strict_opt unique_keys_opt? + | JSON scalars_opt? unique_keys_opt strict_opt + | JSON LeftParen scalars_opt? unique_keys_opt strict_opt RightParen + | JSON LeftParen unique_keys_opt ((strict_opt scalars_opt)?|scalars_opt strict_opt) RightParen + | JSON unique_keys_opt strict_opt scalars_opt + | JSON unique_keys_opt scalars_opt strict_opt + ; + +strict_opt + : LAX + | STRICT + ; + +scalars_opt + : ALLOW SCALARS + | DISALLOW SCALARS + ; + +unique_keys_opt + : (WITH|WITHOUT) UNIQUE KEYS + ; + +json_equal_option + : (BOOL_VALUE|ERROR_P) ON ERROR_P + ; + +predicate + : LNNVL LeftParen bool_pri RightParen + | bit_expr not? IN in_expr + | bit_expr not? BETWEEN bit_expr AND bit_expr + | bit_expr not? LIKE bit_expr (ESCAPE bit_expr)? + | REGEXP_LIKE LeftParen substr_params RightParen + | exists_function_name select_with_parens + | collection_predicate_expr + | updating_func + ; + +collection_predicate_expr + : bit_expr MEMBER OF? bit_expr + | bit_expr NOT MEMBER OF? bit_expr + | bit_expr SUBMULTISET OF? bit_expr + | bit_expr NOT SUBMULTISET OF? bit_expr + | bit_expr IS A_ SET + | bit_expr IS NOT A_ SET + | bit_expr IS EMPTY + | bit_expr IS NOT EMPTY + ; + +bit_expr + : bit_expr Plus bit_expr + | bit_expr Minus bit_expr + | bit_expr Star bit_expr + | bit_expr Div bit_expr + | bit_expr CNNOP bit_expr + | bit_expr AT TIME ZONE bit_expr + | bit_expr AT LOCAL + | bit_expr MULTISET_OP (ALL | DISTINCT)? bit_expr + | bit_expr POW_PL bit_expr + | bit_expr MOD bit_expr + | unary_expr + | BOOL_VALUE + ; + +is_nan_inf_value + : NAN_VALUE + | INFINITE_VALUE + ; + +unary_expr + : Plus? simple_expr + | Minus simple_expr + ; + +simple_expr + : simple_expr collation + | obj_access_ref COLUMN_OUTER_JOIN_SYMBOL + | expr_const + | select_with_parens + | CURSOR LeftParen select_stmt RightParen + | LeftParen bit_expr RightParen + | LeftParen expr_list Comma bit_expr RightParen + | MATCH LeftParen column_list RightParen AGAINST LeftParen STRING_VALUE ((IN NATURAL LANGUAGE MODE) | (IN BOOLEAN MODE))? RightParen + | case_expr + | obj_access_ref + | sql_function + | cursor_attribute_expr + | window_function + | USER_VARIABLE + | PLSQL_VARIABLE + | PRIOR unary_expr + | CONNECT_BY_ROOT unary_expr + | SET LeftParen bit_expr RightParen + | MULTISET select_with_parens + | column_ref Dot column_ref USER_VARIABLE + | column_ref Dot column_ref Dot column_ref USER_VARIABLE + | {this.is_pl_parse_}? QUESTIONMARK Dot column_name + ; + +json_function + : json_value_expr + | json_query_expr + | json_mergepatch_expr + | json_array_expr + | json_exists_expr + | json_object_expr + | json_table_expr + ; + +common_cursor_attribute + : ISOPEN + | FOUND + | NOTFOUND + | ROWCOUNT + ; + +cursor_attribute_bulk_rowcount + : BULK_ROWCOUNT LeftParen bit_expr RightParen + ; + +cursor_attribute_bulk_exceptions + : BULK_EXCEPTIONS Dot COUNT + | BULK_EXCEPTIONS LeftParen bit_expr RightParen Dot (ERROR_CODE|ERROR_INDEX) + ; + +implicit_cursor_attribute + : SQL Mod ((common_cursor_attribute|cursor_attribute_bulk_rowcount)|cursor_attribute_bulk_exceptions) + ; + +explicit_cursor_attribute + : obj_access_ref Mod common_cursor_attribute + ; + +cursor_attribute_expr + : explicit_cursor_attribute + | implicit_cursor_attribute + ; + +obj_access_ref + : column_ref ((Dot obj_access_ref) | (Dot Star))? + | access_func_expr func_access_ref? + | QUESTIONMARK func_access_ref + | column_ref Dot FIRST LeftParen RightParen + | column_ref Dot LAST LeftParen RightParen + | column_ref Dot COUNT LeftParen RightParen + | column_ref dot_notation_path + | dot_notation_fun_sys + ; + +dot_notation_path + : LeftBracket path_param_array RightBracket dot_notation_path_obj_access_ref + ; + +dot_notation_path_obj_access_ref + : empty + | Dot obj_access_ref + | dot_notation_path + ; + +path_param_array + : Star (Comma path_param_list)? + | path_param_list + ; + +path_param_list + : path_param (Comma path_param)* + ; + +path_param + : INTNUM (TO path_param)? + ; + +dot_notation_fun_sys + : dot_notation_fun + ; + +dot_notation_fun + : func_name=(DATE|SIZE|NUMBER) LeftParen RightParen + ; + +obj_access_ref_normal + : pl_var_name (Dot obj_access_ref_normal)? + | access_func_expr_count ((Dot obj_access_ref_normal) | table_element_access_list)? + | var_name LeftParen func_param_list? RightParen ((Dot obj_access_ref_normal) | table_element_access_list)? + | PRIOR LeftParen func_param_list? RightParen ((Dot obj_access_ref_normal) | table_element_access_list)? + | exists_function_name LeftParen func_param_list? RightParen ((Dot obj_access_ref_normal) | table_element_access_list)? + ; + +func_access_ref + : table_element_access_list? Dot obj_access_ref + | table_element_access_list + ; + +table_element_access_list + : LeftParen table_index RightParen + | table_element_access_list LeftParen table_index RightParen + ; + +table_index + : bit_expr + ; + +expr + : NOT expr + | (USER_VARIABLE set_var_op)? bit_expr + | bool_pri + | LeftParen expr RightParen + | expr (AND|OR) expr + ; + +not + : NOT + ; + +sub_query_flag + : ALL + | ANY + ; + +in_expr + : bit_expr + ; + +case_expr + : CASE (bit_expr simple_when_clause_list|bool_when_clause_list) case_default END CASE? + ; + +window_function + : func_name=COUNT LeftParen ALL? Star RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=COUNT LeftParen ALL? bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=COUNT LeftParen DISTINCT bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=APPROX_COUNT_DISTINCT LeftParen expr_list RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=APPROX_COUNT_DISTINCT_SYNOPSIS LeftParen expr_list RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=APPROX_COUNT_DISTINCT_SYNOPSIS_MERGE LeftParen bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=SUM LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=MAX LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=MIN LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=AVG LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=MEDIAN LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=STDDEV LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=VARIANCE LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=STDDEV_POP LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=STDDEV_SAMP LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=LISTAGG LeftParen (ALL | DISTINCT | UNIQUE)? expr_list RightParen WITHIN GROUP LeftParen order_by RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=LISTAGG LeftParen (ALL | DISTINCT | UNIQUE)? expr_list RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=RANK LeftParen RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=DENSE_RANK LeftParen RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=PERCENT_RANK LeftParen RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=ROW_NUMBER LeftParen RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=NTILE LeftParen bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=CUME_DIST LeftParen RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=FIRST_VALUE win_fun_first_last_params OVER LeftParen generalized_window_clause RightParen + | func_name=LAST_VALUE win_fun_first_last_params OVER LeftParen generalized_window_clause RightParen + | func_name=LEAD win_fun_lead_lag_params OVER LeftParen generalized_window_clause RightParen + | func_name=LAG win_fun_lead_lag_params OVER LeftParen generalized_window_clause RightParen + | func_name=NTH_VALUE LeftParen bit_expr Comma bit_expr RightParen (FROM first_or_last)? (respect_or_ignore NULLS)? OVER LeftParen generalized_window_clause RightParen + | func_name=RATIO_TO_REPORT LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=CORR LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr Comma bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=COVAR_POP LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr Comma bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=COVAR_SAMP LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr Comma bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=VAR_POP LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=VAR_SAMP LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=REGR_SLOPE LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr Comma bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=REGR_INTERCEPT LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr Comma bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=REGR_COUNT LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr Comma bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=REGR_R2 LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr Comma bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=REGR_AVGX LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr Comma bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=REGR_AVGY LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr Comma bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=REGR_SXX LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr Comma bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=REGR_SYY LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr Comma bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=REGR_SXY LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr Comma bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=MAX LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen KEEP LeftParen DENSE_RANK first_or_last order_by RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=MIN LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen KEEP LeftParen DENSE_RANK first_or_last order_by RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=SUM LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen KEEP LeftParen DENSE_RANK first_or_last order_by RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=COUNT LeftParen ALL? Star RightParen KEEP LeftParen DENSE_RANK first_or_last order_by RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=COUNT LeftParen ALL? bit_expr RightParen KEEP LeftParen DENSE_RANK first_or_last order_by RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=AVG LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen KEEP LeftParen DENSE_RANK first_or_last order_by RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=VARIANCE LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen KEEP LeftParen DENSE_RANK first_or_last order_by RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=STDDEV LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen KEEP LeftParen DENSE_RANK first_or_last order_by RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=PERCENTILE_CONT LeftParen (ALL | DISTINCT | UNIQUE)? expr_list RightParen WITHIN GROUP LeftParen order_by RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=PERCENTILE_DISC LeftParen (ALL | DISTINCT | UNIQUE)? expr_list RightParen WITHIN GROUP LeftParen order_by RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=WM_CONCAT LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=WMSYS Dot sub_func_name=WM_CONCAT LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=WM_CONCAT LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen KEEP LeftParen DENSE_RANK first_or_last order_by RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=WMSYS Dot sub_func_name=WM_CONCAT LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen KEEP LeftParen DENSE_RANK first_or_last order_by RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=TOP_K_FRE_HIST LeftParen bit_expr Comma bit_expr Comma bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | func_name=HYBRID_HIST LeftParen bit_expr Comma bit_expr RightParen OVER LeftParen generalized_window_clause RightParen + | function_name LeftParen func_param_list RightParen OVER LeftParen generalized_window_clause RightParen + | function_name LeftParen ALL func_param_list RightParen OVER LeftParen generalized_window_clause RightParen + | function_name LeftParen DISTINCT func_param_list RightParen OVER LeftParen generalized_window_clause RightParen + | function_name LeftParen UNIQUE func_param_list RightParen OVER LeftParen generalized_window_clause RightParen + ; + +first_or_last + : FIRST + | LAST + ; + +respect_or_ignore + : RESPECT + | IGNORE + ; + +win_fun_first_last_params + : LeftParen bit_expr respect_or_ignore NULLS RightParen + | LeftParen bit_expr RightParen (respect_or_ignore NULLS)? + ; + +win_fun_lead_lag_params + : LeftParen bit_expr respect_or_ignore NULLS RightParen + | LeftParen bit_expr respect_or_ignore NULLS Comma expr_list RightParen + | LeftParen expr_list RightParen (respect_or_ignore NULLS)? + ; + +generalized_window_clause + : (PARTITION BY expr_list)? order_by? win_window? + ; + +win_rows_or_range + : ROWS + | RANGE + ; + +win_preceding_or_following + : PRECEDING + | FOLLOWING + ; + +win_interval + : bit_expr + ; + +win_bounding + : CURRENT ROW + | win_interval win_preceding_or_following + ; + +win_window + : win_rows_or_range BETWEEN win_bounding AND win_bounding + | win_rows_or_range win_bounding + ; + +simple_when_clause_list + : simple_when_clause+ + ; + +simple_when_clause + : WHEN bit_expr THEN bit_expr + ; + +bool_when_clause_list + : bool_when_clause+ + ; + +bool_when_clause + : WHEN expr THEN bit_expr + ; + +case_default + : ELSE bit_expr + | empty + ; + +sql_function + : single_row_function + | aggregate_function + | special_func_expr + ; + +xml_function + : xmlparse_expr + | xml_element_expr + | xml_extract_expr + | xmlserialize_expr + | xmlcast_expr + ; + +single_row_function + : numeric_function + | character_function + | extract_function + | conversion_function + | hierarchical_function + | environment_id_function + | json_function + | xml_function ((Dot obj_access_ref_normal) | table_element_access_list)? + ; + +numeric_function + : MOD LeftParen bit_expr Comma bit_expr RightParen + ; + +character_function + : TRIM LeftParen parameterized_trim RightParen + | ASCII LeftParen bit_expr RightParen + | TRANSLATE LeftParen bit_expr USING translate_charset RightParen + | TRANSLATE LeftParen bit_expr Comma bit_expr Comma bit_expr RightParen + ; + +translate_charset + : CHAR_CS + | NCHAR_CS + ; + +extract_function + : EXTRACT LeftParen date_unit_for_extract FROM bit_expr RightParen + ; + +conversion_function + : CAST LeftParen bit_expr AS cast_data_type RightParen + | TREAT LeftParen bit_expr AS treat_data_type RightParen + ; + +hierarchical_function + : SYS_CONNECT_BY_PATH LeftParen bit_expr Comma bit_expr RightParen + ; + +environment_id_function + : USER + | UID + ; + +aggregate_function + : funcName=APPROX_COUNT_DISTINCT LeftParen expr_list RightParen + | funcName=APPROX_COUNT_DISTINCT_SYNOPSIS LeftParen expr_list RightParen + | funcName=APPROX_COUNT_DISTINCT_SYNOPSIS_MERGE LeftParen bit_expr RightParen + | funcName=SUM LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen + | funcName=MAX LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen + | funcName=MIN LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen + | funcName=AVG LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen + | funcName=JSON_ARRAYAGG LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr (FORMAT JSON)? order_by? js_agg_on_null? js_agg_returning_type_opt? STRICT? RightParen + | funcName=JSON_OBJECTAGG LeftParen KEY? bit_expr VALUE bit_expr (FORMAT JSON)? js_agg_on_null? js_agg_returning_type_opt? STRICT? json_obj_unique_key? RightParen + | funcName=JSON_OBJECTAGG LeftParen bit_expr Comma bit_expr (FORMAT JSON)? js_agg_on_null? js_agg_returning_type_opt? STRICT? json_obj_unique_key? RightParen + | funcName=MEDIAN LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen + | funcName=STDDEV LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen + | funcName=VARIANCE LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen + | funcName=STDDEV_POP LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen + | funcName=STDDEV_SAMP LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen + | funcName=GROUPING LeftParen bit_expr RightParen + | funcName=LISTAGG LeftParen (ALL | DISTINCT | UNIQUE)? expr_list RightParen WITHIN GROUP LeftParen order_by RightParen + | funcName=LISTAGG LeftParen (ALL | DISTINCT | UNIQUE)? expr_list RightParen + | funcName=CORR LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr Comma bit_expr RightParen + | funcName=COVAR_POP LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr Comma bit_expr RightParen + | funcName=COVAR_SAMP LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr Comma bit_expr RightParen + | funcName=VAR_POP LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen + | funcName=VAR_SAMP LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen + | funcName=REGR_SLOPE LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr Comma bit_expr RightParen + | funcName=REGR_INTERCEPT LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr Comma bit_expr RightParen + | funcName=REGR_COUNT LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr Comma bit_expr RightParen + | funcName=REGR_R2 LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr Comma bit_expr RightParen + | funcName=REGR_AVGX LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr Comma bit_expr RightParen + | funcName=REGR_AVGY LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr Comma bit_expr RightParen + | funcName=REGR_SXX LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr Comma bit_expr RightParen + | funcName=REGR_SYY LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr Comma bit_expr RightParen + | funcName=REGR_SXY LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr Comma bit_expr RightParen + | funcName=RANK LeftParen (ALL | DISTINCT | UNIQUE)? expr_list RightParen WITHIN GROUP LeftParen order_by RightParen + | funcName=PERCENT_RANK LeftParen (ALL | DISTINCT | UNIQUE)? expr_list RightParen WITHIN GROUP LeftParen order_by RightParen + | funcName=DENSE_RANK LeftParen (ALL | DISTINCT | UNIQUE)? expr_list RightParen WITHIN GROUP LeftParen order_by RightParen + | funcName=CUME_DIST LeftParen (ALL | DISTINCT | UNIQUE)? expr_list RightParen WITHIN GROUP LeftParen order_by RightParen + | funcName=PERCENTILE_CONT LeftParen (ALL | DISTINCT | UNIQUE)? expr_list RightParen WITHIN GROUP LeftParen order_by RightParen + | funcName=PERCENTILE_DISC LeftParen (ALL | DISTINCT | UNIQUE)? expr_list RightParen WITHIN GROUP LeftParen order_by RightParen + | funcName=MAX LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen KEEP LeftParen DENSE_RANK first_or_last order_by RightParen + | funcName=MIN LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen KEEP LeftParen DENSE_RANK first_or_last order_by RightParen + | funcName=SUM LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen KEEP LeftParen DENSE_RANK first_or_last order_by RightParen + | funcName=AVG LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen KEEP LeftParen DENSE_RANK first_or_last order_by RightParen + | funcName=VARIANCE LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen KEEP LeftParen DENSE_RANK first_or_last order_by RightParen + | funcName=STDDEV LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen KEEP LeftParen DENSE_RANK first_or_last order_by RightParen + | funcName=WM_CONCAT LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen + | funcName=WMSYS Dot subFuncName=WM_CONCAT LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen + | funcName=WM_CONCAT LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen KEEP LeftParen DENSE_RANK first_or_last order_by RightParen + | funcName=WMSYS Dot subFuncName=WM_CONCAT LeftParen (ALL | DISTINCT | UNIQUE)? bit_expr RightParen KEEP LeftParen DENSE_RANK first_or_last order_by RightParen + | funcName=TOP_K_FRE_HIST LeftParen bit_expr Comma bit_expr Comma bit_expr RightParen + | funcName=HYBRID_HIST LeftParen bit_expr Comma bit_expr RightParen + | funcName=XMLAGG LeftParen simple_expr order_by? RightParen + ; + +js_agg_on_null + : (ABSENT | NULLX) ON NULLX + ; + +js_agg_returning_type_opt + : RETURNING js_return_type + | RETURNING js_agg_returning_type + ; + +js_agg_returning_type + : RAW LeftParen zero_suffix_intnum RightParen + | RAW + | NVARCHAR2 nstring_length_i? + ; + +special_func_expr + : (((DATE|ISNULL)|(TIME|YEAR))|MONTH) LeftParen bit_expr RightParen + | cur_timestamp_func + | INSERT LeftParen bit_expr Comma bit_expr Comma bit_expr Comma bit_expr RightParen + | (CALC_PARTITION_ID|LEFT) LeftParen bit_expr Comma bit_expr RightParen + | POSITION LeftParen bit_expr IN bit_expr RightParen + | (DEFAULT|VALUES) LeftParen column_definition_ref RightParen + | CALC_PARTITION_ID LeftParen bit_expr Comma bit_expr Comma bit_expr RightParen + ; + +access_func_expr_count + : COUNT LeftParen ALL? Star RightParen + | COUNT LeftParen ALL? bit_expr RightParen + | COUNT LeftParen DISTINCT bit_expr RightParen + | COUNT LeftParen UNIQUE bit_expr RightParen + | COUNT LeftParen ALL? Star RightParen KEEP LeftParen DENSE_RANK first_or_last order_by RightParen + | COUNT LeftParen ALL? bit_expr RightParen KEEP LeftParen DENSE_RANK first_or_last order_by RightParen + ; + +access_func_expr + : access_func_expr_count + | function_name LeftParen RightParen + | function_name LeftParen func_param_list RightParen + | NEW NAME_OB LeftParen RightParen + | NEW NAME_OB LeftParen func_param_list RightParen + | function_name LeftParen func_param_list opt_json_exist RightParen + | function_name LeftParen func_param_list json_equal_option RightParen + | aggregate_function_keyword LeftParen RightParen + | aggregate_function_keyword LeftParen func_param_list RightParen + | function_name LeftParen ALL func_param_list RightParen + | function_name LeftParen DISTINCT func_param_list RightParen + | function_name LeftParen UNIQUE func_param_list RightParen + | exists_function_name LeftParen func_param_list? RightParen + ; + +func_param_list + : func_param (Comma func_param)* + ; + +func_param + : func_param_with_assign + | bit_expr + | bool_pri_in_pl_func + ; + +func_param_with_assign + : var_name PARAM_ASSIGN_OPERATOR (bit_expr|bool_pri_in_pl_func) + ; + +pl_var_name + : var_name + | oracle_pl_non_reserved_words + ; + +bool_pri_in_pl_func + : bool_pri + | NOT bool_pri_in_pl_func + | LeftParen bool_pri_in_pl_func RightParen + | bool_pri_in_pl_func (AND|OR) bool_pri_in_pl_func + ; + +cur_timestamp_func + : SYSDATE + | ((LOCALTIMESTAMP|SYSTIMESTAMP)|CURRENT_TIMESTAMP) LeftParen INTNUM RightParen + ; + +updating_func + : UPDATING LeftParen updating_params RightParen + ; + +updating_params + : STRING_VALUE + | pl_var_name + ; + +substr_params + : bit_expr Comma bit_expr (Comma bit_expr)? + ; + +returning_log_error_clause + : returning_clause + | log_error_clause + | returning_clause log_error_clause + ; + +returning_clause + : (RETURNING | RETURN) returning_exprs opt_into_clause + ; + +log_error_clause + : LOG ERRORS into_err_log_caluse opt_simple_expression reject_limit + ; + +delete_stmt + : delete_with_opt_hint FROM table_factor opt_where_extension returning_log_error_clause? + | delete_with_opt_hint table_factor ((WHERE expr) | (WHERE HINT_VALUE expr))? returning_log_error_clause? + ; + +update_stmt + : update_with_opt_hint dml_table_clause SET update_asgn_list opt_where_extension returning_log_error_clause? + ; + +update_asgn_list + : normal_asgn_list + | ROW COMP_EQ obj_access_ref_normal + ; + +normal_asgn_list + : update_asgn_factor (Comma update_asgn_factor)* + ; + +update_asgn_factor + : column_definition_ref COMP_EQ expr_or_default + | LeftParen column_list RightParen COMP_EQ LeftParen subquery order_by? fetch_next_clause? RightParen + ; + +create_resource_stmt + : CREATE RESOURCE UNIT relation_name (resource_unit_option | (opt_resource_unit_option_list Comma resource_unit_option))? + | CREATE RESOURCE POOL relation_name (create_resource_pool_option | (opt_create_resource_pool_option_list Comma create_resource_pool_option))? + ; + +opt_resource_unit_option_list + : resource_unit_option + | empty + | opt_resource_unit_option_list Comma resource_unit_option + ; + +resource_unit_option + : MIN_CPU COMP_EQ? conf_const + | MIN_IOPS COMP_EQ? conf_const + | MIN_MEMORY COMP_EQ? conf_const + | MAX_CPU COMP_EQ? conf_const + | MAX_MEMORY COMP_EQ? conf_const + | MEMORY_SIZE COMP_EQ? conf_const + | MAX_IOPS COMP_EQ? conf_const + | MAX_DISK_SIZE COMP_EQ? conf_const + | MAX_SESSION_NUM COMP_EQ? conf_const + | IOPS_WEIGHT COMP_EQ? conf_const + | LOG_DISK_SIZE COMP_EQ? conf_const + ; + +opt_create_resource_pool_option_list + : create_resource_pool_option + | empty + | opt_create_resource_pool_option_list Comma create_resource_pool_option + ; + +create_resource_pool_option + : UNIT COMP_EQ? relation_name_or_string + | UNIT_NUM COMP_EQ? INTNUM + | ZONE_LIST COMP_EQ? LeftParen zone_list RightParen + | REPLICA_TYPE COMP_EQ? STRING_VALUE + ; + +alter_resource_pool_option_list + : alter_resource_pool_option (Comma alter_resource_pool_option)* + ; + +id_list + : INTNUM (Comma INTNUM)* + ; + +alter_resource_pool_option + : UNIT COMP_EQ? relation_name_or_string + | UNIT_NUM COMP_EQ? INTNUM (DELETE UNIT opt_equal_mark LeftParen id_list RightParen)? + | ZONE_LIST COMP_EQ? LeftParen zone_list RightParen + ; + +alter_resource_stmt + : ALTER RESOURCE UNIT relation_name (resource_unit_option | (opt_resource_unit_option_list Comma resource_unit_option))? + | ALTER RESOURCE POOL relation_name alter_resource_pool_option_list + | ALTER RESOURCE POOL relation_name SPLIT INTO LeftParen resource_pool_list RightParen ON LeftParen zone_list RightParen + | ALTER RESOURCE POOL MERGE LeftParen resource_pool_list RightParen INTO LeftParen resource_pool_list RightParen + | ALTER RESOURCE TENANT relation_name UNIT_NUM COMP_EQ? INTNUM (DELETE UNIT_GROUP opt_equal_mark LeftParen id_list RightParen)? + ; + +drop_resource_stmt + : DROP RESOURCE (POOL|UNIT) relation_name + ; + +create_tenant_stmt + : CREATE TENANT relation_name (tenant_option | (opt_tenant_option_list Comma tenant_option))? ((SET sys_var_and_val_list) | (SET VARIABLES sys_var_and_val_list) | (VARIABLES sys_var_and_val_list))? + ; + +opt_tenant_option_list + : tenant_option + | empty + | opt_tenant_option_list Comma tenant_option + ; + +tenant_option + : LOGONLY_REPLICA_NUM COMP_EQ? INTNUM + | LOCALITY COMP_EQ? STRING_VALUE FORCE? + | REPLICA_NUM COMP_EQ? INTNUM + | REWRITE_MERGE_VERSION COMP_EQ? INTNUM + | STORAGE_FORMAT_VERSION COMP_EQ? INTNUM + | STORAGE_FORMAT_WORK_VERSION COMP_EQ? INTNUM + | PRIMARY_ZONE COMP_EQ? primary_zone_name + | RESOURCE_POOL_LIST COMP_EQ? LeftParen resource_pool_list RightParen + | ZONE_LIST COMP_EQ? LeftParen zone_list RightParen + | charset_key COMP_EQ? charset_name + | read_only_or_write + | COMMENT COMP_EQ? STRING_VALUE + | default_tablegroup + | ENABLE_EXTENDED_ROWID COMP_EQ? BOOL_VALUE + ; + +zone_list + : STRING_VALUE (opt_comma STRING_VALUE)* + ; + +resource_pool_list + : STRING_VALUE (Comma STRING_VALUE)* + ; + +alter_tenant_stmt + : ALTER TENANT relation_name SET? (tenant_option | (opt_tenant_option_list Comma tenant_option))? (VARIABLES sys_var_and_val_list)? + | ALTER TENANT relation_name lock_spec_mysql57 + ; + +drop_tenant_stmt + : DROP TENANT relation_name + ; + +create_restore_point_stmt + : CREATE RESTORE POINT relation_name + ; + +drop_restore_point_stmt + : DROP RESTORE POINT relation_name + ; + +database_key + : DATABASE + | SCHEMA + ; + +database_factor + : relation_name + ; + +database_option_list + : database_option+ + ; + +charset_key + : CHARSET + | CHARACTER SET + ; + +database_option + : DEFAULT? charset_key COMP_EQ? charset_name + | REPLICA_NUM COMP_EQ? INTNUM + | PRIMARY_ZONE COMP_EQ? primary_zone_name + | read_only_or_write + | default_tablegroup + | DATABASE_ID COMP_EQ? INTNUM + ; + +read_only_or_write + : READ ONLY + | READ WRITE + ; + +alter_database_stmt + : ALTER database_key database_name? SET? database_option_list + ; + +database_name + : NAME_OB + ; + +load_data_stmt + : load_data_with_opt_hint (LOCAL | REMOTE_OSS)? INFILE STRING_VALUE (IGNORE | REPLACE)? INTO TABLE relation_factor (CHARACTER SET charset_name_or_default)? field_opt line_opt (IGNORE INTNUM lines_or_rows)? ((LeftParen RightParen) | (LeftParen field_or_vars_list RightParen))? (SET load_set_list)? load_data_extended_option_list? + | load_data_with_opt_hint (LOCAL | REMOTE_OSS)? INFILE STRING_VALUE (IGNORE | REPLACE)? INTO TABLE relation_factor use_partition (CHARACTER SET charset_name_or_default)? field_opt line_opt (IGNORE INTNUM lines_or_rows)? ((LeftParen RightParen) | (LeftParen field_or_vars_list RightParen))? (SET load_set_list)? load_data_extended_option_list? + ; + +load_data_with_opt_hint + : LOAD DATA + | LOAD_DATA_HINT_BEGIN hint_list_with_end + ; + +lines_or_rows + : LINES + | ROWS + ; + +field_or_vars_list + : field_or_vars (Comma field_or_vars)* + ; + +field_or_vars + : column_definition_ref + | USER_VARIABLE + ; + +load_set_list + : load_set_element (Comma load_set_element)* + ; + +load_set_element + : column_definition_ref COMP_EQ expr_or_default + ; + +load_data_extended_option_list + : load_data_extended_option load_data_extended_option_list? + ; + +load_data_extended_option + : LOGFILE COMP_EQ? STRING_VALUE + | REJECT LIMIT COMP_EQ? INTNUM + | BADFILE COMP_EQ? STRING_VALUE + ; + +create_synonym_stmt + : CREATE (OR REPLACE)? PUBLIC? SYNONYM synonym_name FOR synonym_object (USER_VARIABLE opt_reverse_link_flag)? + | CREATE (OR REPLACE)? PUBLIC? SYNONYM database_factor Dot synonym_name FOR synonym_object (USER_VARIABLE opt_reverse_link_flag)? + | CREATE (OR REPLACE)? PUBLIC? SYNONYM synonym_name FOR database_factor Dot synonym_object (USER_VARIABLE opt_reverse_link_flag)? + | CREATE (OR REPLACE)? PUBLIC? SYNONYM database_factor Dot synonym_name FOR database_factor Dot synonym_object (USER_VARIABLE opt_reverse_link_flag)? + ; + +synonym_name + : NAME_OB + | unreserved_keyword + ; + +synonym_object + : NAME_OB + | unreserved_keyword + ; + +drop_synonym_stmt + : DROP PUBLIC? SYNONYM synonym_name FORCE? + | DROP PUBLIC? SYNONYM database_factor Dot synonym_name FORCE? + ; + +temporary_option + : GLOBAL TEMPORARY + | EXTERNAL + | empty + ; + +on_commit_option + : ON COMMIT (DELETE|PRESERVE) ROWS + | empty + ; + +create_directory_stmt + : CREATE (OR REPLACE)? DIRECTORY directory_name AS directory_path + ; + +directory_name + : NAME_OB + | unreserved_keyword + ; + +directory_path + : STRING_VALUE + ; + +drop_directory_stmt + : DROP DIRECTORY directory_name + ; + +create_keystore_stmt + : ADMINISTER KEY MANAGEMENT CREATE KEYSTORE keystore_name IDENTIFIED BY password + ; + +alter_keystore_stmt + : ADMINISTER KEY MANAGEMENT ALTER KEYSTORE PASSWORD IDENTIFIED BY password SET password + | ADMINISTER KEY MANAGEMENT SET ((KEY|KEYSTORE CLOSE)|KEYSTORE OPEN) IDENTIFIED BY password + ; + +create_table_stmt + : CREATE temporary_option TABLE relation_factor LeftParen table_element_list RightParen table_option_list? opt_partition_option on_commit_option + | CREATE temporary_option TABLE relation_factor LeftParen table_element_list RightParen table_option_list? opt_partition_option on_commit_option AS subquery order_by? fetch_next_clause? + | CREATE temporary_option TABLE relation_factor table_option_list opt_partition_option on_commit_option AS subquery order_by? fetch_next_clause? + | CREATE temporary_option TABLE relation_factor partition_option on_commit_option AS subquery order_by? fetch_next_clause? + | CREATE temporary_option TABLE relation_factor on_commit_option AS subquery order_by? fetch_next_clause? + ; + +table_element_list + : table_element (Comma table_element)* + ; + +table_element + : column_definition + | out_of_line_constraint + | out_of_line_index + ; + +column_definition + : column_definition_ref data_type visibility_option? opt_column_attribute_list? + | column_definition_ref data_type visibility_option? (GENERATED opt_generated_option_list)? AS LeftParen bit_expr RightParen VIRTUAL? opt_generated_column_attribute_list? + | column_definition_ref visibility_option? (GENERATED opt_generated_option_list)? AS LeftParen bit_expr RightParen VIRTUAL? opt_generated_column_attribute_list? + | column_definition_ref data_type visibility_option? (GENERATED opt_generated_option_list)? AS opt_identity_attribute sequence_option_list? opt_column_attribute_list? + | column_definition_ref visibility_option? opt_column_attribute_list? + | column_definition_ref visibility_option? (GENERATED opt_generated_option_list)? AS opt_identity_attribute sequence_option_list? opt_column_attribute_list? + ; + +column_definition_opt_datatype + : column_definition_ref opt_column_attribute_list? + | column_definition_ref visibility_option opt_column_attribute_list? + | column_definition_ref data_type visibility_option? opt_column_attribute_list? + | column_definition_ref visibility_option? (GENERATED opt_generated_option_list)? AS LeftParen bit_expr RightParen VIRTUAL? opt_generated_column_attribute_list? + | column_definition_ref data_type visibility_option? (GENERATED opt_generated_option_list)? AS LeftParen bit_expr RightParen VIRTUAL? opt_generated_column_attribute_list? + | column_definition_ref data_type visibility_option? (GENERATED opt_generated_option_list)? AS opt_identity_attribute sequence_option_list? opt_column_attribute_list? + ; + +out_of_line_index + : INDEX index_using_algorithm? LeftParen sort_column_list RightParen opt_index_options? + | INDEX index_name index_using_algorithm? LeftParen sort_column_list RightParen opt_index_options? + ; + +out_of_line_constraint + : constraint_and_name? out_of_line_unique_index + | constraint_and_name? out_of_line_primary_index[true] + | constraint_and_name? FOREIGN KEY LeftParen column_name_list RightParen references_clause constraint_state + | constraint_and_name? CHECK LeftParen expr RightParen constraint_state + ; + +out_of_line_primary_index[boolean using_idx_flag] + : PRIMARY KEY LeftParen column_name_list RightParen out_of_line_index_state[$using_idx_flag]? + ; + +out_of_line_unique_index + : UNIQUE LeftParen sort_column_list RightParen out_of_line_index_state[true]? + ; + +out_of_line_index_state[boolean using_idx_flag] + : {!$using_idx_flag}? opt_index_options + | {$using_idx_flag}? USING INDEX opt_index_options? + ; + +constraint_state + : (RELY | NORELY)? ((USING INDEX opt_index_options) | (USING INDEX))? enable_option? (VALIDATE | NOVALIDATE)? + ; + +enable_option + : ENABLE + | DISABLE + ; + +references_clause + : REFERENCES normal_relation_factor LeftParen column_name_list RightParen reference_option? + | REFERENCES normal_relation_factor reference_option? + ; + +reference_option + : ON DELETE reference_action + ; + +reference_action + : CASCADE + | SET NULLX + ; + +opt_generated_option_list + : ALWAYS + | BY DEFAULT opt_generated_identity_option + | empty + ; + +opt_generated_identity_option + : ON NULLX + | empty + ; + +opt_generated_column_attribute_list + : opt_generated_column_attribute_list generated_column_attribute + | generated_column_attribute + ; + +generated_column_attribute + : constraint_and_name? NOT NULLX constraint_state + | constraint_and_name? NULLX + | UNIQUE KEY + | PRIMARY? KEY + | UNIQUE + | COMMENT STRING_VALUE + | ID INTNUM + | constraint_and_name? CHECK LeftParen expr RightParen constraint_state + ; + +opt_identity_attribute + : IDENTITY + ; + +column_definition_ref + : (relation_name Dot)? column_name + | relation_name Dot relation_name Dot column_name + ; + +column_definition_list + : column_definition (Comma column_definition)* + ; + +column_definition_opt_datatype_list + : column_definition_opt_datatype (Comma column_definition_opt_datatype)* + ; + +column_name_list + : column_name (Comma column_name)* + ; + +zero_suffix_intnum + : INTNUM + | DECIMAL_VAL + ; + +cast_data_type + : binary_type_i + | character_type_i[true] + | rowid_type_i + | datetime_type_i + | timestamp_type_i + | int_type_i + | number_type_i + | float_type_i + | double_type_i + | interval_type_i + | treat_data_type + ; + +treat_data_type + : JSON + | udt_type_i + ; + +udt_type_i + : (database_name Dot)? type_name + ; + +type_name + : NAME_OB + ; + +data_type + : int_type_i + | float_type_i + | double_type_i + | number_type_i + | timestamp_type_i + | datetime_type_i + | character_type_i[false] (charset_key charset_name)? collation? + | binary_type_i + | STRING_VALUE + | JSON + | XMLTYPE + | interval_type_i + | rowid_type_i + ; + +binary_type_i + : RAW LeftParen zero_suffix_intnum RightParen + | BLOB + ; + +float_type_i + : FLOAT (data_type_precision | (LeftParen RightParen))? + | REAL data_type_precision? + ; + +character_type_i [boolean in_cast_data_type] + : CHARACTER string_length_i? BINARY? + | CHAR string_length_i? BINARY? + | varchar_type_i string_length_i BINARY? + | {$in_cast_data_type}? varchar_type_i + | NVARCHAR2 string_length_i + | NCHAR string_length_i + | CLOB + ; + +rowid_type_i + : UROWID urowid_length_i? + | ROWID urowid_length_i? + ; + +interval_type_i + : INTERVAL YEAR year_precision=data_type_precision? TO MONTH + | INTERVAL DAY day_precision=data_type_precision? TO SECOND second_precision=data_type_precision? + ; + +number_type_i + : NUMBER number_precision? + | NUMERIC number_precision? + | DECIMAL number_precision? + | DEC number_precision? + ; + +timestamp_type_i + : TIMESTAMP data_type_precision? + | TIMESTAMP data_type_precision? WITH TIME ZONE + | TIMESTAMP data_type_precision? WITH LOCAL TIME ZONE + ; + +data_type_precision + : LeftParen precision_int_num RightParen + | LeftParen precision_decimal_num RightParen + ; + +int_type_i + : SMALLINT + | INT + | INTEGER + ; + +varchar_type_i + : VARCHAR + | VARCHAR2 + ; + +double_type_i + : BINARY_DOUBLE + | BINARY_FLOAT + ; + +datetime_type_i + : DATE + ; + +number_precision + : LeftParen ((Star|signed_int_num) (Comma signed_int_num)?|precision_decimal_num) RightParen + ; + +signed_int_num + : Minus? INTNUM + ; + +precision_int_num + : INTNUM + ; + +precision_decimal_num + : DECIMAL_VAL + ; + +nstring_length_i + : LeftParen zero_suffix_intnum RightParen + ; + +string_length_i + : LeftParen zero_suffix_intnum (CHARACTER | CHAR | BYTE)? RightParen + ; + +urowid_length_i + : LeftParen INTNUM RightParen + ; + +collation_name + : NAME_OB + | STRING_VALUE + ; + +trans_param_name + : STRING_VALUE + ; + +trans_param_value + : STRING_VALUE + | INTNUM + ; + +charset_name + : NAME_OB + | STRING_VALUE + | BINARY + ; + +charset_name_or_default + : charset_name + | DEFAULT + ; + +collation + : COLLATE collation_name + ; + +opt_column_attribute_list + : opt_column_attribute_list column_attribute + | column_attribute + ; + +column_attribute + : constraint_and_name? NOT NULLX constraint_state + | constraint_and_name? NULLX + | DEFAULT bit_expr + | ORIG_DEFAULT now_or_signed_literal + | constraint_and_name? PRIMARY KEY + | constraint_and_name? UNIQUE + | ID INTNUM + | constraint_and_name? CHECK LeftParen expr RightParen constraint_state + | constraint_and_name? references_clause constraint_state + ; + +now_or_signed_literal + : cur_timestamp_func_params + | signed_literal_params + ; + +cur_timestamp_func_params + : LeftParen cur_timestamp_func_params RightParen + | cur_timestamp_func + ; + +signed_literal_params + : LeftParen signed_literal_params RightParen + | signed_literal + ; + +signed_literal + : literal + | Plus number_literal + | Minus number_literal + ; + +opt_comma + : Comma? + ; + +table_option_list_space_seperated + : table_option table_option_list_space_seperated? + ; + +table_option_list + : table_option_list_space_seperated + | table_option Comma table_option_list + ; + +primary_zone_name + : DEFAULT + | RANDOM + | relation_name_or_string + ; + +locality_name + : STRING_VALUE + | DEFAULT + ; + +table_option + : SORTKEY LeftParen column_name_list RightParen + | parallel_option + | TABLE_MODE COMP_EQ? STRING_VALUE + | DUPLICATE_SCOPE COMP_EQ? STRING_VALUE + | LOCALITY COMP_EQ? locality_name FORCE? + | EXPIRE_INFO COMP_EQ? LeftParen bit_expr RightParen + | PROGRESSIVE_MERGE_NUM COMP_EQ? INTNUM + | BLOCK_SIZE COMP_EQ? INTNUM + | TABLE_ID COMP_EQ? INTNUM + | REPLICA_NUM COMP_EQ? INTNUM + | compress_option + | USE_BLOOM_FILTER COMP_EQ? BOOL_VALUE + | PRIMARY_ZONE COMP_EQ? primary_zone_name + | TABLEGROUP COMP_EQ? relation_name_or_string + | read_only_or_write + | ENGINE_ COMP_EQ? relation_name_or_string + | TABLET_SIZE COMP_EQ? INTNUM + | MAX_USED_PART_ID COMP_EQ? INTNUM + | ENABLE ROW MOVEMENT + | DISABLE ROW MOVEMENT + | ENABLE_EXTENDED_ROWID COMP_EQ? BOOL_VALUE + | physical_attributes_option + | LOCATION COMP_EQ? STRING_VALUE + | FORMAT COMP_EQ? LeftParen external_file_format_list RightParen + | PATTERN COMP_EQ? STRING_VALUE + ; + +parallel_option + : PARALLEL COMP_EQ? INTNUM + | NOPARALLEL + ; + +storage_options_list + : storage_option+ + ; + +storage_option + : INITIAL_ size_option + | NEXT size_option + | MINEXTENTS INTNUM + | MAXEXTENTS int_or_unlimited + ; + +size_option + : INTNUM unit_of_size? + ; + +int_or_unlimited + : INTNUM + | UNLIMITED + ; + +unit_of_size + : K_SIZE + | M_SIZE + | G_SIZE + | T_SIZE + | P_SIZE + | E_SIZE + ; + +relation_name_or_string + : relation_name + | STRING_VALUE + ; + +opt_equal_mark + : COMP_EQ? + ; + +partition_option_inner + : hash_partition_option + | range_partition_option + | list_partition_option + ; + +opt_partition_option + : partition_option + | opt_column_partition_option + | auto_partition_option + ; + +auto_partition_option + : auto_partition_type PARTITION SIZE partition_size PARTITIONS AUTO + ; + +partition_size + : conf_const + | AUTO + ; + +auto_partition_type + : auto_range_type + ; + +auto_range_type + : PARTITION BY RANGE LeftParen column_name_list? RightParen + ; + +partition_option + : partition_option_inner + ; + +hash_partition_option + : PARTITION BY HASH LeftParen column_name_list RightParen subpartition_option? (PARTITIONS INTNUM)? (LeftParen hash_partition_list RightParen)? hash_partition_attributes_option_list? + ; + +hash_partition_attributes_option_list + : TABLESPACE tablespace + | compress_option + | TABLESPACE tablespace compress_option + ; + +list_partition_option + : PARTITION BY LIST LeftParen column_name_list RightParen subpartition_option? opt_list_partition_list + ; + +range_partition_option + : PARTITION BY RANGE LeftParen column_name_list RightParen interval_option? subpartition_option? opt_range_partition_list + ; + +interval_option + : INTERVAL LeftParen bit_expr RightParen + ; + +subpartition_option + : subpartition_template_option + | subpartition_individual_option + ; + +subpartition_template_option + : SUBPARTITION BY HASH LeftParen column_name_list RightParen SUBPARTITION TEMPLATE opt_hash_subpartition_list + | SUBPARTITION BY RANGE LeftParen column_name_list RightParen SUBPARTITION TEMPLATE opt_range_subpartition_list + | SUBPARTITION BY LIST LeftParen column_name_list RightParen SUBPARTITION TEMPLATE opt_list_subpartition_list + ; + +subpartition_individual_option + : SUBPARTITION BY HASH LeftParen column_name_list RightParen (SUBPARTITIONS hash_subpartition_quantity)? + | SUBPARTITION BY RANGE LeftParen column_name_list RightParen + | SUBPARTITION BY LIST LeftParen column_name_list RightParen + ; + +opt_column_partition_option + : column_partition_option? + ; + +column_partition_option + : PARTITION BY COLUMN? LeftParen vertical_column_name (Comma aux_column_list)? RightParen + ; + +aux_column_list + : vertical_column_name (Comma vertical_column_name)* + ; + +vertical_column_name + : column_name + | LeftParen column_name_list RightParen + ; + +hash_partition_list + : hash_partition_element (Comma hash_partition_element)* + ; + +hash_partition_element + : PARTITION relation_factor? (ID INTNUM)? hash_partition_attributes_option_list? subpartition_list? + ; + +opt_range_partition_list + : LeftParen range_partition_list RightParen + ; + +range_partition_list + : range_partition_element (Comma range_partition_element)* + ; + +partition_attributes_option_list + : physical_attributes_option_list + | compress_option + | physical_attributes_option_list compress_option + ; + +range_partition_element + : PARTITION relation_factor VALUES LESS THAN range_partition_expr (ID INTNUM)? partition_attributes_option_list? subpartition_list? + | PARTITION VALUES LESS THAN range_partition_expr (ID INTNUM)? partition_attributes_option_list? subpartition_list? + ; + +opt_list_partition_list + : LeftParen list_partition_list RightParen + ; + +list_partition_list + : list_partition_element (Comma list_partition_element)* + ; + +list_partition_element + : PARTITION relation_factor VALUES list_partition_expr (ID INTNUM)? partition_attributes_option_list? subpartition_list? + | PARTITION VALUES list_partition_expr (ID INTNUM)? partition_attributes_option_list? subpartition_list? + ; + +subpartition_list + : opt_hash_subpartition_list + | opt_range_subpartition_list + | opt_list_subpartition_list + ; + +opt_hash_subpartition_list + : LeftParen hash_subpartition_list RightParen + ; + +hash_subpartition_list + : hash_subpartition_element (Comma hash_subpartition_element)* + ; + +hash_subpartition_element + : SUBPARTITION relation_factor physical_attributes_option_list? + ; + +opt_range_subpartition_list + : LeftParen range_subpartition_list RightParen + ; + +range_subpartition_list + : range_subpartition_element (Comma range_subpartition_element)* + ; + +range_subpartition_element + : SUBPARTITION relation_factor VALUES LESS THAN range_partition_expr physical_attributes_option_list? + ; + +opt_list_subpartition_list + : LeftParen list_subpartition_list RightParen + ; + +list_subpartition_list + : list_subpartition_element (Comma list_subpartition_element)* + ; + +list_subpartition_element + : SUBPARTITION relation_factor VALUES list_partition_expr physical_attributes_option_list? + ; + +list_partition_expr + : LeftParen (DEFAULT|list_expr) RightParen + ; + +list_expr + : bit_expr (Comma bit_expr)* + ; + +physical_attributes_option_list + : physical_attributes_option+ + ; + +physical_attributes_option + : PCTFREE COMP_EQ? INTNUM + | PCTUSED INTNUM + | INITRANS INTNUM + | MAXTRANS INTNUM + | STORAGE LeftParen storage_options_list RightParen + | TABLESPACE tablespace + ; + +opt_special_partition_list + : LeftParen special_partition_list RightParen + ; + +special_partition_list + : special_partition_define (Comma special_partition_define)* + ; + +special_partition_define + : PARTITION (ID INTNUM)? + | PARTITION relation_factor (ID INTNUM)? + ; + +range_partition_expr + : LeftParen range_expr_list RightParen + ; + +range_expr_list + : range_expr (Comma range_expr)* + ; + +range_expr + : Plus? literal + | Minus literal + | access_func_expr + | MAXVALUE + ; + +hash_subpartition_quantity + : INTNUM + ; + +int_or_decimal + : INTNUM + | DECIMAL_VAL + ; + +tg_hash_partition_option + : PARTITION BY HASH tg_subpartition_option (PARTITIONS INTNUM)? + | PARTITION BY HASH INTNUM tg_subpartition_option (PARTITIONS INTNUM)? + ; + +tg_range_partition_option + : PARTITION BY RANGE COLUMNS? INTNUM tg_subpartition_option opt_range_partition_list + ; + +tg_list_partition_option + : PARTITION BY LIST COLUMNS? INTNUM tg_subpartition_option opt_list_partition_list + ; + +tg_subpartition_option + : tg_subpartition_template_option + | tg_subpartition_individual_option + ; + +tg_subpartition_template_option + : SUBPARTITION BY RANGE COLUMNS? INTNUM SUBPARTITION TEMPLATE opt_range_subpartition_list + | SUBPARTITION BY HASH SUBPARTITION TEMPLATE hash_subpartition_quantity + | SUBPARTITION BY HASH INTNUM SUBPARTITION TEMPLATE hash_subpartition_quantity + | SUBPARTITION BY LIST COLUMNS? INTNUM SUBPARTITION TEMPLATE opt_list_subpartition_list + | empty + ; + +tg_subpartition_individual_option + : SUBPARTITION BY HASH (SUBPARTITIONS hash_subpartition_quantity)? + | SUBPARTITION BY HASH INTNUM (SUBPARTITIONS hash_subpartition_quantity)? + | SUBPARTITION BY RANGE COLUMNS? INTNUM + | SUBPARTITION BY LIST COLUMNS? INTNUM + ; + +opt_alter_compress_option + : MOVE compress_option + ; + +compress_option + : NOCOMPRESS + | COMPRESS (BASIC | (FOR OLTP) | (FOR QUERY opt_compress_level) | (FOR ARCHIVE opt_compress_level))? + ; + +opt_compress_level + : (LOW | HIGH)? + ; + +external_file_format_list + : external_file_format (opt_comma external_file_format)* + ; + +external_file_format + : format_key=(ENCODING|TYPE) COMP_EQ STRING_VALUE + | format_key=(ESCAPE|FIELD_OPTIONALLY_ENCLOSED_BY|FIELD_DELIMITER|LINE_DELIMITER) COMP_EQ bit_expr + | format_key=SKIP_HEADER COMP_EQ INTNUM + | format_key=(SKIP_BLANK_LINES|TRIM_SPACE|EMPTY_FIELD_AS_NULL) COMP_EQ BOOL_VALUE + | format_key=NULL_IF_EXETERNAL COMP_EQ LeftParen expr_list RightParen + ; + +create_tablegroup_stmt + : CREATE TABLEGROUP relation_name tablegroup_option_list? (tg_hash_partition_option | tg_range_partition_option | tg_list_partition_option)? + ; + +drop_tablegroup_stmt + : DROP TABLEGROUP relation_name + ; + +alter_tablegroup_stmt + : ALTER TABLEGROUP relation_name ADD TABLE? table_list + | ALTER TABLEGROUP relation_name ((alter_partition_option|alter_tablegroup_actions)|tg_modify_partition_info) + ; + +tablegroup_option_list_space_seperated + : tablegroup_option tablegroup_option_list_space_seperated? + ; + +tablegroup_option_list + : tablegroup_option_list_space_seperated + | tablegroup_option Comma tablegroup_option_list + ; + +tablegroup_option + : LOCALITY COMP_EQ? locality_name FORCE? + | PRIMARY_ZONE COMP_EQ? primary_zone_name + | TABLEGROUP_ID COMP_EQ? INTNUM + | BINDING COMP_EQ? BOOL_VALUE + | SHARDING COMP_EQ? STRING_VALUE + | MAX_USED_PART_ID COMP_EQ? INTNUM + ; + +alter_tablegroup_actions + : alter_tablegroup_action (Comma alter_tablegroup_action)* + ; + +alter_tablegroup_action + : SET? tablegroup_option_list_space_seperated + ; + +default_tablegroup + : DEFAULT_TABLEGROUP COMP_EQ? relation_name + | DEFAULT_TABLEGROUP COMP_EQ? NULLX + ; + +create_view_stmt + : CREATE (OR REPLACE)? ((NO FORCE) | FORCE)? VIEW view_name (LeftParen alias_name_list RightParen)? (TABLE_ID COMP_EQ INTNUM)? AS view_subquery view_with_opt + ; + +view_subquery + : subquery order_by? fetch_next_clause? + ; + +view_with_opt + : WITH READ ONLY + | with_check_option + | empty + ; + +with_check_option + : WITH CHECK OPTION + ; + +view_name + : relation_factor + ; + +create_index_stmt + : CREATE UNIQUE? INDEX normal_relation_factor index_using_algorithm? ON relation_factor LeftParen sort_column_list RightParen opt_index_options? opt_partition_option + ; + +index_name + : relation_name + ; + +constraint_and_name + : CONSTRAINT constraint_name + ; + +constraint_name + : relation_name + ; + +sort_column_list + : sort_column_key (Comma sort_column_key)* + ; + +sort_column_key + : index_expr opt_asc_desc (ID INTNUM)? + ; + +index_expr + : bit_expr + ; + +opt_index_options + : index_option+ + ; + +index_option + : GLOBAL + | LOCAL + | BLOCK_SIZE COMP_EQ? INTNUM + | COMMENT STRING_VALUE + | STORING LeftParen column_name_list RightParen + | WITH ROWID + | WITH PARSER STRING_VALUE + | index_using_algorithm + | visibility_option + | DATA_TABLE_ID COMP_EQ? INTNUM + | INDEX_TABLE_ID COMP_EQ? INTNUM + | MAX_USED_PART_ID COMP_EQ? INTNUM + | physical_attributes_option + | REVERSE + | parallel_option + ; + +index_using_algorithm + : USING BTREE + | USING HASH + ; + +drop_table_stmt + : DROP TABLE relation_factor (CASCADE CONSTRAINTS)? PURGE? + ; + +table_or_tables + : TABLE + | TABLES + ; + +drop_view_stmt + : DROP MATERIALIZED? VIEW relation_factor (CASCADE CONSTRAINTS)? + ; + +table_list + : relation_factor (Comma relation_factor)* + ; + +drop_index_stmt + : DROP INDEX relation_name (Dot relation_name)? + ; + +insert_stmt + : insert_with_opt_hint single_table_insert + | insert_with_opt_hint multi_table_insert + ; + +opt_simple_expression + : empty + | LeftParen simple_expr RightParen + ; + +into_err_log_caluse + : empty + | INTO relation_factor + ; + +reject_limit + : empty + | REJECT LIMIT (INTNUM|UNLIMITED) + ; + +single_table_insert + : INTO insert_table_clause NOLOGGING? LeftParen column_list RightParen values_clause returning_log_error_clause? + | INTO insert_table_clause NOLOGGING? LeftParen RightParen values_clause returning_log_error_clause? + | INTO insert_table_clause NOLOGGING? values_clause returning_log_error_clause? + ; + +multi_table_insert + : ALL insert_table_clause_list subquery order_by? fetch_next_clause? + | conditional_insert_clause subquery order_by? fetch_next_clause? + ; + +insert_table_clause_list + : insert_single_table_clause+ + ; + +insert_single_table_clause + : INTO dml_table_name + | INTO dml_table_name LeftParen column_list RightParen + | INTO dml_table_name VALUES LeftParen insert_vals RightParen + | INTO dml_table_name LeftParen column_list RightParen VALUES LeftParen insert_vals RightParen + ; + +conditional_insert_clause + : (ALL | FIRST)? condition_insert_clause_list (ELSE insert_table_clause_list)? + ; + +condition_insert_clause_list + : condition_insert_clause+ + ; + +condition_insert_clause + : WHEN expr THEN insert_table_clause_list + ; + +values_clause + : VALUES insert_vals_list + | VALUES obj_access_ref_normal + | subquery order_by? fetch_next_clause? + ; + +opt_into_clause + : into_clause? + ; + +returning_exprs + : projection (Comma projection)* + ; + +insert_with_opt_hint + : INSERT + | INSERT_HINT_BEGIN hint_list_with_end + ; + +column_list + : column_definition_ref (Comma column_definition_ref)* + ; + +insert_vals_list + : LeftParen insert_vals RightParen + | insert_vals_list Comma LeftParen insert_vals RightParen + ; + +insert_vals + : expr_or_default (Comma expr_or_default)* + ; + +expr_or_default + : bit_expr + | DEFAULT + ; + +merge_with_opt_hint + : MERGE + | MERGE_HINT_BEGIN hint_list_with_end + ; + +merge_stmt + : merge_with_opt_hint INTO source_relation_factor USING source_relation_factor ON LeftParen expr RightParen merge_update_clause? merge_insert_clause + | merge_with_opt_hint INTO source_relation_factor USING source_relation_factor ON LeftParen expr RightParen merge_insert_clause? merge_update_clause + ; + +merge_update_clause + : WHEN MATCHED THEN UPDATE SET update_asgn_list ((WHERE expr) | (WHERE HINT_VALUE expr))? (DELETE WHERE expr)? + ; + +merge_insert_clause + : WHEN NOT MATCHED THEN INSERT (LeftParen column_list RightParen)? VALUES LeftParen insert_vals RightParen ((WHERE expr) | (WHERE HINT_VALUE expr))? + ; + +source_relation_factor + : relation_factor relation_name? + | select_with_parens relation_name? + | TABLE LeftParen simple_expr RightParen relation_name? + | dual_table relation_name? + ; + +select_stmt + : subquery fetch_next_clause? + | subquery for_update + | subquery fetch_next for_update + | subquery order_by fetch_next_clause? + | subquery order_by fetch_next_clause? for_update + | subquery for_update order_by + ; + +subquery + : select_no_parens + | select_with_parens + | with_select + ; + +select_with_parens + : LeftParen (select_no_parens|with_select) order_by? fetch_next_clause? RightParen + | LeftParen select_with_parens RightParen + ; + +select_no_parens + : select_clause + | select_clause_set + ; + +select_clause + : simple_select + | select_with_hierarchical_query + ; + +select_clause_set + : select_clause_set set_type select_clause_set_right + | select_clause_set_left set_type select_clause_set_right + ; + +select_clause_set_right + : simple_select + | select_with_hierarchical_query + | select_with_parens + ; + +select_clause_set_left + : select_clause_set_right + ; + +select_with_opt_hint + : SELECT + | SELECT_HINT_BEGIN hint_list_with_end + ; + +update_with_opt_hint + : UPDATE + | UPDATE_HINT_BEGIN hint_list_with_end + ; + +delete_with_opt_hint + : DELETE + | DELETE_HINT_BEGIN hint_list_with_end + ; + +simple_select + : select_with_opt_hint query_expression_option_list? select_expr_list into_opt FROM from_list ((WHERE expr) | (WHERE HINT_VALUE expr))? ((GROUP BY groupby_clause) | (HAVING expr) | (GROUP BY groupby_clause HAVING expr) | (HAVING expr GROUP BY groupby_clause))? + ; + +select_with_hierarchical_query + : select_with_opt_hint query_expression_option_list? select_expr_list into_opt FROM from_list ((WHERE expr) | (WHERE HINT_VALUE expr))? start_with connect_by ((GROUP BY groupby_clause) | (HAVING expr) | (GROUP BY groupby_clause HAVING expr) | (HAVING expr GROUP BY groupby_clause))? + | select_with_opt_hint query_expression_option_list? select_expr_list into_opt FROM from_list ((WHERE expr) | (WHERE HINT_VALUE expr))? connect_by start_with? ((GROUP BY groupby_clause) | (HAVING expr) | (GROUP BY groupby_clause HAVING expr) | (HAVING expr GROUP BY groupby_clause))? + ; + +start_with + : START WITH expr + ; + +fetch_next_clause + : OFFSET bit_expr (ROW|ROWS) fetch_next? + | fetch_next + ; + +fetch_next + : fetch_next_count + | fetch_next_percent + ; + +fetch_next_count + : fetch_next_expr (ONLY|WITH TIES) + ; + +fetch_next_percent + : fetch_next_percent_expr (ONLY|WITH TIES) + ; + +fetch_next_expr + : FETCH (FIRST|NEXT) bit_expr? (ROW|ROWS) + ; + +fetch_next_percent_expr + : FETCH (FIRST|NEXT) bit_expr PERCENT (ROW|ROWS) + ; + +connect_by + : CONNECT BY NOCYCLE? expr + ; + +set_type_union + : UNION + ; + +set_type_other + : INTERSECT + | MINUS + ; + +set_type + : set_type_union set_expression_option + | set_type_other + ; + +set_expression_option + : ALL? + ; + +opt_where + : empty + | WHERE HINT_VALUE? expr + ; + +opt_where_extension + : opt_where + | WHERE CURRENT OF obj_access_ref + ; + +into_clause + : (BULK COLLECT)? INTO into_var_list + ; + +into_opt + : INTO OUTFILE STRING_VALUE (charset_key charset_name)? field_opt line_opt + | INTO DUMPFILE STRING_VALUE + | into_clause + | empty + ; + +into_var_list + : into_var (Comma into_var)* + ; + +into_var + : USER_VARIABLE + | obj_access_ref_normal + | QUESTIONMARK + | {this.is_pl_parse_}? QUESTIONMARK Dot column_name + ; + +field_opt + : columns_or_fields field_term_list + | empty + ; + +field_term_list + : field_term+ + ; + +field_term + : ((OPTIONALLY? ENCLOSED|TERMINATED)|ESCAPED) BY STRING_VALUE + ; + +line_opt + : LINES line_term_list + | empty + ; + +line_term_list + : line_term+ + ; + +line_term + : (STARTING|TERMINATED) BY STRING_VALUE + ; + +hint_list_with_end + : (hint_options | (opt_hint_list Comma hint_options))? HINT_END + ; + +opt_hint_list + : hint_options + | empty + | opt_hint_list Comma hint_options + ; + +hint_options + : hint_option? + ; + +name_list + : relation_name + | name_list relation_name + | name_list Comma relation_name + ; + +hint_option + : NO_REWRITE + | READ_CONSISTENCY LeftParen consistency_level RightParen + | INDEX_HINT LeftParen qb_name_option relation_factor_in_hint NAME_OB RightParen + | QUERY_TIMEOUT LeftParen INTNUM RightParen + | FROZEN_VERSION LeftParen INTNUM RightParen + | TOPK LeftParen INTNUM INTNUM RightParen + | HOTSPOT + | LOG_LEVEL LeftParen NAME_OB RightParen + | LOG_LEVEL LeftParen STRING_VALUE RightParen + | LEADING_HINT LeftParen qb_name_option relation_factor_in_leading_hint_list_entry RightParen + | LEADING_HINT LeftParen qb_name_option relation_factor_in_hint_list RightParen + | ORDERED + | FULL_HINT LeftParen qb_name_option relation_factor_in_hint RightParen + | USE_PLAN_CACHE LeftParen use_plan_cache_type RightParen + | USE_MERGE LeftParen qb_name_option relation_factor_in_use_join_hint_list RightParen + | NO_USE_MERGE LeftParen qb_name_option relation_factor_in_use_join_hint_list RightParen + | USE_HASH LeftParen qb_name_option relation_factor_in_use_join_hint_list RightParen + | NO_USE_HASH LeftParen qb_name_option relation_factor_in_use_join_hint_list RightParen + | USE_NL LeftParen qb_name_option relation_factor_in_use_join_hint_list RightParen + | NO_USE_NL LeftParen qb_name_option relation_factor_in_use_join_hint_list RightParen + | USE_BNL LeftParen qb_name_option relation_factor_in_use_join_hint_list RightParen + | NO_USE_BNL LeftParen qb_name_option relation_factor_in_use_join_hint_list RightParen + | USE_NL_MATERIALIZATION LeftParen qb_name_option relation_factor_in_use_join_hint_list RightParen + | NO_USE_NL_MATERIALIZATION LeftParen qb_name_option relation_factor_in_use_join_hint_list RightParen + | USE_HASH_AGGREGATION + | NO_USE_HASH_AGGREGATION + | MERGE_HINT (LeftParen qb_name_option RightParen)? + | NO_MERGE_HINT (LeftParen qb_name_option RightParen)? + | NO_EXPAND (LeftParen qb_name_option RightParen)? + | USE_CONCAT (LeftParen qb_name_option RightParen)? + | UNNEST (LeftParen qb_name_option RightParen)? + | NO_UNNEST (LeftParen qb_name_option RightParen)? + | PLACE_GROUP_BY (LeftParen qb_name_option RightParen)? + | NO_PLACE_GROUP_BY (LeftParen qb_name_option RightParen)? + | NO_PRED_DEDUCE (LeftParen qb_name_option RightParen)? + | USE_JIT LeftParen use_jit_type RightParen + | NO_USE_JIT + | USE_LATE_MATERIALIZATION + | NO_USE_LATE_MATERIALIZATION + | TRACE_LOG + | STAT LeftParen tracing_num_list RightParen + | TRACING LeftParen tracing_num_list RightParen + | DOP LeftParen INTNUM Comma INTNUM RightParen + | USE_PX + | NO_USE_PX + | TRANS_PARAM LeftParen trans_param_name Comma? trans_param_value RightParen + | PX_JOIN_FILTER LeftParen qb_name_option relation_factor_in_use_join_hint_list RightParen + | NO_PX_JOIN_FILTER LeftParen qb_name_option relation_factor_in_use_join_hint_list RightParen + | FORCE_REFRESH_LOCATION_CACHE + | QB_NAME LeftParen NAME_OB RightParen + | MAX_CONCURRENT LeftParen INTNUM RightParen + | PARALLEL LeftParen INTNUM RightParen + | NO_PARALLEL + | MONITOR + | PQ_DISTRIBUTE LeftParen qb_name_option relation_factor_in_pq_hint Comma? distribute_method (opt_comma distribute_method)? RightParen + | PQ_MAP LeftParen qb_name_option relation_factor_in_hint RightParen + | LOAD_BATCH_SIZE LeftParen INTNUM RightParen + | NAME_OB + | EOF + | PARSER_SYNTAX_ERROR + | ENABLE_PARALLEL_DML + | DISABLE_PARALLEL_DML + | INLINE (LeftParen qb_name_option RightParen)? + | MATERIALIZE (LeftParen qb_name_option RightParen)? + ; + +distribute_method + : ALL + | NONE + | PARTITION + | RANDOM + | RANDOM_LOCAL + | HASH + | BROADCAST + | LOCAL + | BC2HOST + | RANGE + | LIST + ; + +consistency_level + : WEAK + | STRONG + | FROZEN + ; + +use_plan_cache_type + : NONE + | DEFAULT + ; + +use_jit_type + : AUTO + | FORCE + ; + +for_update + : FOR UPDATE (OF column_list)? ((WAIT INTNUM) | NOWAIT | (R_SKIP LOCKED))? + ; + +parameterized_trim + : (BOTH FROM)? bit_expr + | BOTH? bit_expr FROM bit_expr + | (LEADING|TRAILING) bit_expr? FROM bit_expr + ; + +groupby_clause + : groupby_element_list + ; + +groupby_element_list + : groupby_element (Comma groupby_element)* + ; + +groupby_element + : group_by_expr + | rollup_clause + | cube_clause + | grouping_sets_clause + | LeftParen RightParen + ; + +group_by_expr + : bit_expr + ; + +rollup_clause + : ROLLUP LeftParen group_by_expr_list RightParen + ; + +cube_clause + : CUBE LeftParen group_by_expr_list RightParen + ; + +group_by_expr_list + : group_by_expr (Comma group_by_expr)* + ; + +grouping_sets_clause + : GROUPING SETS LeftParen grouping_sets_list RightParen + ; + +grouping_sets_list + : grouping_sets (Comma grouping_sets)* + ; + +grouping_sets + : group_by_expr + | rollup_clause + | cube_clause + | LeftParen RightParen + ; + +order_by + : ORDER SIBLINGS? BY sort_list + ; + +sort_list + : sort_key (Comma sort_key)* + ; + +sort_key + : bit_expr opt_asc_desc + ; + +opt_null_pos + : empty + | NULLS LAST + | NULLS FIRST + ; + +opt_ascending_type + : (ASC | DESC)? + ; + +opt_asc_desc + : opt_ascending_type opt_null_pos + ; + +query_expression_option_list + : query_expression_option query_expression_option? + ; + +query_expression_option + : ALL + | DISTINCT + | UNIQUE + | SQL_CALC_FOUND_ROWS + ; + +projection + : bit_expr (AS column_label|column_label?) + | Star + ; + +opt_as + : AS? + ; + +select_expr_list + : projection (Comma projection)* + ; + +from_list + : table_references + ; + +table_references + : table_reference (Comma table_reference)* + ; + +table_reference + : table_factor + | joined_table + ; + +table_factor + : tbl_name + | table_subquery + | LeftParen table_reference RightParen + | TABLE LeftParen simple_expr RightParen relation_name? + | select_function relation_name? + | json_table_expr (AS? relation_name)? + ; + +select_function + : access_func_expr + | database_factor Dot select_function + ; + +tbl_name + : relation_factor use_partition? (sample_clause seed|sample_clause?) use_flashback? relation_name? + | relation_factor use_partition? (sample_clause seed|sample_clause?) relation_name? transpose_clause + | dual_table relation_name? + ; + +dual_table + : DUAL + ; + +transpose_clause + : PIVOT LeftParen pivot_aggr_clause transpose_for_clause transpose_in_clause RightParen + | PIVOT LeftParen pivot_aggr_clause transpose_for_clause transpose_in_clause RightParen relation_name + | UNPIVOT ((EXCLUDE NULLS) | (INCLUDE NULLS))? LeftParen unpivot_column_clause transpose_for_clause unpivot_in_clause RightParen + | UNPIVOT ((EXCLUDE NULLS) | (INCLUDE NULLS))? LeftParen unpivot_column_clause transpose_for_clause unpivot_in_clause RightParen relation_name + ; + +pivot_aggr_clause + : pivot_single_aggr_clause (Comma pivot_single_aggr_clause)* + ; + +pivot_single_aggr_clause + : aggregate_function (opt_as relation_name)? + | access_func_expr_count (opt_as relation_name)? + ; + +transpose_for_clause + : FOR column_name + | FOR LeftParen column_name_list RightParen + ; + +transpose_in_clause + : IN LeftParen transpose_in_args RightParen + ; + +transpose_in_args + : transpose_in_arg (Comma transpose_in_arg)* + ; + +transpose_in_arg + : bit_expr (AS relation_name|relation_name?) + ; + +unpivot_column_clause + : column_name + | LeftParen column_name_list RightParen + ; + +unpivot_in_clause + : IN LeftParen unpivot_in_args RightParen + ; + +unpivot_in_args + : unpivot_in_arg (Comma unpivot_in_arg)* + ; + +unpivot_in_arg + : unpivot_column_clause (AS bit_expr)? + ; + +dml_table_name + : relation_factor use_partition? + ; + +order_by_fetch_with_check_option + : with_check_option + | fetch_next_clause with_check_option? + | order_by fetch_next_clause? with_check_option? + ; + +insert_table_clause + : dml_table_name relation_name? + | select_with_parens relation_name? + | LeftParen subquery order_by_fetch_with_check_option RightParen relation_name? + ; + +dml_table_clause + : dml_table_name relation_name? + | ONLY LeftParen dml_table_name RightParen relation_name? + | select_with_parens relation_name? + | LeftParen subquery order_by_fetch_with_check_option RightParen relation_name? + ; + +seed + : SEED LeftParen INTNUM RightParen + ; + +sample_percent + : INTNUM + | DECIMAL_VAL + ; + +sample_clause + : SAMPLE BLOCK? (ALL | BASE | INCR)? LeftParen sample_percent RightParen + ; + +table_subquery + : select_with_parens use_flashback? relation_name? transpose_clause? + | LeftParen subquery order_by_fetch_with_check_option RightParen use_flashback? relation_name? transpose_clause? + ; + +use_partition + : (PARTITION|SUBPARTITION) LeftParen name_list RightParen + ; + +use_flashback + : AS OF (SCN|TIMESTAMP) bit_expr + ; + +relation_factor + : normal_relation_factor + | dot_relation_factor + ; + +normal_relation_factor + : relation_name (USER_VARIABLE opt_reverse_link_flag)? + | database_factor Dot relation_name (USER_VARIABLE opt_reverse_link_flag)? + ; + +dot_relation_factor + : Dot relation_name + ; + +opt_reverse_link_flag + : Not? + ; + +relation_factor_in_hint + : normal_relation_factor qb_name_option + ; + +qb_name_option + : At NAME_OB + | empty + ; + +relation_factor_in_hint_list + : relation_factor_in_hint (relation_sep_option relation_factor_in_hint)* + ; + +relation_sep_option + : Comma? + ; + +relation_factor_in_pq_hint + : relation_factor_in_hint + | LeftParen relation_factor_in_hint_list RightParen + ; + +relation_factor_in_leading_hint + : LeftParen relation_factor_in_hint_list RightParen + ; + +tracing_num_list + : INTNUM (relation_sep_option tracing_num_list)? + ; + +relation_factor_in_leading_hint_list + : relation_factor_in_leading_hint + | LeftParen (relation_factor_in_hint_list relation_sep_option)? relation_factor_in_leading_hint_list RightParen + | relation_factor_in_leading_hint_list relation_sep_option (relation_factor_in_hint|relation_factor_in_leading_hint) + | relation_factor_in_leading_hint_list relation_sep_option LeftParen relation_factor_in_hint_list relation_sep_option relation_factor_in_leading_hint_list RightParen + ; + +relation_factor_in_leading_hint_list_entry + : (relation_factor_in_hint_list relation_sep_option)? relation_factor_in_leading_hint_list + ; + +relation_factor_in_use_join_hint_list + : relation_factor_in_hint + | LeftParen relation_factor_in_hint_list RightParen + | relation_factor_in_use_join_hint_list relation_sep_option relation_factor_in_hint + | relation_factor_in_use_join_hint_list relation_sep_option LeftParen relation_factor_in_hint_list RightParen + ; + +join_condition + : ON expr + | USING LeftParen column_list RightParen + ; + +joined_table + : table_factor outer_join_type JOIN table_factor join_condition + | table_factor INNER? JOIN table_factor ON expr + | table_factor INNER? JOIN table_factor USING LeftParen column_list RightParen + | table_factor (CROSS JOIN|natural_join_type) table_factor + | joined_table natural_join_type table_factor + | joined_table CROSS JOIN table_factor + | joined_table outer_join_type JOIN table_factor join_condition + | joined_table JOIN table_factor ON expr + | joined_table INNER JOIN table_factor ON expr + | joined_table JOIN table_factor USING LeftParen column_list RightParen + | joined_table INNER JOIN table_factor USING LeftParen column_list RightParen + ; + +natural_join_type + : NATURAL (INNER|outer_join_type?) JOIN + ; + +outer_join_type + : FULL join_outer + | LEFT join_outer + | RIGHT join_outer + ; + +join_outer + : OUTER? + ; + +with_select + : with_clause (select_no_parens |select_with_parens) + ; + +with_clause + : WITH (RECURSIVE common_table_expr|with_list) + ; + +with_list + : common_table_expr (Comma common_table_expr)* + ; + +common_table_expr + : relation_name (LeftParen alias_name_list RightParen)? AS LeftParen select_no_parens order_by? fetch_next_clause? RightParen ((SEARCH DEPTH FIRST BY sort_list search_set_value) | (SEARCH BREADTH FIRST BY sort_list search_set_value))? (CYCLE alias_name_list SET var_name TO STRING_VALUE DEFAULT STRING_VALUE)? + | relation_name (LeftParen alias_name_list RightParen)? AS LeftParen with_select RightParen ((SEARCH DEPTH FIRST BY sort_list search_set_value) | (SEARCH BREADTH FIRST BY sort_list search_set_value))? (CYCLE alias_name_list SET var_name TO STRING_VALUE DEFAULT STRING_VALUE)? + | relation_name (LeftParen alias_name_list RightParen)? AS LeftParen select_with_parens RightParen ((SEARCH DEPTH FIRST BY sort_list search_set_value) | (SEARCH BREADTH FIRST BY sort_list search_set_value))? (CYCLE alias_name_list SET var_name TO STRING_VALUE DEFAULT STRING_VALUE)? + | relation_name (LeftParen alias_name_list RightParen)? AS LeftParen subquery order_by fetch_next_clause? RightParen ((SEARCH DEPTH FIRST BY sort_list search_set_value) | (SEARCH BREADTH FIRST BY sort_list search_set_value))? (CYCLE alias_name_list SET var_name TO STRING_VALUE DEFAULT STRING_VALUE)? + ; + +alias_name_list + : column_alias_name (Comma column_alias_name)* + ; + +column_alias_name + : column_name + ; + +search_set_value + : SET var_name + ; + +analyze_stmt + : ANALYZE TABLE relation_factor use_partition? analyze_statistics_clause + ; + +analyze_statistics_clause + : COMPUTE STATISTICS opt_analyze_for_clause_list? + | ESTIMATE STATISTICS opt_analyze_for_clause_list? (SAMPLE INTNUM sample_option)? + ; + +opt_analyze_for_clause_list + : opt_analyze_for_clause_element + ; + +opt_analyze_for_clause_element + : FOR TABLE + | for_all + | for_columns + ; + +sample_option + : ROWS + | PERCENTAGE + ; + +create_outline_stmt + : CREATE (OR REPLACE)? OUTLINE relation_name ON explainable_stmt (TO explainable_stmt)? + | CREATE (OR REPLACE)? OUTLINE relation_name ON STRING_VALUE USING HINT_HINT_BEGIN hint_list_with_end + ; + +alter_outline_stmt + : ALTER OUTLINE relation_name ADD explainable_stmt (TO explainable_stmt)? + ; + +drop_outline_stmt + : DROP OUTLINE relation_factor + ; + +explain_stmt + : explain_or_desc relation_factor (STRING_VALUE | column_name)? + | explain_or_desc explainable_stmt + | explain_or_desc PRETTY explainable_stmt + | explain_or_desc PRETTY_COLOR explainable_stmt + | explain_or_desc BASIC explainable_stmt + | explain_or_desc BASIC PRETTY explainable_stmt + | explain_or_desc BASIC PRETTY_COLOR explainable_stmt + | explain_or_desc OUTLINE explainable_stmt + | explain_or_desc OUTLINE PRETTY explainable_stmt + | explain_or_desc OUTLINE PRETTY_COLOR explainable_stmt + | explain_or_desc EXTENDED explainable_stmt + | explain_or_desc EXTENDED PRETTY explainable_stmt + | explain_or_desc EXTENDED PRETTY_COLOR explainable_stmt + | explain_or_desc EXTENDED_NOADDR explainable_stmt + | explain_or_desc EXTENDED_NOADDR PRETTY explainable_stmt + | explain_or_desc EXTENDED_NOADDR PRETTY_COLOR explainable_stmt + | explain_or_desc PLANREGRESS explainable_stmt + | explain_or_desc PLANREGRESS PRETTY explainable_stmt + | explain_or_desc PLANREGRESS PRETTY_COLOR explainable_stmt + | explain_or_desc PARTITIONS explainable_stmt + | explain_or_desc PARTITIONS PRETTY explainable_stmt + | explain_or_desc PARTITIONS PRETTY_COLOR explainable_stmt + | explain_or_desc SET STATEMENT_ID COMP_EQ literal explainable_stmt + | explain_or_desc INTO relation_name explainable_stmt + | explain_or_desc INTO relation_name SET STATEMENT_ID COMP_EQ literal explainable_stmt + | explain_or_desc FORMAT COMP_EQ format_name explainable_stmt + ; + +explain_or_desc + : EXPLAIN + | DESCRIBE + | DESC + ; + +explainable_stmt + : select_stmt + | delete_stmt + | insert_stmt + | merge_stmt + | update_stmt + ; + +format_name + : TRADITIONAL + | JSON + ; + +show_stmt + : SHOW FULL? columns_or_fields from_or_in relation_factor (from_or_in database_factor)? ((LIKE STRING_VALUE) | (LIKE STRING_VALUE ESCAPE STRING_VALUE) | (WHERE expr))? + | SHOW TABLE STATUS (from_or_in database_factor)? ((LIKE STRING_VALUE) | (LIKE STRING_VALUE ESCAPE STRING_VALUE) | (WHERE expr))? + | SHOW (GLOBAL | SESSION | LOCAL)? VARIABLES ((LIKE STRING_VALUE) | (LIKE STRING_VALUE ESCAPE STRING_VALUE) | (WHERE expr))? + | SHOW CREATE TABLE relation_factor + | SHOW CREATE VIEW relation_factor + | SHOW CREATE PROCEDURE relation_factor + | SHOW CREATE FUNCTION relation_factor + | SHOW CREATE TRIGGER relation_factor + | SHOW GRANTS opt_for_grant_user + | SHOW charset_key ((LIKE STRING_VALUE) | (LIKE STRING_VALUE ESCAPE STRING_VALUE) | (WHERE expr))? + | SHOW TRACE ((LIKE STRING_VALUE) | (LIKE STRING_VALUE ESCAPE STRING_VALUE) | (WHERE expr))? + | SHOW TRACE FORMAT COMP_EQ STRING_VALUE ((LIKE STRING_VALUE) | (LIKE STRING_VALUE ESCAPE STRING_VALUE) | (WHERE expr))? + | SHOW COLLATION ((LIKE STRING_VALUE) | (LIKE STRING_VALUE ESCAPE STRING_VALUE) | (WHERE expr))? + | SHOW PARAMETERS ((LIKE STRING_VALUE) | (LIKE STRING_VALUE ESCAPE STRING_VALUE) | (WHERE expr))? tenant_name? + | SHOW FULL? PROCESSLIST + | SHOW TABLEGROUPS ((LIKE STRING_VALUE) | (LIKE STRING_VALUE ESCAPE STRING_VALUE) | (WHERE expr))? + | SHOW PRIVILEGES + | SHOW RECYCLEBIN + | SHOW CREATE TABLEGROUP relation_name + ; + +opt_for_grant_user + : opt_for_user + | FOR CURRENT_USER LeftParen RightParen + ; + +columns_or_fields + : COLUMNS + | FIELDS + ; + +from_or_in + : FROM + | IN + ; + +help_stmt + : HELP STRING_VALUE + | HELP NAME_OB + ; + +create_user_stmt + : CREATE USER user_specification user_profile? (DEFAULT TABLESPACE tablespace)? (PRIMARY_ZONE opt_equal_mark primary_zone_name)? + | CREATE USER user_specification require_specification user_profile? (DEFAULT TABLESPACE tablespace)? (PRIMARY_ZONE opt_equal_mark primary_zone_name)? + ; + +default_role_clause + : role_opt_identified_by_list + | ALL (EXCEPT role_list)? + | NONE + ; + +alter_user_stmt + : ALTER USER user_with_host_name DEFAULT ROLE default_role_clause + | ALTER USER user_with_host_name PRIMARY_ZONE COMP_EQ? primary_zone_name + ; + +alter_user_profile_stmt + : ALTER USER user_with_host_name user_profile + ; + +alter_role_stmt + : ALTER ROLE role (NOT IDENTIFIED)? + | ALTER ROLE role IDENTIFIED BY password + | ALTER ROLE role IDENTIFIED BY VALUES password + ; + +user_specification + : user USER_VARIABLE? IDENTIFIED BY password + | user USER_VARIABLE? IDENTIFIED BY VALUES password + ; + +require_specification + : REQUIRE NONE + | REQUIRE SSL + | REQUIRE X509 + | REQUIRE tls_option_list + ; + +tls_option_list + : tls_option + | tls_option_list tls_option + | tls_option_list AND tls_option + ; + +tls_option + : CIPHER STRING_VALUE + | ISSUER STRING_VALUE + | SUBJECT STRING_VALUE + ; + +grant_user + : user USER_VARIABLE? + | CONNECT + | RESOURCE + | PUBLIC + ; + +grant_user_list + : grant_user (Comma grant_user)* + ; + +user + : STRING_VALUE + | NAME_OB + | unreserved_keyword + ; + +opt_host_name + : USER_VARIABLE? + ; + +user_with_host_name + : user USER_VARIABLE? + | CONNECT + | RESOURCE + | PUBLIC + ; + +password + : INTNUM + | NAME_OB + | unreserved_keyword + ; + +password_str + : STRING_VALUE + ; + +drop_user_stmt + : DROP USER user_list CASCADE? + ; + +user_list + : user_with_host_name (Comma user_with_host_name)* + ; + +set_password_stmt + : SET PASSWORD COMP_EQ password_str + | SET PASSWORD FOR user USER_VARIABLE? COMP_EQ password_str + | SET PASSWORD COMP_EQ PASSWORD LeftParen password RightParen + | SET PASSWORD FOR user USER_VARIABLE? COMP_EQ PASSWORD LeftParen password RightParen + | ALTER USER user_with_host_name IDENTIFIED BY password + | ALTER USER user_with_host_name IDENTIFIED BY VALUES password_str + | ALTER USER user_with_host_name require_specification + ; + +opt_for_user + : FOR user opt_host_name + | empty + ; + +lock_user_stmt + : ALTER USER user_list ACCOUNT lock_spec_mysql57 + ; + +lock_spec_mysql57 + : LOCK + | UNLOCK + ; + +lock_tables_stmt + : LOCK_ table_or_tables lock_table_list + ; + +lock_table_stmt + : LOCK TABLE lock_table_factors IN lock_mode MODE ((WAIT INTNUM) | NOWAIT)? + ; + +lock_table_factors + : lock_table_factor (Comma lock_table_factor)* + ; + +lock_table_factor + : relation_factor use_partition? + ; + +lock_mode + : (ROW|SHARE ROW)? EXCLUSIVE + | ROW? SHARE + | SHARE UPDATE + ; + +unlock_tables_stmt + : UNLOCK TABLES + ; + +lock_table_list + : lock_table (Comma lock_table)* + ; + +create_context_stmt + : CREATE (OR REPLACE)? CONTEXT relation_name USING context_package_name context_option + ; + +context_package_name + : relation_name (Dot relation_name)? + ; + +lock_table + : relation_factor (AS relation_name|relation_name?) lock_type + ; + +context_option + : ACCESSED GLOBALLY + | INITIALIZED GLOBALLY + | INITIALIZED EXTERNALLY + | empty + ; + +lock_type + : READ LOCAL? + | WRITE + | LOW_PRIORITY WRITE + ; + +drop_context_stmt + : DROP CONTEXT relation_name + ; + +create_sequence_stmt + : CREATE SEQUENCE relation_factor sequence_option_list? + ; + +sequence_option_list + : sequence_option+ + ; + +sequence_option + : (INCREMENT BY|MAXVALUE) simple_num + | (MINVALUE|START WITH) simple_num + | NOMAXVALUE + | NOMINVALUE + | CYCLE + | NOCYCLE + | CACHE simple_num + | NOCACHE + | ORDER + | NOORDER + | RESTART + ; + +simple_num + : Plus? INTNUM + | Minus INTNUM + | Plus? DECIMAL_VAL + | Minus DECIMAL_VAL + ; + +drop_sequence_stmt + : DROP SEQUENCE relation_factor + ; + +alter_sequence_stmt + : ALTER SEQUENCE relation_factor sequence_option_list? + ; + +create_dblink_stmt + : CREATE DATABASE LINK dblink CONNECT TO user tenant IDENTIFIED BY password NAME_OB? ip_port (CLUSTER relation_name)? (MY_NAME user tenant IDENTIFIED BY password ip_port opt_cluster)? + ; + +drop_dblink_stmt + : DROP DATABASE LINK dblink + ; + +dblink + : relation_name + ; + +tenant + : USER_VARIABLE + ; + +opt_cluster + : CLUSTER relation_name + | empty + ; + +begin_stmt + : BEGIN HINT_VALUE? WORK? + | START HINT_VALUE? TRANSACTION ((WITH CONSISTENT SNAPSHOT) | transaction_access_mode | (WITH CONSISTENT SNAPSHOT Comma transaction_access_mode) | (transaction_access_mode Comma WITH CONSISTENT SNAPSHOT))? + ; + +commit_stmt + : COMMIT HINT_VALUE? WORK? + | COMMIT HINT_VALUE? WORK? COMMENT STRING_VALUE + ; + +rollback_stmt + : ROLLBACK WORK? + | ROLLBACK HINT_VALUE WORK? + ; + +kill_stmt + : KILL (CONNECTION?|QUERY) bit_expr + ; + +create_role_stmt + : CREATE ROLE role (NOT IDENTIFIED)? + | CREATE ROLE role IDENTIFIED BY password + | CREATE ROLE role IDENTIFIED BY VALUES password + ; + +role_list + : role (Comma role)* + ; + +role + : STRING_VALUE + | NAME_OB + | DBA + | RESOURCE + | CONNECT + | PUBLIC + ; + +drop_role_stmt + : DROP ROLE role + ; + +set_role_stmt + : SET ROLE default_role_clause + ; + +role_opt_identified_by_list + : role_opt_identified_by (Comma role_opt_identified_by)* + ; + +role_opt_identified_by + : role + | role IDENTIFIED BY password + ; + +sys_and_obj_priv + : priv_type + | CREATE ((ANY? TABLE|SESSION)|ANY? (PROCEDURE|VIEW)) + | EXEMPT (ACCESS|REDACTION) POLICY + | SYSDBA + | SYSOPER + | SYSBACKUP + | ((((ALTER|BACKUP)|(DROP|LOCK))|((COMMENT|SELECT)|(INSERT|UPDATE)))|(DELETE|FLASHBACK)) ANY TABLE + | ((ALTER|GRANT) ANY|(CREATE|DROP ANY)) ROLE + | AUDIT ANY + | GRANT ANY OBJECT? PRIVILEGE + | (ALTER|CREATE) ANY INDEX + | DROP ((ANY TYPE|PROFILE)|ANY (INDEX|VIEW)) + | SELECT ANY (DICTIONARY|SEQUENCE) + | (ALTER|DROP) ANY ((PROCEDURE|SEQUENCE)|TRIGGER) + | EXECUTE ANY (PROCEDURE|TYPE) + | CREATE ((ANY? TYPE|PROFILE)|(ANY?|PUBLIC) SYNONYM) + | DROP ((ANY OUTLINE|USER)|(ANY|PUBLIC) SYNONYM) + | CREATE ((ANY OUTLINE|USER)|ANY? (SEQUENCE|TRIGGER)) + | ALTER (ANY TYPE|PROFILE) + | ALTER (ANY OUTLINE|USER) + | UNDER ANY TYPE + | PURGE DBA_RECYCLEBIN + | SYSKM + | CREATE ((ANY DIRECTORY|TABLESPACE)|ANY CONTEXT) + | ALTER TABLESPACE + | DROP ((DATABASE LINK|TABLESPACE)|ANY (CONTEXT|DIRECTORY)) + | SHOW PROCESS + | ALTER SYSTEM + | CREATE PUBLIC? DATABASE LINK + | (ALTER|DEBUG CONNECT) SESSION + | ALTER DATABASE + | DEBUG ANY PROCEDURE + ; + +grant_stmt + : GRANT role_sys_obj_all_col_priv_list ON obj_clause TO grant_user_list (WITH GRANT OPTION)? + | GRANT grant_system_privileges + ; + +grant_system_privileges + : role_sys_obj_all_col_priv_list TO grantee_clause (WITH ADMIN OPTION)? + ; + +grantee_clause + : grant_user_list + | grant_user IDENTIFIED BY password + ; + +role_sys_obj_all_col_priv_list + : role_sys_obj_all_col_priv (Comma role_sys_obj_all_col_priv)* + ; + +role_sys_obj_all_col_priv + : role + | sys_and_obj_priv (LeftParen column_list RightParen)? + | ALL PRIVILEGES? (LeftParen column_list RightParen)? + ; + +priv_type + : ALTER + | CREATE + | DELETE + | DROP + | GRANT OPTION + | INSERT + | UPDATE + | SELECT + | INDEX + | SHOW VIEW + | SHOW DATABASES + | SUPER + | PROCESS + | USAGE + | REFERENCES + | EXECUTE + | FLASHBACK + | READ + | WRITE + | FILE_KEY + | DEBUG + ; + +obj_clause + : Star (Dot Star)? + | relation_name Dot (Star|relation_name) + | DIRECTORY? relation_name + ; + +revoke_stmt + : REVOKE role_sys_obj_all_col_priv_list ON obj_clause FROM user_list + | REVOKE role_sys_obj_all_col_priv_list FROM grantee_clause + ; + +prepare_stmt + : PREPARE stmt_name FROM preparable_stmt + ; + +stmt_name + : column_label + ; + +preparable_stmt + : select_stmt + | insert_stmt + | merge_stmt + | update_stmt + | delete_stmt + ; + +variable_set_stmt + : SET var_and_val_list + ; + +sys_var_and_val_list + : sys_var_and_val (Comma sys_var_and_val)* + ; + +var_and_val_list + : var_and_val (Comma var_and_val)* + ; + +set_expr_or_default + : bit_expr + | ON + | DEFAULT + ; + +var_and_val + : USER_VARIABLE (set_var_op|to_or_eq) bit_expr + | USER_VARIABLE to_or_eq PARSER_SYNTAX_ERROR + | sys_var_and_val + | (SYSTEM_VARIABLE|scope_or_scope_alias column_name) to_or_eq set_expr_or_default + ; + +sys_var_and_val + : obj_access_ref_normal to_or_eq set_expr_or_default + ; + +scope_or_scope_alias + : GLOBAL + | SESSION + | GLOBAL_ALIAS Dot + | SESSION_ALIAS Dot + ; + +to_or_eq + : TO + | COMP_EQ + ; + +set_var_op + : SET_VAR + ; + +argument + : USER_VARIABLE + ; + +execute_stmt + : EXECUTE stmt_name (USING argument_list)? + ; + +argument_list + : argument (Comma argument)* + ; + +deallocate_prepare_stmt + : deallocate_or_drop PREPARE stmt_name + ; + +deallocate_or_drop + : DEALLOCATE + | DROP + ; + +call_stmt + : CALL routine_access_name call_param_list? + ; + +call_param_list + : LeftParen func_param_list? RightParen + ; + +routine_access_name + : var_name Dot (var_name Dot)? routine_name + | routine_name + ; + +routine_name + : NAME_OB + | oracle_unreserved_keyword + | unreserved_keyword_normal + | aggregate_function_keyword + | ADD + | SET + | MODIFY + | DELETE + ; + +truncate_table_stmt + : TRUNCATE TABLE? relation_factor + ; + +rename_table_stmt + : RENAME rename_table_actions + ; + +rename_table_actions + : rename_table_action + ; + +rename_table_action + : relation_factor TO relation_factor + ; + +alter_index_stmt + : ALTER INDEX relation_factor alter_index_actions + ; + +alter_index_actions + : alter_index_action + ; + +alter_index_action + : alter_index_option_oracle + ; + +alter_index_option_oracle + : RENAME TO index_name + | parallel_option + | TABLESPACE tablespace + ; + +alter_table_stmt + : ALTER EXTERNAL? TABLE relation_factor alter_table_actions + ; + +alter_table_actions + : alter_table_action (Comma alter_table_action)* + ; + +alter_table_action + : table_option_list_space_seperated + | SET table_option_list_space_seperated + | SET INTERVAL LeftParen bit_expr? RightParen + | opt_alter_compress_option + | alter_column_option + | alter_tablegroup_option + | RENAME TO? relation_factor + | alter_index_option + | alter_partition_option + | modify_partition_info + | DROP CONSTRAINT constraint_name + | enable_option ALL TRIGGERS + | REFRESH + ; + +alter_partition_option + : DROP (PARTITION|SUBPARTITION) drop_partition_name_list + | DROP (PARTITION|SUBPARTITION) drop_partition_name_list UPDATE GLOBAL INDEXES + | RENAME (PARTITION|SUBPARTITION) relation_name TO relation_name + | add_range_or_list_partition + | SPLIT PARTITION relation_factor split_actions + | TRUNCATE (PARTITION|SUBPARTITION) name_list + | TRUNCATE (PARTITION|SUBPARTITION) name_list UPDATE GLOBAL INDEXES + | MODIFY PARTITION relation_factor add_range_or_list_subpartition + ; + +drop_partition_name_list + : name_list + | LeftParen name_list RightParen + ; + +split_actions + : VALUES LeftParen list_expr RightParen modify_special_partition + | AT LeftParen range_expr_list RightParen modify_special_partition + | split_range_partition + | split_list_partition + ; + +add_range_or_list_partition + : ADD range_partition_list + | ADD list_partition_list + ; + +add_range_or_list_subpartition + : ADD range_subpartition_list + | ADD list_subpartition_list + ; + +modify_special_partition + : INTO opt_special_partition_list + | empty + ; + +split_range_partition + : INTO opt_range_partition_list + | INTO LeftParen range_partition_list Comma special_partition_list RightParen + ; + +split_list_partition + : INTO opt_list_partition_list + | INTO LeftParen list_partition_list Comma special_partition_list RightParen + ; + +modify_partition_info + : MODIFY hash_partition_option + | MODIFY list_partition_option + | MODIFY range_partition_option + ; + +tg_modify_partition_info + : MODIFY tg_hash_partition_option + | MODIFY tg_range_partition_option + | MODIFY tg_list_partition_option + ; + +alter_index_option + : ADD out_of_line_constraint + | ADD LeftParen out_of_line_constraint RightParen + | ALTER INDEX index_name visibility_option + | DROP PRIMARY KEY + | MODIFY out_of_line_primary_index[false] + | MODIFY CONSTRAINT constraint_name (RELY | NORELY)? enable_option? (VALIDATE | NOVALIDATE)? + | enable_option (VALIDATE | NOVALIDATE)? CONSTRAINT constraint_name + ; + +visibility_option + : VISIBLE + | INVISIBLE + ; + +alter_column_option + : ADD column_definition + | ADD LeftParen column_definition_list RightParen + | DROP COLUMN column_definition_ref (CASCADE | RESTRICT)? + | DROP LeftParen column_list RightParen + | RENAME COLUMN column_definition_ref TO column_name + | MODIFY column_definition_opt_datatype + | MODIFY LeftParen column_definition_opt_datatype_list RightParen + ; + +alter_tablegroup_option + : DROP TABLEGROUP + ; + +flashback_stmt + : FLASHBACK TABLE relation_factors TO BEFORE DROP (RENAME TO relation_factor)? + | FLASHBACK database_key database_factor TO BEFORE DROP (RENAME TO database_factor)? + | FLASHBACK TENANT relation_name TO BEFORE DROP (RENAME TO relation_name)? + | FLASHBACK TABLE relation_factors TO TIMESTAMP bit_expr + | FLASHBACK TABLE relation_factors TO SCN bit_expr + ; + +relation_factors + : relation_factor (Comma relation_factor)* + ; + +purge_stmt + : PURGE (((INDEX|TABLE) relation_factor|(RECYCLEBIN|database_key database_factor))|TENANT relation_name) + ; + +shrink_space_stmt + : ALTER TABLE relation_factor SHRINK SPACE + | ALTER TENANT (ALL|relation_name) SHRINK SPACE + ; + +audit_stmt + : audit_or_noaudit audit_clause + ; + +audit_or_noaudit + : AUDIT + | NOAUDIT + ; + +audit_clause + : audit_operation_clause (auditing_by_user_clause|auditing_on_clause?) op_audit_tail_clause + ; + +audit_operation_clause + : audit_all_shortcut_list + | ALL STATEMENTS? + ; + +audit_all_shortcut_list + : audit_all_shortcut (Comma audit_all_shortcut)* + ; + +auditing_on_clause + : ON normal_relation_factor + | ON DEFAULT + ; + +auditing_by_user_clause + : BY user_list + ; + +op_audit_tail_clause + : empty + | audit_by_session_access_option audit_whenever_option? + | audit_whenever_option + ; + +audit_by_session_access_option + : BY ACCESS + ; + +audit_whenever_option + : WHENEVER NOT? SUCCESSFUL + ; + +audit_all_shortcut + : ALTER SYSTEM? + | CLUSTER + | CONTEXT + | PUBLIC? (DATABASE LINK|SYNONYM) + | DIRECTORY + | MATERIALIZED? VIEW + | NOT EXISTS + | OUTLINE + | EXECUTE? PROCEDURE + | PROFILE + | ROLE + | ALTER? SEQUENCE + | SESSION + | SYSTEM? AUDIT + | SYSTEM? GRANT + | ALTER? TABLE + | TABLESPACE + | TRIGGER + | GRANT? TYPE + | USER + | COMMENT TABLE? + | DELETE TABLE? + | GRANT PROCEDURE + | GRANT SEQUENCE + | GRANT TABLE + | INSERT TABLE? + | SELECT SEQUENCE? + | SELECT TABLE + | UPDATE TABLE? + | EXECUTE + | FLASHBACK + | INDEX + | RENAME + ; + +alter_system_stmt + : ALTER SYSTEM BOOTSTRAP (CLUSTER partition_role)? server_info_list (PRIMARY_ROOTSERVICE_LIST STRING_VALUE)? + | ALTER SYSTEM FLUSH cache_type CACHE namespace_expr? flush_scope + | ALTER SYSTEM FLUSH KVCACHE tenant_name? cache_name? + | ALTER SYSTEM FLUSH ILOGCACHE file_id? + | ALTER SYSTEM ALTER PLAN BASELINE tenant_name? sql_id_expr? baseline_id_expr? SET baseline_asgn_factor + | ALTER SYSTEM LOAD PLAN BASELINE FROM PLAN CACHE (TENANT COMP_EQ tenant_name_list)? sql_id_expr? + | ALTER SYSTEM SWITCH REPLICA partition_role partition_id_or_server_or_zone + | ALTER SYSTEM SWITCH ROOTSERVICE partition_role server_or_zone + | ALTER SYSTEM alter_or_change_or_modify REPLICA partition_id_desc ip_port alter_or_change_or_modify change_actions FORCE? + | ALTER SYSTEM DROP REPLICA partition_id_desc ip_port (CREATE_TIMESTAMP opt_equal_mark INTNUM)? zone_desc? FORCE? + | ALTER SYSTEM migrate_action REPLICA partition_id_desc SOURCE COMP_EQ? STRING_VALUE DESTINATION COMP_EQ? STRING_VALUE FORCE? + | ALTER SYSTEM REPORT REPLICA server_or_zone? + | ALTER SYSTEM RECYCLE REPLICA server_or_zone? + | ALTER SYSTEM START MERGE zone_desc + | ALTER SYSTEM suspend_or_resume MERGE tenant_list_tuple_v2? + | ALTER SYSTEM CLEAR MERGE ERROR_P tenant_list_tuple_v2? + | ALTER SYSTEM CANCEL cancel_task_type TASK STRING_VALUE + | ALTER SYSTEM MAJOR FREEZE tenant_list_tuple_v2? + | ALTER SYSTEM CHECKPOINT + | ALTER SYSTEM MINOR FREEZE tenant_list_tuple? (SERVER opt_equal_mark LeftParen server_list RightParen)? zone_desc? + | ALTER SYSTEM ARCHIVELOG (TENANT opt_equal_mark tenant_name_list)? (DESCRIPTION opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM NOARCHIVELOG (TENANT opt_equal_mark tenant_name_list)? (DESCRIPTION opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM BACKUP DATABASE (TO opt_equal_mark STRING_VALUE)? (DESCRIPTION opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM BACKUP INCREMENTAL DATABASE (TO opt_equal_mark STRING_VALUE)? (DESCRIPTION opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM BACKUP DATABASE (TO opt_equal_mark STRING_VALUE)? PLUS ARCHIVELOG (DESCRIPTION opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM BACKUP INCREMENTAL DATABASE (TO opt_equal_mark STRING_VALUE)? PLUS ARCHIVELOG (DESCRIPTION opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM BACKUP KEY (TO opt_equal_mark STRING_VALUE)? (ENCRYPTED BY STRING_VALUE)? + | ALTER SYSTEM CANCEL BACKUP (TENANT opt_equal_mark tenant_name_list)? + | SET ENCRYPTION ON IDENTIFIED BY STRING_VALUE ONLY + | ALTER SYSTEM CANCEL DELETE BACKUP (TENANT opt_equal_mark tenant_name_list)? (DESCRIPTION opt_equal_mark STRING_VALUE)? + | ALTER SYSTEM ADD DELETE BACKUP policy_name (RECOVERY_WINDOW opt_equal_mark STRING_VALUE)? (REDUNDANCY opt_equal_mark INTNUM)? (BACKUP_COPIES opt_equal_mark INTNUM)? (TENANT opt_equal_mark tenant_name_list)? + | ALTER SYSTEM DROP DELETE BACKUP policy_name (TENANT opt_equal_mark tenant_name_list)? + | ALTER SYSTEM CLEAR ROOTTABLE tenant_name? + | ALTER SYSTEM server_action SERVER server_list zone_desc? + | ALTER SYSTEM ADD ZONE relation_name_or_string add_or_alter_zone_options + | ALTER SYSTEM zone_action ZONE relation_name_or_string + | ALTER SYSTEM alter_or_change_or_modify ZONE relation_name_or_string SET? add_or_alter_zone_options + | ALTER SYSTEM REFRESH SCHEMA server_or_zone? + | ALTER SYSTEM SET_TP alter_system_settp_actions + | ALTER SYSTEM CLEAR LOCATION CACHE server_or_zone? + | ALTER SYSTEM REMOVE BALANCE TASK (TENANT COMP_EQ tenant_name_list)? (ZONE COMP_EQ zone_list)? (TYPE opt_equal_mark balance_task_type)? + | ALTER SYSTEM RELOAD GTS + | ALTER SYSTEM RELOAD UNIT + | ALTER SYSTEM RELOAD SERVER + | ALTER SYSTEM RELOAD ZONE + | ALTER SYSTEM MIGRATE UNIT COMP_EQ? INTNUM DESTINATION COMP_EQ? STRING_VALUE + | ALTER SYSTEM CANCEL MIGRATE UNIT INTNUM + | ALTER SYSTEM UPGRADE VIRTUAL SCHEMA + | ALTER SYSTEM RUN JOB STRING_VALUE server_or_zone? + | ALTER SYSTEM upgrade_action UPGRADE + | ALTER SYSTEM REFRESH TIME_ZONE_INFO + | ALTER SYSTEM ENABLE SQL THROTTLE (FOR PRIORITY COMP_LE INTNUM)? opt_sql_throttle_using_cond + | ALTER SYSTEM DISABLE SQL THROTTLE + | ALTER SYSTEM SET DISK VALID ip_port + | ALTER SYSTEM DROP TABLES IN SESSION INTNUM + | ALTER SYSTEM REFRESH TABLES IN SESSION INTNUM + | ALTER SYSTEM SET alter_system_set_clause_list + | ALTER SYSTEM KILL SESSION bit_expr IMMEDIATE + | ALTER SYSTEM KILL SESSION bit_expr + ; + +opt_sql_throttle_using_cond + : USING sql_throttle_one_or_more_metrics + ; + +sql_throttle_one_or_more_metrics + : sql_throttle_metric sql_throttle_one_or_more_metrics? + ; + +sql_throttle_metric + : ((CPU|RT)|(NETWORK|QUEUE_TIME)) COMP_EQ int_or_decimal + | (IO|LOGICAL_READS) COMP_EQ INTNUM + ; + +alter_system_set_clause_list + : alter_system_set_clause+ + ; + +alter_system_set_clause + : set_system_parameter_clause + ; + +set_system_parameter_clause + : var_name COMP_EQ bit_expr + ; + +cache_type + : ALL + | LOCATION + | CLOG + | ILOG + | COLUMN_STAT + | BLOCK_INDEX + | BLOCK + | ROW + | BLOOM_FILTER + | SCHEMA + | PLAN + | LIB + ; + +balance_task_type + : AUTO + | MANUAL + | ALL + ; + +tenant_list_tuple + : TENANT COMP_EQ? LeftParen tenant_name_list RightParen + ; + +tenant_list_tuple_v2 + : TENANT COMP_EQ? tenant_name_list + ; + +tenant_name_list + : relation_name_or_string (Comma relation_name_or_string)* + ; + +policy_name + : POLICY COMP_EQ? STRING_VALUE + ; + +flush_scope + : GLOBAL? + ; + +server_info_list + : server_info (Comma server_info)* + ; + +server_info + : REGION COMP_EQ? relation_name_or_string ZONE COMP_EQ? relation_name_or_string SERVER COMP_EQ? STRING_VALUE + | ZONE COMP_EQ? relation_name_or_string SERVER COMP_EQ? STRING_VALUE + ; + +server_action + : ADD + | CANCEL? DELETE + | START + | FORCE? STOP + ; + +server_list + : STRING_VALUE (Comma STRING_VALUE)* + ; + +zone_action + : DELETE + | START + | FORCE? STOP + ; + +ip_port + : SERVER COMP_EQ? STRING_VALUE + | HOST STRING_VALUE + ; + +zone_desc + : ZONE COMP_EQ? relation_name_or_string + ; + +server_or_zone + : ip_port + | zone_desc + ; + +add_or_alter_zone_option + : REGION COMP_EQ? relation_name_or_string + | IDC COMP_EQ? relation_name_or_string + | ZONE_TYPE COMP_EQ? relation_name_or_string + ; + +add_or_alter_zone_options + : add_or_alter_zone_option + | empty + | add_or_alter_zone_options Comma add_or_alter_zone_option + ; + +alter_or_change_or_modify + : ALTER + | CHANGE + | MODIFY + ; + +partition_id_desc + : PARTITION_ID COMP_EQ? STRING_VALUE + ; + +partition_id_or_server_or_zone + : partition_id_desc ip_port + | ip_port tenant_name? + | zone_desc tenant_name? + ; + +migrate_action + : MOVE + | COPY + ; + +change_actions + : change_action change_actions? + ; + +change_action + : replica_type + | memstore_percent + ; + +replica_type + : REPLICA_TYPE COMP_EQ? STRING_VALUE + ; + +memstore_percent + : MEMSTORE_PERCENT COMP_EQ? INTNUM + ; + +suspend_or_resume + : SUSPEND + | RESUME + ; + +baseline_id_expr + : BASELINE_ID COMP_EQ? INTNUM + ; + +sql_id_expr + : SQL_ID COMP_EQ? STRING_VALUE + ; + +baseline_asgn_factor + : column_name COMP_EQ literal + ; + +tenant_name + : TENANT COMP_EQ? relation_name_or_string + ; + +namespace_expr + : NAMESPACE COMP_EQ? STRING_VALUE + ; + +cache_name + : CACHE COMP_EQ? relation_name_or_string + ; + +file_id + : FILE_ID COMP_EQ? INTNUM + ; + +cancel_task_type + : PARTITION MIGRATION + | empty + ; + +alter_system_settp_actions + : settp_option + | empty + | alter_system_settp_actions Comma settp_option + ; + +settp_option + : TP_NO COMP_EQ? INTNUM + | TP_NAME COMP_EQ? relation_name_or_string + | OCCUR COMP_EQ? INTNUM + | FREQUENCY COMP_EQ? INTNUM + | ERROR_CODE COMP_EQ? INTNUM + | MATCH COMP_EQ? INTNUM + ; + +partition_role + : LEADER + | FOLLOWER + ; + +upgrade_action + : BEGIN + | END + ; + +alter_session_stmt + : ALTER SESSION SET CURRENT_SCHEMA COMP_EQ current_schema + | ALTER SESSION SET ISOLATION_LEVEL COMP_EQ session_isolation_level + | ALTER SESSION SET alter_session_set_clause + | ALTER SESSION FORCE var_name_of_forced_module PARALLEL INTNUM + | ALTER SESSION switch_option var_name_of_module + ; + +var_name_of_forced_module + : PARALLEL DML + | PARALLEL QUERY + | PARALLEL DDL + ; + +var_name_of_module + : PARALLEL DML + | PARALLEL QUERY + | PARALLEL DDL + ; + +switch_option + : ENABLE + | DISABLE + ; + +session_isolation_level + : isolation_level + ; + +alter_session_set_clause + : set_system_parameter_clause_list + ; + +set_system_parameter_clause_list + : set_system_parameter_clause+ + ; + +current_schema + : relation_name + ; + +set_comment_stmt + : COMMENT ON TABLE normal_relation_factor IS STRING_VALUE + | COMMENT ON COLUMN column_definition_ref IS STRING_VALUE + ; + +create_tablespace_stmt + : CREATE TABLESPACE tablespace permanent_tablespace + ; + +drop_tablespace_stmt + : DROP TABLESPACE tablespace + ; + +tablespace + : NAME_OB + ; + +alter_tablespace_stmt + : ALTER TABLESPACE tablespace alter_tablespace_actions + ; + +alter_tablespace_actions + : alter_tablespace_action (Comma alter_tablespace_action)? + ; + +alter_tablespace_action + : permanent_tablespace_option + ; + +permanent_tablespace + : permanent_tablespace_options? + ; + +permanent_tablespace_options + : permanent_tablespace_option (Comma permanent_tablespace_option)* + ; + +permanent_tablespace_option + : ENCRYPTION USING STRING_VALUE + ; + +create_profile_stmt + : CREATE PROFILE profile_name LIMIT password_parameters + ; + +alter_profile_stmt + : ALTER PROFILE profile_name LIMIT password_parameters + ; + +drop_profile_stmt + : DROP PROFILE profile_name + ; + +profile_name + : NAME_OB + | unreserved_keyword + | DEFAULT + ; + +password_parameters + : password_parameter+ + ; + +password_parameter + : password_parameter_type password_parameter_value + ; + +verify_function_name + : relation_name + | NULLX + ; + +password_parameter_value + : number_literal + | verify_function_name + | DEFAULT + ; + +password_parameter_type + : FAILED_LOGIN_ATTEMPTS + | PASSWORD_LOCK_TIME + | PASSWORD_VERIFY_FUNCTION + | PASSWORD_LIFE_TIME + | PASSWORD_GRACE_TIME + ; + +user_profile + : PROFILE profile_name + ; + +method_opt + : method_list + ; + +method_list + : method+ + ; + +method + : for_all + | for_columns + ; + +for_all + : FOR ALL (INDEXED | HIDDEN_)? COLUMNS size_clause? + ; + +size_clause + : SIZE AUTO + | SIZE REPEAT + | SIZE SKEWONLY + | SIZE number_literal + ; + +for_columns + : FOR COLUMNS for_columns_list? + ; + +for_columns_list + : for_columns_item + | for_columns_list for_columns_item + | for_columns_list Comma for_columns_item + ; + +for_columns_item + : column_clause size_clause? + | size_clause + ; + +column_clause + : column_name + | extension + ; + +extension + : LeftParen column_name_list RightParen + ; + +set_names_stmt + : SET NAMES charset_name_or_default collation? + ; + +set_charset_stmt + : SET charset_key charset_name_or_default + ; + +set_transaction_stmt + : SET ((GLOBAL?|SESSION)|LOCAL) TRANSACTION transaction_characteristics + ; + +transaction_characteristics + : transaction_access_mode + | (transaction_access_mode Comma)? ISOLATION LEVEL isolation_level + | ISOLATION LEVEL isolation_level Comma transaction_access_mode + ; + +transaction_access_mode + : READ ONLY + | READ WRITE + ; + +isolation_level + : READ UNCOMMITTED + | READ COMMITTED + | REPEATABLE READ + | SERIALIZABLE + ; + +switchover_tenant_stmt + : ALTER SYSTEM switchover_clause VERIFY? + ; + +switchover_clause + : ACTIVATE STANDBY tenant_name? + | SWITCHOVER TO PRIMARY tenant_name? + | SWITCHOVER TO STANDBY tenant_name? + ; + +recover_tenant_stmt + : ALTER SYSTEM RECOVER STANDBY tenant_name? recover_point_clause + ; + +recover_point_clause + : ((UNTIL TIME opt_equal_mark STRING_VALUE) | (UNTIL SCN opt_equal_mark INTNUM))? + | UNTIL UNLIMITED + | CANCEL + ; + +create_savepoint_stmt + : SAVEPOINT var_name + ; + +rollback_savepoint_stmt + : ROLLBACK WORK? TO var_name + | ROLLBACK TO SAVEPOINT var_name + ; + +var_name + : NAME_OB + | oracle_unreserved_keyword + | unreserved_keyword_normal + | aggregate_function_keyword + ; + +column_name + : NAME_OB + | unreserved_keyword + | ROWID + ; + +relation_name + : NAME_OB + | unreserved_keyword + ; + +exists_function_name + : EXISTS + ; + +function_name + : NAME_OB + | oracle_unreserved_keyword + | unreserved_keyword_normal + | oracle_pl_non_reserved_words + | PRIOR + | RANDOM + ; + +column_label + : NAME_OB + | unreserved_keyword + ; + +keystore_name + : NAME_OB + | unreserved_keyword + ; + +date_unit + : YEAR + | MONTH + | DAY + | HOUR + | MINUTE + | SECOND + ; + +timezone_unit + : TIMEZONE_HOUR + | TIMEZONE_MINUTE + | TIMEZONE_REGION + | TIMEZONE_ABBR + ; + +date_unit_for_extract + : date_unit + | timezone_unit + ; + +json_mergepatch_expr + : JSON_MERGEPATCH LeftParen bit_expr Comma bit_expr js_mp_return_clause? opt_json_mergepatch json_mergepatch_on_error? RightParen + ; + +json_mergepatch_on_error + : (ERROR_P | NULLX) ON ERROR_P + ; + +opt_json_mergepatch + : ASCII? PRETTY? TRUNCATE? + | PRETTY ASCII TRUNCATE? + | TRUNCATE ASCII? PRETTY + | TRUNCATE PRETTY? ASCII + ; + +js_mp_return_clause + : RETURNING js_return_type + ; + +json_array_expr + : JSON_ARRAY LeftParen json_array_content? RightParen + | JSON LeftBracket json_array_content RightBracket + ; + +json_array_content + : js_array_eles json_array_on_null? js_array_return_clause? STRICT? + ; + +json_array_on_null + : (ABSENT | NULLX) ON NULLX + ; + +js_array_eles + : js_array_ele (Comma js_array_ele)* + ; + +js_array_ele + : bit_expr (FORMAT JSON)? + ; + +js_array_return_clause + : RETURNING js_return_type + ; + +json_value_expr + : JSON_VALUE LeftParen js_doc_expr Comma js_literal opt_js_value_returning_type TRUNCATE? ASCII? json_value_on_opt? RightParen + ; + +json_value_on_opt + : json_value_on_empty + | json_value_on_error + | json_value_on_empty json_value_on_error + | json_value_on_error json_value_on_empty + | opt_on_mismatchs + | json_value_on_empty opt_on_mismatchs + | json_value_on_error opt_on_mismatchs + | json_value_on_empty json_value_on_error opt_on_mismatchs + | json_value_on_error json_value_on_empty opt_on_mismatchs + ; + +js_doc_expr + : bit_expr (FORMAT JSON)? + ; + +opt_js_value_returning_type + : RETURNING (NCHAR nstring_length_i|js_value_return_type) + | RETURNING NVARCHAR2 + | RETURNING CHAR string_length_i? BINARY? + | RETURNING RAW + | js_return_default_type + ; + +json_value_on_empty + : json_value_on_empty_response + ; + +json_value_on_empty_response + : (DEFAULT signed_literal|json_value_on_response) ON EMPTY + ; + +json_value_on_error + : json_value_on_error_response + ; + +json_value_on_error_response + : (DEFAULT signed_literal|json_value_on_response) ON ERROR_P + ; + +opt_on_mismatchs + : opt_on_mismatch+ + ; + +opt_on_mismatch + : (IGNORE|json_value_on_response) ON MISMATCH + | (IGNORE|json_value_on_response) ON MISMATCH LeftParen mismatch_type_list RightParen + ; + +json_value_on_response + : ERROR_P + | NULLX + ; + +mismatch_type_list + : mismatch_type (Comma mismatch_type)* + ; + +mismatch_type + : MISSING DATA + | EXTRA DATA + | TYPE ERROR_P + | empty + ; + +json_exists_expr + : JSON_EXISTS LeftParen js_doc_expr Comma literal opt_json_exist? RightParen + ; + +opt_json_exist + : PASSING passing_elements opt_json_exists_on_error_on_empty? + | opt_json_exists_on_error_on_empty + ; + +passing_elements + : passing_context (Comma passing_context)* + ; + +passing_context + : bit_expr AS sql_var_name + ; + +sql_var_name + : NAME_OB + ; + +opt_json_exists_on_error_on_empty + : json_exists_on_error json_exists_on_empty? + | json_exists_on_empty + ; + +json_exists_on_error + : json_exists_response_type ON ERROR_P + ; + +json_exists_on_empty + : json_exists_response_type ON EMPTY + ; + +json_exists_response_type + : BOOL_VALUE + | ERROR_P + ; + +json_query_expr + : JSON_QUERY LeftParen js_doc_expr Comma js_literal (RETURNING js_query_return_type)? TRUNCATE? scalars_opt? PRETTY? ASCII? wrapper_opts? json_query_on_opt? RightParen + ; + +json_query_on_opt + : on_empty_query + | on_error_query + | on_mismatch_query + | on_error_query on_empty_query + | on_empty_query on_error_query + | on_error_query on_mismatch_query + | on_empty_query on_mismatch_query + | on_error_query on_empty_query on_mismatch_query + | on_empty_query on_error_query on_mismatch_query + ; + +wrapper_opts + : WITHOUT WRAPPER + | WITHOUT ARRAY WRAPPER + | WITH WRAPPER + | WITH ARRAY WRAPPER + | WITH UNCONDITIONAL WRAPPER + | WITH CONDITIONAL WRAPPER + | WITH UNCONDITIONAL ARRAY WRAPPER + | WITH CONDITIONAL ARRAY WRAPPER + ; + +js_query_return_type + : js_value_return_type + | BLOB + | JSON + ; + +on_mismatch_query + : (DOT|opt_response_query) ON MISMATCH + ; + +on_error_query + : opt_response_query_on_empty_error ON ERROR_P + ; + +on_empty_query + : opt_response_query_on_empty_error ON EMPTY + ; + +opt_response_query_on_empty_error + : EMPTY ARRAY? + | EMPTY OBJECT + | opt_response_query + ; + +opt_response_query + : ERROR_P + | NULLX + ; + +opt_json_table_on_error_on_empty + : json_table_on_error + | json_table_on_empty + | json_table_on_error json_table_on_empty + ; + +json_table_columns_def_opt + : json_table_columns_def + | LeftParen json_table_columns_def RightParen + ; + +json_table_expr + : JSON_TABLE LeftParen js_doc_expr (Comma literal)? opt_json_table_on_error_on_empty? COLUMNS json_table_columns_def_opt RightParen + ; + +json_table_columns_def + : json_table_column_def (Comma json_table_column_def)* + ; + +json_table_column_def + : json_table_ordinality_column_def + | json_table_exists_column_def + | json_table_query_column_def + | json_table_value_column_def + | json_table_nested_column_def + ; + +json_table_ordinality_column_def + : column_name FOR ORDINALITY + ; + +json_table_column_def_path + : PATH literal + | PATH column_name + | PATH column_name dot_notation_path + ; + +json_table_exists_column_def + : column_name opt_jt_value_type TRUNCATE? EXISTS json_table_column_def_path? ASIS? opt_json_exists_on_error_on_empty? + ; + +json_table_query_column_def + : column_name opt_jt_query_type FORMAT JSON TRUNCATE? scalars_opt? wrapper_opts? json_table_column_def_path? ASIS? json_query_on_opt? + | column_name JSON scalars_opt? wrapper_opts? json_table_column_def_path? ASIS? json_query_on_opt? + ; + +json_table_value_column_def + : column_name opt_jt_value_type TRUNCATE? json_table_column_def_path? ASIS? json_value_on_opt? + ; + +json_table_nested_column_def + : NESTED PATH literal COLUMNS LeftParen json_table_columns_def RightParen + ; + +opt_jt_query_type + : js_return_type + | js_return_default_type + ; + +opt_jt_value_type + : js_value_return_type + | int_type_i + | CHAR string_length_i? BINARY? + | NVARCHAR2 nstring_length_i + | NCHAR nstring_length_i + | js_return_default_type + ; + +js_value_return_type + : datetime_type_i + | timestamp_type_i + | NUMBER number_precision? + | double_type_i + | interval_type_i + | js_return_text_type + ; + +js_return_type + : BLOB + | JSON + | js_return_text_type + ; + +js_return_default_type + : empty + ; + +js_return_text_type + : CLOB + | varchar_type_i string_length_i BINARY? + | varchar_type_i + ; + +json_table_on_response + : ERROR_P + | NULLX + | DEFAULT signed_literal + ; + +json_table_on_error + : json_table_on_response ON ERROR_P + ; + +json_table_on_empty + : json_table_on_response ON EMPTY + ; + +json_object_expr + : JSON_OBJECT LeftParen opt_json_object_content RightParen + | JSON LeftBrace opt_json_object_content RightBrace + ; + +opt_json_object_content + : entry_op? opt_json_object_clause + | entry_op STRICT json_obj_unique_key? + | entry_op? json_obj_unique_key + ; + +opt_json_object_clause + : empty + | (js_on_null json_obj_returning_type?|json_obj_returning_type) STRICT? json_obj_unique_key? + ; + +entry_op + : Star + | entry_set + ; + +entry_set + : entry_obj (Comma entry_obj)* + ; + +entry_obj + : regular_entry_obj (FORMAT JSON)? + ; + +regular_entry_obj + : JSON_OBJECT_VALUE + | KEY? json_obj_literal_expr VALUE json_obj_literal_expr + | (json_obj_literal_key Colon)? json_obj_literal_expr + ; + +json_obj_literal_expr + : bit_expr + ; + +json_obj_literal_key + : complex_string_literal + | DATE_VALUE + | TIMESTAMP_VALUE + | INTNUM + | APPROXNUM + | DECIMAL_VAL + | INTERVAL_VALUE + ; + +js_on_null + : (ABSENT|NULLX) ON NULLX + ; + +json_obj_returning_type + : RETURNING js_return_type + ; + +json_obj_unique_key + : WITH UNIQUE KEYS + ; + +xmlparse_expr + : XMLPARSE LeftParen xml_doc_type xml_text WELLFORMED? RightParen + ; + +xml_text + : bit_expr + ; + +xml_doc_type + : DOCUMENT + | CONTENT + ; + +xml_element_expr + : XMLELEMENT LeftParen xml_tag (Comma xml_attributes_expr)? RightParen + | XMLELEMENT LeftParen xml_tag Comma (xml_attributes_expr Comma)? xml_value_clause RightParen + ; + +xml_tag + : ENTITYESCAPING? element_name + | NOENTITYESCAPING element_name + ; + +evalname_expr + : simple_expr + | evalname_expr CNNOP evalname_expr + ; + +element_name + : NAME? column_name + | EVALNAME evalname_expr + ; + +xml_value_clause + : xml_value (Comma xml_value)* + ; + +xml_value + : bit_expr (AS column_label|column_label?) + ; + +xml_attributes_expr + : XMLATTRIBUTES LeftParen (ENTITYESCAPING?|NOENTITYESCAPING) (NOSCHEMACHECK|SCHEMACHECK?) xml_attributes_value_clause RightParen + ; + +xml_attributes_value_clause + : xml_attributes_value (Comma xml_attributes_value_clause)? + ; + +attributes_name_value + : bit_expr + ; + +xml_attributes_value + : attributes_name_value ((AS EVALNAME bit_expr) | (AS relation_name))? + ; + +xml_extract_expr + : EXTRACT LeftParen bit_expr Comma bit_expr (Comma literal)? RightParen + ; + +xmlcast_expr + : XMLCAST LeftParen bit_expr AS cast_data_type RightParen + ; + +xmlserialize_expr + : XMLSERIALIZE LeftParen xml_doc_type bit_expr (AS cast_data_type)? (ENCODING STRING_VALUE)? (VERSION literal)? ((NO INDENT) | INDENT | (INDENT SIZE COMP_EQ signed_int_num))? ((HIDE DEFAULTS) | (SHOW DEFAULTS))? RightParen + ; + +unreserved_keyword + : oracle_unreserved_keyword + | unreserved_keyword_normal + | aggregate_function_keyword + | STAT + | LOG_LEVEL + | CLIENT_VERSION + ; + +aggregate_function_keyword + : COUNT + | MAX + | MIN + | SUM + | AVG + | APPROX_COUNT_DISTINCT + | APPROX_COUNT_DISTINCT_SYNOPSIS + | APPROX_COUNT_DISTINCT_SYNOPSIS_MERGE + | MEDIAN + | STDDEV + | VARIANCE + | STDDEV_POP + | STDDEV_SAMP + | LISTAGG + | RANK + | DENSE_RANK + | PERCENT_RANK + | ROW_NUMBER + | NTILE + | CUME_DIST + | FIRST_VALUE + | LAST_VALUE + | LEAD + | LAG + | NTH_VALUE + | RATIO_TO_REPORT + | CORR + | COVAR_POP + | COVAR_SAMP + | VAR_POP + | VAR_SAMP + | REGR_SLOPE + | REGR_INTERCEPT + | REGR_COUNT + | REGR_R2 + | REGR_AVGX + | REGR_AVGY + | REGR_SXX + | REGR_SYY + | REGR_SXY + | PERCENTILE_CONT + | PERCENTILE_DISC + | WM_CONCAT + | TOP_K_FRE_HIST + | HYBRID_HIST + ; + +oracle_unreserved_keyword + : ACCESSED + | ADMIN + | AFTER + | ALLOCATE + | ANALYZE + | ARCHIVE + | ARCHIVELOG + | AUTHORIZATION + | BACKUP + | BECOME + | BEFORE + | BEGIN + | BLOCK + | BODY + | CACHE + | CANCEL + | CASCADE + | CHANGE + | CHARACTER + | CHECKPOINT + | CLOSE + | COBOL + | COMMIT + | COMPILE + | CONSTRAINT + | CONSTRAINTS + | CONTENTS + | CONTINUE + | CONTROLFILE + | CURSOR + | CYCLE + | DATABASE + | DATAFILE + | DBA + | DEC + | DECLARE + | DISABLE + | DISMOUNT + | DOP + | DOUBLE + | DUMP + | EACH + | ENABLE + | END + | ESCAPE + | EVENTS + | EXCEPT + | EXCEPTIONS + | EXEC + | EXECUTE + | EXPLAIN + | EXTENT + | EXTERNAL + | EXTERNALLY + | FETCH + | FLUSH + | FORCE + | FOREIGN + | FORTRAN + | FOUND + | FREELIST + | FREELISTS + | FUNCTION + | GLOBALLY + | GO + | GOTO + | GROUPS + | INCLUDING + | INDICATOR + | INITIALIZED + | INITRANS + | INSTANCE + | INT + | KEY + | LANGUAGE + | LAYER + | LINK + | LISTS + | LOGFILE + | MANAGE + | MANUAL + | MAXDATAFILES + | MAXINSTANCES + | MAXLOGFILES + | MAXLOGHISTORY + | MAXLOGMEMBERS + | MAXTRANS + | MAXVALUE + | MINEXTENTS + | MINVALUE + | MODULE + | MOUNT + | NEW + | NEXT + | NOARCHIVELOG + | NOCACHE + | NOCYCLE + | NOMAXVALUE + | NOMINVALUE + | NONE + | NOORDER + | NORESETLOGS + | NOSORT + | NUMERIC + | OFF + | OLD + | ONLY + | OPEN + | OPTIMAL + | OWN + | PACKAGE_KEY + | PARALLEL + | NOPARALLEL + | PCTINCREASE + | PCTUSED + | PLAN + | PLI + | PRECISION + | PRIMARY + | PRIVATE + | PROCEDURE + | PROFILE + | QUOTA + | READ + | REAL + | RECOVER + | REFERENCES + | REFERENCING + | RESETLOGS + | RESTRICTED + | REUSE + | ROLE + | ROLES + | ROLLBACK + | SAVEPOINT + | SCHEMA + | SCN + | SECTION + | SEGMENT + | SEQUENCE + | SHARED + | SNAPSHOT + | SOME + | SORT + | SQL + | SQLCODE + | SQLERROR + | SQLSTATE + | STATEMENT_ID + | STATISTICS + | STOP + | STORAGE + | SWITCH + | SYSTEM + | TABLES + | TABLESPACE + | TEMPORARY + | THREAD + | TIME + | TRACING + | TRANSACTION + | TRIGGERS + | TRUNCATE + | UNDER + | UNLIMITED + | UNTIL + | USE + | USING + | WHEN + | WORK + | WRITE + ; + +unreserved_keyword_normal + : ACCOUNT + | ABSENT + | ACCESSIBLE + | ACTION + | ACTIVE + | ACTIVATE + | ADDDATE + | ADMINISTER + | AGGREGATE + | AGAINST + | ALGORITHM + | ALLOW + | ALWAYS + | ANALYSE + | ARRAY + | ASCII + | ASENSITIVE + | ASIS + | AT + | AUTHORS + | AUTO + | AUTOEXTEND_SIZE + | AVG_ROW_LENGTH + | BACKUP_COPIES + | BADFILE + | BASE + | BASELINE + | BASELINE_ID + | BASIC + | BALANCE + | BINARY + | BINARY_DOUBLE + | BINARY_DOUBLE_INFINITY + | BINARY_DOUBLE_NAN + | BINARY_FLOAT + | BINARY_FLOAT_INFINITY + | BINARY_FLOAT_NAN + | BINDING + | SHARDING + | BINLOG + | BIT + | BLOB + | BLOCK_SIZE + | BLOCK_INDEX + | BLOOM_FILTER + | BOOL + | BOOLEAN + | BOOTSTRAP + | BOTH + | BTREE + | BULK + | BULK_EXCEPTIONS + | BULK_ROWCOUNT + | BYTE + | BREADTH + | CALC_PARTITION_ID + | CALL + | CASCADED + | CAST + | CATALOG_NAME + | CONTENT + | CHAIN + | CHANGED + | CHARSET + | CHAR_CS + | CHECKSUM + | CIPHER + | CLASS_ORIGIN + | CLEAN + | CLEAR + | CLIENT + | CLOB + | CLOG + | CLUSTER_ID + | CLUSTER_NAME + | COALESCE + | CODE + | COLLATE + | COLLATION + | COLLECT + | COLUMN_FORMAT + | COLUMN_NAME + | COLUMN_OUTER_JOIN_SYMBOL + | COLUMN_STAT + | COLUMNS + | COMMITTED + | COMPACT + | COMPLETION + | COMPRESSED + | COMPRESSION + | COMPUTE + | CONCURRENT + | CONDITIONAL + | CONNECTION + | CONNECT_BY_ISCYCLE + | CONNECT_BY_ISLEAF + | CONSISTENT + | CONSISTENT_MODE + | CONSTRAINT_CATALOG + | CONSTRAINT_NAME + | CONSTRAINT_SCHEMA + | CONTAINS + | CONTEXT + | CONTRIBUTORS + | COPY + | CPU + | CREATE_TIMESTAMP + | CROSS + | CUBE + | CURRENT_USER + | CURRENT_SCHEMA + | CURRENT_DATE + | CURRENT_TIMESTAMP + | DATA + | DATABASES + | DATABASE_ID + | DATA_TABLE_ID + | DATE_ADD + | DATE_SUB + | DATETIME + | DAY + | DAY_HOUR + | DAY_MICROSECOND + | DAY_MINUTE + | DAY_SECOND + | DBA_RECYCLEBIN + | DBTIMEZONE + | DEALLOCATE + | DEFAULTS + | DEFAULT_AUTH + | DEFINER + | DELAY + | DELAYED + | DELAY_KEY_WRITE + | DELETING + | DEPTH + | DESCRIPTION + | DES_KEY_FILE + | DESCRIBE + | DESTINATION + | DETERMINISTIC + | DIAGNOSTICS + | DICTIONARY + | DIRECTORY + | DISALLOW + | DISCARD + | DISK + | DML + | DDL + | DISTINCTROW + | DIV + | DO + | DOT + | DOCUMENT + | DUMPFILE + | DUPLICATE + | DUPLICATE_SCOPE + | DYNAMIC + | DEFAULT_TABLEGROUP + | DEBUG + | E_SIZE + | EFFECTIVE + | ELSEIF + | ENCLOSED + | ENCODING + | ENCRYPTED + | ENCRYPTION + | ENDS + | ENGINE_ + | ENGINES + | ENUM + | ERROR_CODE + | ERROR_P + | ERROR_INDEX + | ERRORS + | ESCAPED + | ESTIMATE + | EVENT + | EVERY + | EXCHANGE + | EXCLUDE + | EXEMPT + | EXIT + | EXPANSION + | EXPIRE + | EXPIRE_INFO + | EXPORT + | EXTENDED + | EXTENDED_NOADDR + | EXTENT_SIZE + | EXTRA + | EXTRACT + | EVALNAME + | ENTITYESCAPING + | EXTRACTVALUE + | FAILED_LOGIN_ATTEMPTS + | FAST + | FAULTS + | FIELDS + | FIELD_DELIMITER + | FIELD_OPTIONALLY_ENCLOSED_BY + | SKIP_HEADER + | SKIP_BLANK_LINES + | TRIM_SPACE + | NULL_IF_EXETERNAL + | EMPTY_FIELD_AS_NULL + | FILE_ID + | FILEX + | FINAL_COUNT + | FIRST + | FIXED + | FLASHBACK + | FLOAT4 + | FLOAT8 + | FOLLOWER + | FOLLOWING + | FORMAT + | FREEZE + | FREQUENCY + | FROZEN + | FULL + | G_SIZE + | GENERAL + | GENERATED + | GEOMETRY + | GEOMETRYCOLLECTION + | GET + | GET_FORMAT + | GLOBAL + | GLOBAL_ALIAS + | GRANTS + | GROUP_ID + | GROUPING + | GROUPING_ID + | GTS + | HANDLER + | HASH + | HELP + | HIDE + | HIGH + | HIGH_PRIORITY + | HOUR_MICROSECOND + | HOUR_MINUTE + | HOUR_SECOND + | HOST + | HOSTS + | HOUR + | ID + | IDC + | IDENTITY + | IF + | IFIGNORE + | IGNORE + | IGNORE_SERVER_IDS + | ILOG + | ILOGCACHE + | IMPORT + | INDENT + | INDEXES + | INDEX_TABLE_ID + | INCR + | INCLUDE + | INCREMENTAL + | INFO + | INFILE + | INFINITE_VALUE + | INITIAL_SIZE + | INNER + | INNER_PARSE + | INOUT + | INSENSITIVE + | INSERTING + | INSERT_METHOD + | INSTALL + | INT1 + | INT2 + | INT3 + | INT4 + | INT8 + | INTERVAL + | INVOKER + | IO + | IOPS_WEIGHT + | IO_AFTER_GTIDS + | IO_BEFORE_GTIDS + | IO_THREAD + | IPC + | ISNULL + | ISOLATION + | ISSUER + | ITERATE + | JOB + | JOIN + | JSON + | JSON_ARRAY + | JSON_EMPTY + | JSON_EQUAL + | JSON_TABLE + | JSON_VALUE + | JSON_QUERY + | JSON_EXISTS + | JSON_MERGEPATCH + | JSON_ARRAYAGG + | JSON_OBJECTAGG + | JSON_OBJECT + | K_SIZE + | KEY_BLOCK_SIZE + | KEYS + | KEYSTORE + | KEY_VERSION + | KILL + | KEEP + | KVCACHE + | LAST + | LAX + | LEADER + | LEADING + | LEAVE + | LEAVES + | LEFT + | LESS + | LIMIT + | LINEAR + | LINES + | LINESTRING + | LINE_DELIMITER + | LIST + | LNNVL + | LOAD + | LOCAL + | LOCALITY + | LOCALTIMESTAMP + | LOCK_ + | LOCKED + | LOCKS + | LOGONLY_REPLICA_NUM + | LOG + | LOGS + | LONGBLOB + | LONGTEXT + | LOOP + | LOW + | LOW_PRIORITY + | ISOPEN + | ISOLATION_LEVEL + | M_SIZE + | MAJOR + | MANAGEMENT + | MASTER + | MASTER_AUTO_POSITION + | MASTER_BIND + | MASTER_CONNECT_RETRY + | MASTER_DELAY + | MASTER_HEARTBEAT_PERIOD + | MASTER_HOST + | MASTER_LOG_FILE + | MASTER_LOG_POS + | MASTER_PASSWORD + | MASTER_PORT + | MASTER_RETRY_COUNT + | MASTER_SERVER_ID + | MASTER_SSL + | MASTER_SSL_CA + | MASTER_SSL_CAPATH + | MASTER_SSL_CERT + | MASTER_SSL_CIPHER + | MASTER_SSL_CRL + | MASTER_SSL_CRLPATH + | MASTER_SSL_KEY + | MASTER_SSL_VERIFY_SERVER_CERT + | MASTER_USER + | MATCH + | MATCHED + | MAX_CONNECTIONS_PER_HOUR + | MAX_CPU + | LOG_DISK_SIZE + | MAX_IOPS + | MEMORY_SIZE + | MAX_QUERIES_PER_HOUR + | MAX_ROWS + | MAX_SESSION_NUM + | MAX_SIZE + | MAX_UPDATES_PER_HOUR + | MAX_USED_PART_ID + | MAX_USER_CONNECTIONS + | MEDIUM + | MEDIUMBLOB + | MEDIUMINT + | MEDIUMTEXT + | MEMORY + | MEMSTORE_PERCENT + | MEMTABLE + | MERGE + | MESSAGE_TEXT + | META + | MICROSECOND + | MIDDLEINT + | MIGRATE + | MIGRATION + | MIN_CPU + | MIN_IOPS + | MIN_MEMORY + | MINOR + | MIN_ROWS + | MINUTE + | MINUTE_MICROSECOND + | MINUTE_SECOND + | MISMATCH + | MISSING + | MOD + | MODIFIES + | MONTH + | MOVE + | MOVEMENT + | MULTILINESTRING + | MULTIPOINT + | MULTIPOLYGON + | MULTISET + | MUTEX + | MYSQL_ERRNO + | MY_NAME + | NAME + | NAMES + | NAN_VALUE + | NATIONAL + | NATURAL + | NCHAR + | NCHAR_CS + | NDB + | NDBCLUSTER + | NESTED + | NO + | NOENTITYESCAPING + | NODEGROUP + | NOLOGGING + | NOSCHEMACHECK + | NOW + | NOWAIT + | NO_WAIT + | NO_WRITE_TO_BINLOG + | NULLS + | NVARCHAR + | NVARCHAR2 + | OBJECT + | OCCUR + | ORDINALITY + | OFFSET + | OLD_PASSWORD + | OLD_KEY + | OLTP + | OVER + | ONE + | ONE_SHOT + | OPTIONS + | OPTIMIZE + | OPTIONALLY + | ORA_ROWSCN + | ORIG_DEFAULT + | OUT + | OUTER + | OUTFILE + | OUTLINE + | OWNER + | P_SIZE + | PACK_KEYS + | PAGE + | PARAMETERS + | PARAM_ASSIGN_OPERATOR + | PARSER + | PARTIAL + | PARTITION + | PARTITION_ID + | PARTITIONING + | PARTITIONS + | PASSING + | PASSWORD + | PASSWORD_GRACE_TIME + | PASSWORD_LIFE_TIME + | PASSWORD_LOCK_TIME + | PASSWORD_VERIFY_FUNCTION + | PATH + | PATTERN + | PAUSE + | PERCENTAGE + | PHASE + | PLANREGRESS + | PLUGIN + | PLUGIN_DIR + | PLUGINS + | PLUS + | PIVOT + | POINT + | POLICY + | POLYGON + | POOL + | PORT + | POSITION + | PRECEDING + | PREPARE + | PRESERVE + | PRETTY + | PRETTY_COLOR + | PREV + | PRIMARY_ZONE + | PRIVILEGE + | PROCESS + | PROCESSLIST + | PROFILES + | PROGRESSIVE_MERGE_NUM + | PROXY + | PURGE + | QUARTER + | QUERY + | QUICK + | RANGE + | READ_WRITE + | READS + | READ_ONLY + | REBUILD + | RECOVERY_WINDOW + | RECURSIVE + | RECYCLE + | RECYCLEBIN + | REDACTION + | REDO_BUFFER_SIZE + | REDOFILE + | REDUNDANCY + | REDUNDANT + | REFRESH + | REGEXP_LIKE + | REGION + | REJECT + | RELAY + | RELAYLOG + | RELAY_LOG_FILE + | RELAY_LOG_POS + | RELAY_THREAD + | RELEASE + | RELOAD + | REMOVE + | REORGANIZE + | REPAIR + | REPEAT + | REPEATABLE + | REPLACE + | REPLICA + | REPLICA_NUM + | REPLICA_TYPE + | REPLICATION + | REPORT + | REQUIRE + | RESET + | RESIGNAL + | RESOURCE_POOL_LIST + | RESPECT + | RESTART + | RESTORE + | RESTRICT + | RESUME + | RETURN + | RETURNED_SQLSTATE + | RETURNING + | RETURNS + | REVERSE + | REWRITE_MERGE_VERSION + | REMOTE_OSS + | RLIKE + | RIGHT + | ROLLUP + | ROOT + | ROOTTABLE + | ROOTSERVICE + | ROOTSERVICE_LIST + | ROUTINE + | ROWCOUNT + | ROW_COUNT + | ROW_FORMAT + | RTREE + | RUN + | SAMPLE + | SCALARS + | SCHEDULE + | SCHEMACHECK + | SCHEMAS + | SCHEMA_NAME + | SCOPE + | SEARCH + | SECOND + | SECOND_MICROSECOND + | SECURITY + | SEED + | SENSITIVE + | SEPARATOR + | SERIAL + | SERIALIZABLE + | SERVER + | SERVER_IP + | SERVER_PORT + | SERVER_TYPE + | SESSION_ALIAS + | SESSION_USER + | SESSIONTIMEZONE + | SET_MASTER_CLUSTER + | SET_SLAVE_CLUSTER + | SET_TP + | SETS + | SHRINK + | SHOW + | SHUTDOWN + | SIBLINGS + | SIGNAL + | SIGNED + | SIMPLE + | R_SKIP + | SLAVE + | SLOW + | SOCKET + | SONAME + | SORTKEY + | SOUNDS + | SOURCE + | SPACE + | SPATIAL + | SPECIFIC + | SPFILE + | SPLIT + | SQLEXCEPTION + | SQLWARNING + | SQL_BIG_RESULT + | SQL_CALC_FOUND_ROW + | SQL_SMALL_RESULT + | SQL_AFTER_GTIDS + | SQL_AFTER_MTS_GAPS + | SQL_BEFORE_GTIDS + | SQL_BUFFER_RESULT + | SQL_CACHE + | SQL_ID + | SQL_NO_CACHE + | SQL_THREAD + | SQL_TSI_DAY + | SQL_TSI_HOUR + | SQL_TSI_MINUTE + | SQL_TSI_MONTH + | SQL_TSI_QUARTER + | SQL_TSI_SECOND + | SQL_TSI_WEEK + | SQL_TSI_YEAR + | SSL + | STRAIGHT_JOIN + | STARTING + | STARTS + | STATS_AUTO_RECALC + | STATS_PERSISTENT + | STATS_SAMPLE_PAGES + | STATUS + | STATEMENTS + | STORAGE_FORMAT_VERSION + | STORAGE_FORMAT_WORK_VERSION + | STORED + | STORING + | STRICT + | STRONG + | STANDBY + | SUBCLASS_ORIGIN + | SUBDATE + | SUBJECT + | SUBPARTITION + | SUBPARTITIONS + | SUBSTR + | SUPER + | SUSPEND + | SWAPS + | SWITCHES + | SWITCHOVER + | SYSTEM_USER + | SYSTIMESTAMP + | SYSBACKUP + | SYSDBA + | SYSKM + | SYSOPER + | SYS_CONNECT_BY_PATH + | T_SIZE + | TABLEGROUP + | TABLE_CHECKSUM + | TABLE_MODE + | TABLEGROUPS + | TABLEGROUP_ID + | TABLE_ID + | TABLE_NAME + | TABLET + | TABLET_SIZE + | TABLET_MAX_SIZE + | TASK + | TEMPLATE + | TEMPTABLE + | TENANT + | TERMINATED + | TEXT + | THAN + | TIMESTAMP + | TIMESTAMPADD + | TIMESTAMPDIFF + | TIMEZONE_ABBR + | TIMEZONE_HOUR + | TIMEZONE_MINUTE + | TIMEZONE_REGION + | TIME_ZONE_INFO + | TINYBLOB + | TINYTEXT + | TP_NAME + | TP_NO + | TRACE + | TRADITIONAL + | TRAILING + | TREAT + | TRIM + | TRANSLATE + | TYPE + | TYPENAME + | TYPES + | UNCOMMITTED + | UNCONDITIONAL + | UNDEFINED + | UNDO + | UNDO_BUFFER_SIZE + | UNDOFILE + | UNICODE + | UNKNOWN + | UNINSTALL + | UNIT + | UNIT_GROUP + | UNIT_NUM + | UNLOCK + | UNLOCKED + | UNUSUAL + | UNPIVOT + | UPDATING + | UPDATEXML + | UPGRADE + | UROWID + | USAGE + | USE_BLOOM_FILTER + | USE_FRM + | USER_RESOURCES + | UTC_DATE + | UTC_TIMESTAMP + | UNBOUNDED + | VALID + | VARIABLES + | VALUE + | VERBOSE + | VERSION + | MATERIALIZED + | WAIT + | WARNINGS + | WEEK + | WEIGHT_STRING + | WITHOUT + | WMSYS + | WRAPPER + | X509 + | XA + | XML + | YEAR + | ZONE + | ZONE_LIST + | ZONE_TYPE + | LOCATION + | VARYING + | VIRTUAL + | VISIBLE + | VERIFY + | INVISIBLE + | RELY + | NORELY + | NOVALIDATE + | WITHIN + | WEAK + | WELLFORMED + | WHILE + | XMLAGG + | XMLPARSE + | XOR + | XMLELEMENT + | XMLATTRIBUTES + | XMLSERIALIZE + | XMLTYPE + | YEAR_MONTH + | ZEROFILL + | PERCENT + | TIES + | MEMBER + | SUBMULTISET + | EMPTY + | A_ + | THROTTLE + | PRIORITY + | RT + | NETWORK + | LOGICAL_READS + | QUEUE_TIME + | HIDDEN_ + | INDEXED + | SKEWONLY + | NAMESPACE + | LIB + ; + +empty + : + ; + +forward_expr + : expr EOF + ; + +forward_sql_stmt + : stmt EOF + ; + + diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/OceanBaseMysqlTransformer.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/OceanBaseMysqlTransformer.java new file mode 100644 index 0000000..e117e2c --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/OceanBaseMysqlTransformer.java @@ -0,0 +1,63 @@ +package com.aliyun.fastmodel.transform.oceanbase; + +import com.aliyun.fastmodel.core.tree.BaseStatement; +import com.aliyun.fastmodel.core.tree.Node; +import com.aliyun.fastmodel.transform.api.Transformer; +import com.aliyun.fastmodel.transform.api.builder.BuilderFactory; +import com.aliyun.fastmodel.transform.api.builder.StatementBuilder; +import com.aliyun.fastmodel.transform.api.client.dto.table.Table; +import com.aliyun.fastmodel.transform.api.client.dto.table.TableConfig; +import com.aliyun.fastmodel.transform.api.context.ReverseContext; +import com.aliyun.fastmodel.transform.api.context.TransformContext; +import com.aliyun.fastmodel.transform.api.dialect.Dialect; +import com.aliyun.fastmodel.transform.api.dialect.DialectMeta; +import com.aliyun.fastmodel.transform.api.dialect.DialectName; +import com.aliyun.fastmodel.transform.api.dialect.DialectName.Constants; +import com.aliyun.fastmodel.transform.api.dialect.DialectNode; +import com.aliyun.fastmodel.transform.api.dialect.IVersion; +import com.aliyun.fastmodel.transform.oceanbase.client.converter.OceanBaseMysqlClientConverter; +import com.aliyun.fastmodel.transform.oceanbase.context.OceanBaseContext; +import com.aliyun.fastmodel.transform.oceanbase.parser.OceanBaseMysqlLanguageParser; +import com.google.auto.service.AutoService; + +/** + * OceanBaseTransformer + * + * @author panguanjing + * @date 2024/2/2 + */ +@Dialect(value = Constants.OB_MYSQL) +@AutoService(Transformer.class) +public class OceanBaseMysqlTransformer implements Transformer { + + private final OceanBaseMysqlLanguageParser oceanBaseMysqlLanguageParser = new OceanBaseMysqlLanguageParser(); + + private final OceanBaseMysqlClientConverter oceanBaseMysqlClientConverter = new OceanBaseMysqlClientConverter(); + + @Override + public DialectNode transform(BaseStatement source, TransformContext context) { + DialectMeta dialectMeta = new DialectMeta(DialectName.OB_MYSQL, IVersion.getDefault()); + OceanBaseContext oceanBaseContext = new OceanBaseContext(context); + StatementBuilder builder = BuilderFactory.getInstance().getBuilder(source, dialectMeta, oceanBaseContext); + if (builder == null) { + throw new UnsupportedOperationException( + "UnSupported statement transform with target Dialect, source: " + source.getClass()); + } + return builder.build(source, oceanBaseContext); + } + + @Override + public BaseStatement reverse(DialectNode dialectNode, ReverseContext context) { + return oceanBaseMysqlLanguageParser.parseNode(dialectNode.getNode(), context); + } + + @Override + public Node reverseTable(Table table, ReverseContext context) { + return oceanBaseMysqlClientConverter.covertToNode(table, TableConfig.builder().build()); + } + + @Override + public Table transformTable(Node table, TransformContext context) { + return oceanBaseMysqlClientConverter.convertToTable(table, new OceanBaseContext(context)); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/builder/DefaultBuilder.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/builder/DefaultBuilder.java new file mode 100644 index 0000000..566818d --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/builder/DefaultBuilder.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021. Aliyun.com All right reserved. This software is the + * confidential and proprietary information of Aliyun.com ("Confidential + * Information"). You shall not disclose such Confidential Information and shall + * use it only in accordance with the terms of the license agreement you entered + * into with Aliyun.com. + */ + +package com.aliyun.fastmodel.transform.oceanbase.builder; + +import com.aliyun.fastmodel.core.tree.BaseStatement; +import com.aliyun.fastmodel.transform.api.builder.BuilderAnnotation; +import com.aliyun.fastmodel.transform.api.builder.StatementBuilder; +import com.aliyun.fastmodel.transform.api.dialect.DialectName.Constants; +import com.aliyun.fastmodel.transform.api.dialect.DialectNode; +import com.aliyun.fastmodel.transform.oceanbase.context.OceanBaseContext; +import com.aliyun.fastmodel.transform.oceanbase.format.OceanBaseMysqlOutVisitor; +import com.google.auto.service.AutoService; + +/** + * 默认的builder实现 + * 支持oceanbase mysql的DDL输出 + * + * @author panguanjing + */ +@BuilderAnnotation(dialect = Constants.OB_MYSQL, values = {BaseStatement.class}) +@AutoService(StatementBuilder.class) +public class DefaultBuilder implements StatementBuilder { + + @Override + public DialectNode build(BaseStatement source, OceanBaseContext context) { + OceanBaseMysqlOutVisitor outVisitor = new OceanBaseMysqlOutVisitor(context); + Boolean process = outVisitor.process(source, 0); + StringBuilder builder = outVisitor.getBuilder(); + return new DialectNode(builder.toString(), process); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/OceanBaseMysqlPropertyConverter.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/OceanBaseMysqlPropertyConverter.java new file mode 100644 index 0000000..1293a99 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/OceanBaseMysqlPropertyConverter.java @@ -0,0 +1,32 @@ +package com.aliyun.fastmodel.transform.oceanbase.client; + +import java.util.Map; +import java.util.function.Function; + +import com.aliyun.fastmodel.transform.api.client.converter.BasePropertyConverter; +import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; +import com.google.common.collect.Maps; + +/** + * oceanbase property converter + * + * @author panguanjing + * @date 2024/1/21 + */ +public class OceanBaseMysqlPropertyConverter extends BasePropertyConverter { + + private static Map> functionMap = Maps.newHashMap(); + + public OceanBaseMysqlPropertyConverter() { + init(); + } + + private void init() { + + } + + @Override + protected Map> getFunctionMap() { + return functionMap; + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/converter/OceanBaseMysqlClientConverter.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/converter/OceanBaseMysqlClientConverter.java new file mode 100644 index 0000000..948494b --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/converter/OceanBaseMysqlClientConverter.java @@ -0,0 +1,700 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.converter; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import com.aliyun.fastmodel.common.utils.StripUtils; +import com.aliyun.fastmodel.core.parser.LanguageParser; +import com.aliyun.fastmodel.core.tree.Node; +import com.aliyun.fastmodel.core.tree.Property; +import com.aliyun.fastmodel.core.tree.QualifiedName; +import com.aliyun.fastmodel.core.tree.datatype.IDataTypeName; +import com.aliyun.fastmodel.core.tree.expr.BaseExpression; +import com.aliyun.fastmodel.core.tree.expr.Identifier; +import com.aliyun.fastmodel.core.tree.expr.literal.LongLiteral; +import com.aliyun.fastmodel.core.tree.statement.table.ColumnDefinition; +import com.aliyun.fastmodel.core.tree.statement.table.CreateTable; +import com.aliyun.fastmodel.core.tree.statement.table.PartitionedBy; +import com.aliyun.fastmodel.core.tree.statement.table.constraint.BaseConstraint; +import com.aliyun.fastmodel.core.tree.statement.table.index.IndexColumnName; +import com.aliyun.fastmodel.core.tree.statement.table.index.IndexExpr; +import com.aliyun.fastmodel.core.tree.statement.table.index.IndexSortKey; +import com.aliyun.fastmodel.transform.api.client.PropertyConverter; +import com.aliyun.fastmodel.transform.api.client.dto.constraint.Constraint; +import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; +import com.aliyun.fastmodel.transform.api.client.dto.property.StringProperty; +import com.aliyun.fastmodel.transform.api.client.dto.table.Column; +import com.aliyun.fastmodel.transform.api.client.dto.table.Table; +import com.aliyun.fastmodel.transform.api.extension.client.constraint.UniqueKeyExprClientConstraint; +import com.aliyun.fastmodel.transform.api.extension.client.converter.ExtensionClientConverter; +import com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.BaseClientPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.PartitionClientValue; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.SingleRangeClientPartition; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.UniqueKeyExprConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.SingleRangePartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.PartitionValue; +import com.aliyun.fastmodel.transform.oceanbase.client.converter.partition.OceanBasePartitionClientConverter; +import com.aliyun.fastmodel.transform.oceanbase.client.converter.partition.impl.OceanBasePartitionClientConverterImpl; +import com.aliyun.fastmodel.transform.oceanbase.client.property.SubPartitionClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.hash.HashPartitionClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.hash.HashPartitionElementClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.hash.HashPartitionProperty; +import com.aliyun.fastmodel.transform.oceanbase.client.property.hash.SubHashPartitionElementClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.key.KeyPartitionClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.key.KeyPartitionProperty; +import com.aliyun.fastmodel.transform.oceanbase.client.property.list.ListPartitionClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.list.ListPartitionElementClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.list.ListPartitionProperty; +import com.aliyun.fastmodel.transform.oceanbase.client.property.list.SubListPartitionElementClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.range.RangePartitionClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.range.RangePartitionElementClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.range.RangePartitionProperty; +import com.aliyun.fastmodel.transform.oceanbase.client.property.range.SubRangePartitionElementClient; +import com.aliyun.fastmodel.transform.oceanbase.context.OceanBaseContext; +import com.aliyun.fastmodel.transform.oceanbase.format.OceanBaseMysqlOutVisitor; +import com.aliyun.fastmodel.transform.oceanbase.format.OceanBasePropertyKey; +import com.aliyun.fastmodel.transform.oceanbase.parser.OceanBaseMysqlLanguageParser; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.OceanBaseMysqlDataTypeName; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.OceanBaseHashPartitionBy; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.OceanBaseKeyPartitionBy; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.OceanBaseListPartitionBy; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.OceanBaseRangePartitionBy; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.BaseSubPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.HashPartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.ListPartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.RangePartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubPartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubPartitionList; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubRangePartitionElement; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +/** + * oceanbase mysql client converter + * + * @author panguanjing + * @date 2024/2/5 + */ +public class OceanBaseMysqlClientConverter extends ExtensionClientConverter { + + private final OceanBaseMysqlLanguageParser oceanBaseMysqlLanguageParser; + + private final OceanBaseMysqlPropertyConverter oceanBaseMysqlPropertyConverter; + + private final OceanBasePartitionClientConverter oceanBasePartitionClientConverter; + + public OceanBaseMysqlClientConverter() { + oceanBaseMysqlLanguageParser = new OceanBaseMysqlLanguageParser(); + oceanBaseMysqlPropertyConverter = new OceanBaseMysqlPropertyConverter(); + oceanBasePartitionClientConverter = new OceanBasePartitionClientConverterImpl(this); + } + + @Override + public PropertyConverter getPropertyConverter() { + return oceanBaseMysqlPropertyConverter; + } + + @Override + public IDataTypeName getDataTypeName(String dataTypeName) { + return OceanBaseMysqlDataTypeName.getByValue(dataTypeName); + } + + @Override + public LanguageParser getLanguageParser() { + return oceanBaseMysqlLanguageParser; + } + + @Override + public String getRaw(Node node) { + if (node == null) { + return null; + } + OceanBaseMysqlOutVisitor mysqlOutVisitor = new OceanBaseMysqlOutVisitor(OceanBaseContext.builder().build()); + node.accept(mysqlOutVisitor, 0); + return mysqlOutVisitor.getBuilder().toString(); + } + + @Override + public List toBaseClientProperty(CreateTable createTable) { + List list = super.toBaseClientProperty(createTable); + PartitionedBy partitionedBy = createTable.getPartitionedBy(); + if (partitionedBy instanceof OceanBaseHashPartitionBy) { + OceanBaseHashPartitionBy oceanBaseHashPartitionBy = (OceanBaseHashPartitionBy)partitionedBy; + HashPartitionProperty hashPartitionProperty = toHashPartitionProperty(oceanBaseHashPartitionBy); + list.add(hashPartitionProperty); + } else if (partitionedBy instanceof OceanBaseRangePartitionBy) { + OceanBaseRangePartitionBy oceanBaseRangePartitionBy = (OceanBaseRangePartitionBy)partitionedBy; + RangePartitionProperty rangePartitionProperty = toRangePartitionProperty(oceanBaseRangePartitionBy); + list.add(rangePartitionProperty); + } else if (partitionedBy instanceof OceanBaseKeyPartitionBy) { + OceanBaseKeyPartitionBy oceanBaseKeyPartitionBy = (OceanBaseKeyPartitionBy)partitionedBy; + KeyPartitionProperty keyPartitionProperty = toKeyPartitionProperty(oceanBaseKeyPartitionBy); + list.add(keyPartitionProperty); + } else if (partitionedBy instanceof OceanBaseListPartitionBy) { + OceanBaseListPartitionBy oceanBaseListPartitionBy = (OceanBaseListPartitionBy)partitionedBy; + ListPartitionProperty listPartitionProperty = toListPartitionProperty(oceanBaseListPartitionBy); + list.add(listPartitionProperty); + } + return list; + } + + private ListPartitionProperty toListPartitionProperty(OceanBaseListPartitionBy oceanBaseListPartitionBy) { + ListPartitionProperty listPartitionProperty = new ListPartitionProperty(); + ListPartitionClient client = new ListPartitionClient(); + LongLiteral partitionCount = oceanBaseListPartitionBy.getPartitionCount(); + if (partitionCount != null) { + client.setPartitionCount(partitionCount.getValue()); + } + BaseExpression baseExpression = oceanBaseListPartitionBy.getBaseExpression(); + if (baseExpression != null) { + client.setExpression(getRaw(baseExpression)); + } + if (oceanBaseListPartitionBy.getSubPartition() != null) { + SubPartitionClient subPartitionClient = toSubPartitionClient(oceanBaseListPartitionBy.getSubPartition()); + client.setSubPartitionClient(subPartitionClient); + } + List partitionElementClientList = null; + if (oceanBaseListPartitionBy.getPartitionElementList() != null) { + partitionElementClientList = oceanBaseListPartitionBy.getPartitionElementList().stream() + .map(c -> { + ListPartitionElementClient listPartitionElementClient = toListPartitionElementClient(c); + return listPartitionElementClient; + }).collect(Collectors.toList()); + client.setPartitionElementClientList(partitionElementClientList); + } + List columns = null; + if (oceanBaseListPartitionBy.getColumnDefinitions() != null) { + columns = oceanBaseListPartitionBy.getColumnDefinitions().stream() + .map(c -> c.getColName().getValue()) + .collect(Collectors.toList()); + } + client.setColumns(columns); + listPartitionProperty.setValue(client); + return listPartitionProperty; + } + + private ListPartitionElementClient toListPartitionElementClient(ListPartitionElement c) { + List expressionList = null; + QualifiedName qualifiedName = c.getQualifiedName(); + String name = null; + if (qualifiedName != null) { + name = qualifiedName.toString(); + } + String engine = null; + if (c.getExpressionList() != null) { + expressionList = c.getExpressionList().stream() + .map(x -> getRaw(x)).collect(Collectors.toList()); + } + if (c.getProperty() != null) { + engine = c.getProperty().getValue(); + } + Long num = null; + if (c.getNum() != null) { + num = c.getNum().getValue(); + } + List listSubPartitionElementClients = null; + if (c.getSubPartitionList() != null) { + List subPartitionElementList = c.getSubPartitionList().getSubPartitionElementList(); + listSubPartitionElementClients = subPartitionElementList.stream() + .map(element -> { + return toListSubPartitionElementClient(element); + }).collect(Collectors.toList()); + } + return ListPartitionElementClient.builder() + .expressionList(expressionList) + .engine(engine) + .num(num) + .qualifiedName(name) + .subPartitionElementList(listSubPartitionElementClients) + .defaultExpr(c.getDefaultExpr()) + .build(); + + } + + private SubListPartitionElementClient toListSubPartitionElementClient(SubPartitionElement c) { + return (SubListPartitionElementClient)oceanBasePartitionClientConverter.toSubPartitionElementClient(c); + } + + private KeyPartitionProperty toKeyPartitionProperty(OceanBaseKeyPartitionBy oceanBaseKeyPartitionBy) { + if (oceanBaseKeyPartitionBy == null) { + return null; + } + KeyPartitionProperty keyPartitionProperty = new KeyPartitionProperty(); + KeyPartitionClient keyPartitionClient = new KeyPartitionClient(); + LongLiteral partitionCount = oceanBaseKeyPartitionBy.getPartitionCount(); + if (partitionCount != null) { + keyPartitionClient.setPartitionCount(partitionCount.getValue()); + } + List columnDefinitions = oceanBaseKeyPartitionBy.getColumnDefinitions(); + List columnList = null; + if (columnDefinitions != null) { + columnList = columnDefinitions.stream().map(c -> c.getColName().getValue()).collect(Collectors.toList()); + keyPartitionClient.setColumnList(columnList); + } + BaseSubPartition subPartition = oceanBaseKeyPartitionBy.getSubPartition(); + SubPartitionClient subPartitionClient = toSubPartitionClient(subPartition); + keyPartitionClient.setSubPartitionClient(subPartitionClient); + + if (oceanBaseKeyPartitionBy.getHashPartitionElements() != null) { + List partitionElementClientList = toPartitionElementClientList( + oceanBaseKeyPartitionBy.getHashPartitionElements()); + keyPartitionClient.setPartitionElementClientList(partitionElementClientList); + } + + //set value + keyPartitionProperty.setValue(keyPartitionClient); + return keyPartitionProperty; + } + + private RangePartitionProperty toRangePartitionProperty(OceanBaseRangePartitionBy oceanBaseRangePartitionBy) { + RangePartitionProperty rangePartitionProperty = new RangePartitionProperty(); + RangePartitionClient client = new RangePartitionClient(); + + //columns + List columns = null; + if (oceanBaseRangePartitionBy.getColumnDefinitions() != null) { + columns = oceanBaseRangePartitionBy.getColumnDefinitions().stream().map( + c -> c.getColName().getValue() + ).collect(Collectors.toList()); + } + client.setColumns(columns); + + //partition count + Long partitionCount = null; + if (oceanBaseRangePartitionBy.getPartitionCount() != null) { + partitionCount = oceanBaseRangePartitionBy.getPartitionCount().getValue(); + } + client.setPartitionCount(partitionCount); + + //expression + BaseExpression baseExpression = oceanBaseRangePartitionBy.getBaseExpression(); + if (baseExpression != null) { + client.setBaseExpression(getRaw(baseExpression)); + } + + //partition client + SubPartitionClient rangeSubPartitionClient = toSubPartitionClient(oceanBaseRangePartitionBy.getSubPartition()); + client.setRangeSubPartitionClient(rangeSubPartitionClient); + + //RangePartitionElementClient + List rangePartitionElementClients = toRangePartitionElementClient( + oceanBaseRangePartitionBy.getSingleRangePartitionList()); + client.setRangePartitionElementClients(rangePartitionElementClients); + //set value + rangePartitionProperty.setValue(client); + return rangePartitionProperty; + } + + private SubPartitionClient toSubPartitionClient(BaseSubPartition subPartition) { + return oceanBasePartitionClientConverter.toSubPartitionClient(subPartition); + } + + public List toRangeSubPartitionElementClients(SubPartitionList subPartitionList) { + if (CollectionUtils.isEmpty(subPartitionList.getSubPartitionElementList())) { + return null; + } + List subPartitionElementList = subPartitionList.getSubPartitionElementList(); + return subPartitionElementList.stream().map( + p -> (SubRangePartitionElementClient)oceanBasePartitionClientConverter.toSubPartitionElementClient((SubRangePartitionElement)p) + ).collect(Collectors.toList()); + } + + public SingleRangeClientPartition toSingleRangeClientPartition(SingleRangePartition singleRangePartition) { + LinkedHashMap properties = null; + List propertyList = singleRangePartition.getPropertyList(); + if (propertyList != null) { + properties = Maps.newLinkedHashMap(); + for (Property p : propertyList) { + properties.put(p.getName(), p.getValue()); + } + } + BaseClientPartitionKey partitionKey = null; + if (singleRangePartition.getPartitionKey() != null) { + partitionKey = toClientPartitionKey(singleRangePartition.getPartitionKey()); + } + SingleRangeClientPartition singleRangeClientPartition = SingleRangeClientPartition.builder() + .name(singleRangePartition.getName().getValue()) + .partitionKey(partitionKey) + .properties(properties) + .build(); + return singleRangeClientPartition; + } + + private List toRangePartitionElementClient(List singleRangePartitionList) { + if (singleRangePartitionList == null) { + return null; + } + return singleRangePartitionList.stream().map( + p -> geRangetPartitionElementClient(p) + ).collect(Collectors.toList()); + } + + private RangePartitionElementClient geRangetPartitionElementClient(RangePartitionElement p) { + Long id = null; + if (p.getIdCount() != null) { + id = p.getIdCount().getValue(); + } + SingleRangeClientPartition singleRangeClientPartition = null; + if (p.getSingleRangePartition() != null) { + singleRangeClientPartition = toSingleRangeClientPartition(p.getSingleRangePartition()); + } + List rangeSubPartitionElements = null; + if (p.getSubPartitionList() != null) { + rangeSubPartitionElements = toRangeSubPartitionElementClients(p.getSubPartitionList()); + } + RangePartitionElementClient rangePartitionElementClient = RangePartitionElementClient.builder() + .id(id) + .singleRangeClientPartition(singleRangeClientPartition) + .rangeSubPartitionElementClients(rangeSubPartitionElements) + .build(); + return rangePartitionElementClient; + } + + @Override + protected PartitionedBy toPartitionedBy(Table table, List columns) { + PartitionedBy partitionedBy = super.toPartitionedBy(table, columns); + if (partitionedBy != null) { + return partitionedBy; + } + List properties = table.getProperties(); + if (properties == null) { + return null; + } + Optional first = properties.stream().filter(p -> { + return StringUtils.equalsIgnoreCase(p.getKey(), OceanBasePropertyKey.PARTITION.getValue()); + }).findFirst(); + if (first.isEmpty()) { + return null; + } + BaseClientProperty baseClientProperty = first.get(); + if (baseClientProperty instanceof HashPartitionProperty) { + HashPartitionProperty hashPartitionProperty = (HashPartitionProperty)baseClientProperty; + return toHashPartitionBy(hashPartitionProperty); + } + if (baseClientProperty instanceof RangePartitionProperty) { + RangePartitionProperty rangePartitionProperty = (RangePartitionProperty)baseClientProperty; + return toRangePartitionBy(rangePartitionProperty); + } + if (baseClientProperty instanceof ListPartitionProperty) { + ListPartitionProperty listPartitionProperty = (ListPartitionProperty)baseClientProperty; + return toListPartitionBy(listPartitionProperty); + } + if (baseClientProperty instanceof KeyPartitionProperty) { + KeyPartitionProperty keyPartitionProperty = (KeyPartitionProperty)baseClientProperty; + return toKeyPartitionBy(keyPartitionProperty); + } + return null; + } + + private PartitionedBy toKeyPartitionBy(KeyPartitionProperty keyPartitionProperty) { + if (keyPartitionProperty == null) { + return null; + } + KeyPartitionClient value = keyPartitionProperty.getValue(); + OceanBaseKeyPartitionBy oceanBaseKeyPartitionBy = new OceanBaseKeyPartitionBy( + getColumnDefinitions(value.getColumnList()), + getLongLiteral(value.getPartitionCount()), + getSubPartition(value.getSubPartitionClient()), + getHashPartitionElements(value.getPartitionElementClientList()) + ); + return oceanBaseKeyPartitionBy; + } + + private PartitionedBy toListPartitionBy(ListPartitionProperty listPartitionProperty) { + if (listPartitionProperty == null) { + return null; + } + ListPartitionClient value = listPartitionProperty.getValue(); + List partitionElementList = null; + if (value.getPartitionElementClientList() != null) { + partitionElementList = value.getPartitionElementClientList().stream() + .map(e -> { + return getListPartitionElement(e); + }).collect(Collectors.toList()); + } + OceanBaseListPartitionBy oceanBaseListPartitionBy = new OceanBaseListPartitionBy( + getColumnDefinitions(value.getColumns()), + (BaseExpression)getLanguageParser().parseExpression(value.getExpression()), + getLongLiteral(value.getPartitionCount()), + getSubPartition(value.getSubPartitionClient()), + partitionElementList + ); + return oceanBaseListPartitionBy; + } + + private ListPartitionElement getListPartitionElement(ListPartitionElementClient e) { + QualifiedName qualifiedName = QualifiedName.of(e.getQualifiedName()); + List expressionList = null; + if (e.getExpressionList() != null) { + expressionList = e.getExpressionList().stream() + .map(expr -> (BaseExpression)getLanguageParser().parseExpression(expr)).collect(Collectors.toList()); + } + LongLiteral num = null; + if (e.getNum() != null) { + num = new LongLiteral(e.getNum().toString()); + } + Property property = null; + if (e.getEngine() != null) { + property = new Property(ExtensionPropertyKey.TABLE_ENGINE.getValue(), e.getEngine()); + } + SubPartitionList subPartitionList = null; + if (e.getSubPartitionElementList() != null) { + List subPartitionElementList = e.getSubPartitionElementList() + .stream().map( + ele -> oceanBasePartitionClientConverter.getSubPartitionElement(ele) + ).collect(Collectors.toList()); + subPartitionList = new SubPartitionList(subPartitionElementList); + } + return new ListPartitionElement(qualifiedName, e.getDefaultExpr(), expressionList, num, property, subPartitionList); + } + + private PartitionedBy toRangePartitionBy(RangePartitionProperty rangePartitionProperty) { + if (rangePartitionProperty == null) { + return null; + } + RangePartitionClient value = rangePartitionProperty.getValue(); + if (value == null) { + return null; + } + List columnDefine = getColumnDefinitions(value.getColumns()); + LongLiteral partitionCount = getLongLiteral(value.getPartitionCount()); + BaseExpression baseExpression = null; + if (value.getBaseExpression() != null) { + baseExpression = (BaseExpression)getLanguageParser().parseExpression(value.getBaseExpression()); + } + BaseSubPartition subPartition = null; + SubPartitionClient rangeSubPartitionClient = value.getRangeSubPartitionClient(); + if (rangeSubPartitionClient != null) { + subPartition = getSubPartition(rangeSubPartitionClient); + } + List singleRangePartitionList = null; + if (value.getRangePartitionElementClients() != null) { + singleRangePartitionList = value.getRangePartitionElementClients().stream().map( + c -> { + return toRangePartitionElement(c); + } + ).collect(Collectors.toList()); + } + return new OceanBaseRangePartitionBy(columnDefine, partitionCount, subPartition, baseExpression, singleRangePartitionList); + } + + public LongLiteral getLongLiteral(Long value) { + LongLiteral partitionCount = null; + if (value != null) { + partitionCount = new LongLiteral(String.valueOf(value)); + } + return partitionCount; + } + + private List getColumnDefinitions(List columns) { + List columnDefine = null; + if (columns != null) { + columnDefine = columns.stream().map( + c -> { + return ColumnDefinition.builder().colName(new Identifier(c)).build(); + } + ).collect(Collectors.toList()); + } + return columnDefine; + } + + private BaseSubPartition getSubPartition(SubPartitionClient subPartitionClient) { + return oceanBasePartitionClientConverter.getSubPartition(subPartitionClient); + } + + public RangePartitionElement toRangePartitionElement(RangePartitionElementClient s) { + LongLiteral idCount = getLongLiteral(s.getId()); + SingleRangePartition singleRangePartition = null; + if (s.getSingleRangeClientPartition() != null) { + singleRangePartition = (SingleRangePartition)getPartitionDesc(s.getSingleRangeClientPartition()); + } + SubPartitionList subPartitionList = null; + if (s.getRangeSubPartitionElementClients() != null) { + List subPartitionElementList = s.getRangeSubPartitionElementClients().stream() + .map(elementClient -> { + return oceanBasePartitionClientConverter.getSubPartitionElement(elementClient); + }).collect(Collectors.toList()); + subPartitionList = new SubPartitionList(subPartitionElementList); + } + RangePartitionElement rangePartitionElement = new RangePartitionElement( + idCount, singleRangePartition, subPartitionList + ); + return rangePartitionElement; + } + + private PartitionedBy toHashPartitionBy(HashPartitionProperty hashPartitionProperty) { + LongLiteral i = null; + HashPartitionClient value = hashPartitionProperty.getValue(); + if (value.getPartitionCount() != null) { + i = new LongLiteral(String.valueOf(value.getPartitionCount())); + } + BaseExpression expression = null; + if (value.getExpression() != null) { + expression = (BaseExpression)getLanguageParser().parseExpression(value.getExpression()); + } + SubPartitionClient subPartitionClient = value.getSubPartitionClient(); + BaseSubPartition subPartition = getSubPartition(subPartitionClient); + List hashPartitionElements = getHashPartitionElements(value.getPartitionElementClientList()); + OceanBaseHashPartitionBy oceanBaseHashPartitionBy = new OceanBaseHashPartitionBy( + i, expression, subPartition, hashPartitionElements + ); + return oceanBaseHashPartitionBy; + } + + private List getHashPartitionElements(List value) { + List hashPartitionElements = null; + if (value == null) { + return null; + } + hashPartitionElements = value.stream().map( + p -> getHashPartitionElement(p) + ).collect(Collectors.toList()); + return hashPartitionElements; + } + + private HashPartitionElement getHashPartitionElement(HashPartitionElementClient p) { + QualifiedName qualifiedName = QualifiedName.of(p.getQualifiedName()); + LongLiteral num = getLongLiteral(p.getNum()); + Property property = null; + if (p.getProperty() != null) { + property = new Property(p.getProperty().getKey(), p.getProperty().getValue()); + } + SubPartitionList subPartitionList = null; + if (p.getSubPartitionList() != null) { + List subPartitionElementList = p.getSubPartitionList().stream() + .map(s -> { + return oceanBasePartitionClientConverter.getSubPartitionElement(s); + }).collect(Collectors.toList()); + subPartitionList = new SubPartitionList(subPartitionElementList); + } + return new HashPartitionElement(qualifiedName, num, property, subPartitionList); + } + + private HashPartitionProperty toHashPartitionProperty(OceanBaseHashPartitionBy oceanBaseHashPartitionBy) { + HashPartitionProperty property = new HashPartitionProperty(); + LongLiteral partitionCount = oceanBaseHashPartitionBy.getPartitionCount(); + Long value = partitionCount != null ? partitionCount.getValue() : null; + HashPartitionClient client = HashPartitionClient.builder() + .expression(StripUtils.strip(getRaw(oceanBaseHashPartitionBy.getExpression()))) + .partitionCount(value) + .subPartitionClient(toSubPartitionClient(oceanBaseHashPartitionBy.getSubPartition())) + .partitionElementClientList(toPartitionElementClientList(oceanBaseHashPartitionBy.getHashPartitionElements())) + .build(); + + property.setValue(client); + return property; + } + + private List toPartitionElementClientList(List hashPartitionElements) { + if (hashPartitionElements == null || hashPartitionElements.isEmpty()) { + return null; + } + return hashPartitionElements.stream().map(e -> getHashPartitionElementClient(e)).collect(Collectors.toList()); + } + + private HashPartitionElementClient getHashPartitionElementClient(HashPartitionElement e) { + StringProperty property = getStringProperty(e.getProperty()); + List list = null; + if (e.getSubPartitionList() != null) { + list = e.getSubPartitionList().getSubPartitionElementList().stream().map( + element -> { + return (SubHashPartitionElementClient)oceanBasePartitionClientConverter.toSubPartitionElementClient(element); + } + ).collect(Collectors.toList()); + } + return HashPartitionElementClient.builder() + .num(e.getNum() == null ? null : e.getNum().getValue()) + .qualifiedName(e.getQualifiedName().toString()) + .property(property) + .subPartitionList(list) + .build(); + } + + @Override + protected PartitionValue getPartitionValue(PartitionClientValue partitionClientValue) { + String value = partitionClientValue.getValue(); + BaseExpression baseExpression = null; + if (StringUtils.isNotBlank(value)) { + baseExpression = (BaseExpression)getLanguageParser().parseExpression(value); + } + PartitionValue partitionValue = new PartitionValue(partitionClientValue.isMaxValue(), baseExpression); + return partitionValue; + } + + public StringProperty getStringProperty(Property e) { + if (e == null) { + return null; + } + StringProperty property = new StringProperty(); + property.setKey(e.getName()); + property.setValueString(e.getValue()); + return property; + } + + @Override + protected String formatExpression(BaseExpression baseExpression) { + OceanBaseMysqlOutVisitor mysqlOutVisitor = new OceanBaseMysqlOutVisitor(OceanBaseContext.builder().build()); + baseExpression.accept(mysqlOutVisitor, 0); + return mysqlOutVisitor.getBuilder().toString(); + } + + @Override + protected List toOutlineConstraint(CreateTable createTable) { + List outlineConstraint = super.toOutlineConstraint(createTable); + if (createTable.isConstraintEmpty()) { + return outlineConstraint; + } + List constraintStatements = createTable.getConstraintStatements(); + if (outlineConstraint == null || outlineConstraint.isEmpty()) { + outlineConstraint = Lists.newArrayList(); + } + if (!constraintStatements.isEmpty()) { + for (BaseConstraint baseConstraint : constraintStatements) { + convertConstraint(baseConstraint, outlineConstraint); + } + } + return outlineConstraint; + } + + private void convertConstraint(BaseConstraint baseConstraint, List outlineConstraint) { + if (!(baseConstraint instanceof UniqueKeyExprConstraint)) { + return; + } + UniqueKeyExprConstraint u = (UniqueKeyExprConstraint)baseConstraint; + List indexSortKeys = u.getIndexSortKeys(); + UniqueKeyExprClientConstraint uniqueKeyExprClientConstraint = new UniqueKeyExprClientConstraint(); + List column = indexSortKeys.stream() + .filter(i -> { + return i instanceof IndexColumnName; + }).map(i -> { + IndexColumnName indexColumnName = (IndexColumnName)i; + return indexColumnName.getColumnName().getValue(); + }).collect(Collectors.toList()); + + uniqueKeyExprClientConstraint.setColumns(column); + + List expression = indexSortKeys.stream() + .filter(i -> { + return i instanceof IndexExpr; + }).map(i -> { + IndexExpr indexColumnName = (IndexExpr)i; + return formatExpression(indexColumnName.getExpression()); + }).collect(Collectors.toList()); + uniqueKeyExprClientConstraint.setExpression(expression); + outlineConstraint.add(uniqueKeyExprClientConstraint); + } + + public List getColumnList(List columnList) { + if (columnList == null) { + return null; + } + return columnList.stream() + .map(c -> c.getValue()) + .collect(Collectors.toList()); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/converter/OceanBaseMysqlPropertyConverter.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/converter/OceanBaseMysqlPropertyConverter.java new file mode 100644 index 0000000..c17f7d0 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/converter/OceanBaseMysqlPropertyConverter.java @@ -0,0 +1,32 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.converter; + +import java.util.Map; +import java.util.function.Function; + +import com.aliyun.fastmodel.transform.api.client.converter.BasePropertyConverter; +import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; +import com.google.common.collect.Maps; + +/** + * oceanbase property converter + * + * @author panguanjing + * @date 2024/1/21 + */ +public class OceanBaseMysqlPropertyConverter extends BasePropertyConverter { + + private static Map> functionMap = Maps.newHashMap(); + + public OceanBaseMysqlPropertyConverter() { + init(); + } + + private void init() { + + } + + @Override + protected Map> getFunctionMap() { + return functionMap; + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/converter/partition/OceanBasePartitionClientConverter.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/converter/partition/OceanBasePartitionClientConverter.java new file mode 100644 index 0000000..8bd195f --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/converter/partition/OceanBasePartitionClientConverter.java @@ -0,0 +1,48 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.converter.partition; + +import com.aliyun.fastmodel.transform.oceanbase.client.property.SubPartitionClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.SubPartitionElementClient; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.BaseSubPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubPartitionElement; + +/** + * converter + * provider client to fml, and fml to client converter + * + * @author panguanjing + * @date 2024/2/28 + */ +public interface OceanBasePartitionClientConverter { + /** + * to subPartition client + * + * @param baseSubPartition + * @return + */ + SubPartitionClient toSubPartitionClient(BaseSubPartition baseSubPartition); + + /** + * to baseSubPartition + * + * @param subPartitionClient + * @return + */ + BaseSubPartition getSubPartition(SubPartitionClient subPartitionClient); + + /** + * toSubPartitionElementClient + * + * @param subPartitionElement + * @return + */ + SubPartitionElementClient toSubPartitionElementClient(SubPartitionElement subPartitionElement); + + /** + * getSubPartitionElement + * + * @param subPartitionElementClient + * @return + */ + SubPartitionElement getSubPartitionElement(SubPartitionElementClient subPartitionElementClient); + +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/converter/partition/impl/OceanBasePartitionClientConverterImpl.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/converter/partition/impl/OceanBasePartitionClientConverterImpl.java new file mode 100644 index 0000000..c677bcb --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/converter/partition/impl/OceanBasePartitionClientConverterImpl.java @@ -0,0 +1,469 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.converter.partition.impl; + +import java.util.List; +import java.util.stream.Collectors; + +import com.aliyun.fastmodel.common.utils.StripUtils; +import com.aliyun.fastmodel.core.tree.Property; +import com.aliyun.fastmodel.core.tree.QualifiedName; +import com.aliyun.fastmodel.core.tree.expr.BaseExpression; +import com.aliyun.fastmodel.core.tree.expr.Identifier; +import com.aliyun.fastmodel.core.tree.expr.literal.LongLiteral; +import com.aliyun.fastmodel.transform.api.client.dto.property.StringProperty; +import com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.SingleRangeClientPartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.SingleRangePartition; +import com.aliyun.fastmodel.transform.oceanbase.client.converter.OceanBaseMysqlClientConverter; +import com.aliyun.fastmodel.transform.oceanbase.client.converter.partition.OceanBasePartitionClientConverter; +import com.aliyun.fastmodel.transform.oceanbase.client.property.SubPartitionClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.SubPartitionElementClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.hash.SubHashPartitionClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.hash.SubHashPartitionElementClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.hash.SubHashTemplatePartitionClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.key.SubKeyPartitionClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.key.SubKeyTemplatePartitionClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.list.SubListPartitionClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.list.SubListPartitionElementClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.list.SubListTemplatePartitionClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.range.RangePartitionElementClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.range.SubRangePartitionClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.range.SubRangePartitionElementClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.range.SubRangeTemplatePartitionClient; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.BaseSubPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.SubHashPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.SubKeyPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.SubListPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.SubRangePartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.RangePartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubHashPartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubListPartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubPartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubPartitionList; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubRangePartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.template.SubHashTemplatePartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.template.SubKeyTemplatePartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.template.SubListTemplatePartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.template.SubRangeTemplatePartition; + +/** + * OceanBasePartitionClientConverterImpl + * + * @author panguanjing + * @date 2024/2/28 + */ +public class OceanBasePartitionClientConverterImpl implements OceanBasePartitionClientConverter { + + private final OceanBaseMysqlClientConverter extensionClientConverter; + + public OceanBasePartitionClientConverterImpl(OceanBaseMysqlClientConverter extensionClientConverter) { + this.extensionClientConverter = extensionClientConverter; + } + + @Override + public SubPartitionClient toSubPartitionClient(BaseSubPartition subPartition) { + List columnLists = null; + String expression = null; + List singleRangePartitionList = null; + if (subPartition instanceof SubRangePartition) { + return getSubRangePartitionClient((SubRangePartition)subPartition, columnLists, expression, singleRangePartitionList); + } else if (subPartition instanceof SubKeyPartition) { + return getSubKeyPartitionClient((SubKeyPartition)subPartition); + } else if (subPartition instanceof SubHashPartition) { + return getSubHashPartitionClient((SubHashPartition)subPartition); + } else if (subPartition instanceof SubListPartition) { + return getSubListPartitionClient((SubListPartition)subPartition); + } else if (subPartition instanceof SubRangeTemplatePartition) { + return getSubRangeTemplatePartitionClient((SubRangeTemplatePartition)subPartition); + } else if (subPartition instanceof SubKeyTemplatePartition) { + return getSubKeyTemplatePartitionClient((SubKeyTemplatePartition)subPartition); + } else if (subPartition instanceof SubHashTemplatePartition) { + return getSubHashTemplatePartitionClient((SubHashTemplatePartition)subPartition); + } else if (subPartition instanceof SubListTemplatePartition) { + return getSubListTemplatePartitionClient((SubListTemplatePartition)subPartition); + } + return null; + } + + private SubPartitionClient getSubListTemplatePartitionClient(SubListTemplatePartition subPartition) { + List clientList = getSubPartitionElementClientList(subPartition.getSubPartitionList()); + return SubListTemplatePartitionClient.builder() + .expression(extensionClientConverter.getRaw(subPartition.getExpression())) + .columnList(extensionClientConverter.getColumnList(subPartition.getColumnList())) + .subPartitionElementClientList(clientList) + .build(); + } + + private List getSubPartitionElementClientList(SubPartitionList subPartitionList) { + List subPartitionElementList = null; + List clientList = null; + if (subPartitionList != null) { + subPartitionElementList = subPartitionList.getSubPartitionElementList(); + clientList = subPartitionElementList.stream() + .map(p -> toSubPartitionElementClient(p)).collect(Collectors.toList()); + } + return clientList; + } + + private SubPartitionClient getSubHashTemplatePartitionClient(SubHashTemplatePartition subPartition) { + String expression = null; + List list = null; + if (subPartition.getExpression() != null) { + expression = extensionClientConverter.getRaw(subPartition.getExpression()); + } + if (subPartition.getSubPartitionList() != null) { + list = getSubPartitionElementClientList(subPartition.getSubPartitionList()); + } + return SubHashTemplatePartitionClient.builder() + .expression(expression) + .subPartitionElementClientList(list) + .build(); + } + + private SubPartitionClient getSubKeyTemplatePartitionClient(SubKeyTemplatePartition subPartition) { + List columnList = extensionClientConverter.getColumnList(subPartition.getColumnList()); + List subPartitionElementClient = getSubPartitionElementClientList(subPartition.getSubPartitionList()); + return SubKeyTemplatePartitionClient.builder() + .columnList(columnList) + .subPartitionElementClients(subPartitionElementClient) + .build(); + } + + private SubPartitionClient getSubRangeTemplatePartitionClient(SubRangeTemplatePartition subPartition) { + List columnList = extensionClientConverter.getColumnList(subPartition.getColumnList()); + String expression = null; + if (subPartition.getExpression() != null) { + expression = extensionClientConverter.getRaw(subPartition.getExpression()); + } + List elementList = getSubPartitionElementClientList(subPartition.getSubPartitionList()); + return SubRangeTemplatePartitionClient.builder() + .columnList(columnList) + .expression(expression) + .subPartitionElementClientList(elementList) + .build(); + } + + private SubListPartitionClient getSubListPartitionClient(SubListPartition subPartition) { + SubListPartition subListPartition = subPartition; + List columnList = subListPartition.getColumnList(); + List list = null; + if (columnList != null) { + list = columnList.stream().map(Identifier::getValue).collect(Collectors.toList()); + } + String subListExpression = null; + if (subListPartition.getExpression() != null) { + subListExpression = extensionClientConverter.getRaw(subListPartition.getExpression()); + } + return SubListPartitionClient.builder() + .columnList(list) + .expression(subListExpression) + .build(); + } + + private SubHashPartitionClient getSubHashPartitionClient(SubHashPartition subPartition) { + SubHashPartition subHashPartition = subPartition; + return SubHashPartitionClient.builder() + .expression(StripUtils.strip(extensionClientConverter.getRaw(subHashPartition.getExpression()))) + .subpartitionCount(subHashPartition.getSubpartitionCount() != null ? subHashPartition.getSubpartitionCount().getValue() : null) + .build(); + } + + private static SubKeyPartitionClient getSubKeyPartitionClient(SubKeyPartition subPartition) { + List columnLists; + SubKeyPartition subKeyPartition = subPartition; + List columnList = subKeyPartition.getColumnList(); + columnLists = columnList.stream().map(Identifier::getValue).collect(Collectors.toList()); + Long subPartitionCount = null; + if (subKeyPartition.getSubpartitionCount() != null) { + subPartitionCount = subKeyPartition.getSubpartitionCount().getValue(); + } + return new SubKeyPartitionClient(subPartitionCount, columnLists); + } + + private SubRangePartitionClient getSubRangePartitionClient(SubRangePartition subPartition, List columnLists, String expression, + List singleRangePartitionList) { + SubRangePartition subRangePartition = subPartition; + List columnList = subRangePartition.getColumnList(); + if (columnList != null) { + columnLists = columnList.stream().map(Identifier::getValue).collect(Collectors.toList()); + } + if (subRangePartition.getExpression() != null) { + expression = extensionClientConverter.getRaw(subRangePartition.getExpression()); + } + if (subRangePartition.getSingleRangePartitionList() != null) { + singleRangePartitionList = subRangePartition.getSingleRangePartitionList() + .stream() + .map(c -> getRangePartitionElementClient(c)).collect(Collectors.toList()); + } + return SubRangePartitionClient.builder() + .columnList(columnLists) + .expression(expression) + .singleRangePartitionList(singleRangePartitionList) + .build(); + } + + private RangePartitionElementClient getRangePartitionElementClient(RangePartitionElement c) { + Long id = null; + if (c.getIdCount() != null) { + id = c.getIdCount().getValue(); + } + SingleRangeClientPartition singleRangePartition = null; + if (c.getSingleRangePartition() != null) { + singleRangePartition = extensionClientConverter.toSingleRangeClientPartition(c.getSingleRangePartition()); + } + List rangeSubPartitionElementClients = null; + if (c.getSubPartitionList() != null) { + rangeSubPartitionElementClients = extensionClientConverter.toRangeSubPartitionElementClients(c.getSubPartitionList()); + } + return new RangePartitionElementClient(id, singleRangePartition, rangeSubPartitionElementClients); + } + + @Override + public BaseSubPartition getSubPartition(SubPartitionClient subPartitionClient) { + //sub range + if (subPartitionClient instanceof SubRangePartitionClient) { + return getSubRangePartition((SubRangePartitionClient)subPartitionClient); + } + //sub range template + if (subPartitionClient instanceof SubRangeTemplatePartitionClient) { + return getSubRangeTemplatePartition((SubRangeTemplatePartitionClient)subPartitionClient); + } + + //sub key + if (subPartitionClient instanceof SubKeyPartitionClient) { + return getSubKeyPartition((SubKeyPartitionClient)subPartitionClient); + } + + if (subPartitionClient instanceof SubKeyTemplatePartitionClient) { + return getSubKeyTemplatePartition((SubKeyTemplatePartitionClient)subPartitionClient); + } + + // sub hash + if (subPartitionClient instanceof SubHashPartitionClient) { + return getSubHashPartition((SubHashPartitionClient)subPartitionClient); + } + + //sub hash template + if (subPartitionClient instanceof SubHashTemplatePartitionClient) { + return getSubHashTemplatePartition((SubHashTemplatePartitionClient)subPartitionClient); + } + + //sub list + if (subPartitionClient instanceof SubListPartitionClient) { + return getSubListPartition((SubListPartitionClient)subPartitionClient); + } + + //sub list template + if (subPartitionClient instanceof SubListTemplatePartitionClient) { + return getSubListTemplatePartition((SubListTemplatePartitionClient)subPartitionClient); + } + + return null; + } + + private BaseSubPartition getSubHashTemplatePartition(SubHashTemplatePartitionClient subPartitionClient) { + BaseExpression expression = getExpression(subPartitionClient.getExpression()); + SubPartitionList subPartitionList = getSubPartitionList(subPartitionClient.getSubPartitionElementClientList()); + return new SubHashTemplatePartition(expression, subPartitionList); + } + + private BaseSubPartition getSubListTemplatePartition(SubListTemplatePartitionClient subPartitionClient) { + BaseExpression expression = getExpression(subPartitionClient.getExpression()); + List columnList = getIdentifiers(subPartitionClient.getColumnList()); + SubPartitionList subPartitionList = getSubPartitionList(subPartitionClient.getSubPartitionElementClientList()); + return new SubListTemplatePartition(expression, columnList, subPartitionList); + } + + private BaseSubPartition getSubKeyTemplatePartition(SubKeyTemplatePartitionClient subPartitionClient) { + List columnList = getIdentifiers(subPartitionClient.getColumnList()); + SubPartitionList subPartitionList = getSubPartitionList(subPartitionClient.getSubPartitionElementClients()); + return new SubKeyTemplatePartition(columnList, subPartitionList); + } + + private BaseSubPartition getSubRangeTemplatePartition(SubRangeTemplatePartitionClient subPartitionClient) { + BaseExpression expression = getExpression(subPartitionClient.getExpression()); + List columnList = getIdentifiers(subPartitionClient.getColumnList()); + SubPartitionList subPartitionList = getSubPartitionList(subPartitionClient.getSubPartitionElementClientList()); + return new SubRangeTemplatePartition(expression, columnList, subPartitionList); + } + + private static List getIdentifiers(List subPartitionClient) { + List columnList = null; + if (subPartitionClient != null) { + columnList = subPartitionClient.stream() + .map(Identifier::new) + .collect(Collectors.toList()); + } + return columnList; + } + + private SubPartitionList getSubPartitionList(List subPartitionElementClients) { + SubPartitionList subPartitionList = null; + if (subPartitionElementClients != null) { + List subPartitionElementList = subPartitionElementClients.stream() + .map(c -> getSubPartitionElement(c)).collect(Collectors.toList()); + subPartitionList = new SubPartitionList(subPartitionElementList); + } + return subPartitionList; + } + + private BaseExpression getExpression(String subPartitionClient) { + BaseExpression expression = null; + if (subPartitionClient != null) { + expression = (BaseExpression)extensionClientConverter.getLanguageParser().parseExpression(subPartitionClient); + } + return expression; + } + + @Override + public SubPartitionElementClient toSubPartitionElementClient(SubPartitionElement subPartitionElement) { + if (subPartitionElement == null) { + return null; + } + if (subPartitionElement instanceof SubListPartitionElement) { + return toListSubPartitionElementClient((SubListPartitionElement)subPartitionElement); + } + if (subPartitionElement instanceof SubHashPartitionElement) { + return getSubHashPartitionElementClient((SubHashPartitionElement)subPartitionElement); + } + if (subPartitionElement instanceof SubRangePartitionElement) { + return getSubRangePartitionElementClient((SubRangePartitionElement)subPartitionElement); + } + return null; + } + + private SubRangePartitionElementClient getSubRangePartitionElementClient(SubRangePartitionElement p) { + SubRangePartitionElement subPartitionElement = p; + SingleRangeClientPartition singleRangeClientPartition = extensionClientConverter.toSingleRangeClientPartition( + subPartitionElement.getSingleRangePartition()); + SubRangePartitionElementClient client = SubRangePartitionElementClient.builder() + .singleRangeClientPartition(singleRangeClientPartition) + .build(); + return client; + } + + private SubHashPartitionElementClient getSubHashPartitionElementClient(SubHashPartitionElement element) { + SubHashPartitionElement hashSubPartitionElement = element; + StringProperty stringProperty = extensionClientConverter.getStringProperty(hashSubPartitionElement.getProperty()); + return SubHashPartitionElementClient.builder() + .qualifiedName(hashSubPartitionElement.getQualifiedName().toString()) + .stringProperty(stringProperty) + .build(); + } + + private SubListPartitionElementClient toListSubPartitionElementClient(SubListPartitionElement listSubPartitionElement) { + String engine = null; + if (listSubPartitionElement.getProperty() != null) { + engine = listSubPartitionElement.getProperty().getValue(); + } + List expressionList = null; + if (listSubPartitionElement.getExpressionList() != null) { + expressionList = listSubPartitionElement.getExpressionList().stream() + .map(e -> extensionClientConverter.getRaw(e)).collect(Collectors.toList()); + } + return SubListPartitionElementClient.builder() + .defaultListExpr(listSubPartitionElement.getDefaultListExpr()) + .qualifiedName(listSubPartitionElement.getQualifiedName().toString()) + .expressionList(expressionList) + .engine(engine) + .build(); + } + + @Override + public SubPartitionElement getSubPartitionElement(SubPartitionElementClient subPartitionElementClient) { + if (subPartitionElementClient instanceof SubListPartitionElementClient) { + return getSubListPartitionElement((SubListPartitionElementClient)subPartitionElementClient); + } + + if (subPartitionElementClient instanceof SubRangePartitionElementClient) { + return getSubRangePartitionElement((SubRangePartitionElementClient)subPartitionElementClient); + } + + if (subPartitionElementClient instanceof SubHashPartitionElementClient) { + return getSubHashPartitionElement((SubHashPartitionElementClient)subPartitionElementClient); + } + + return null; + } + + private SubRangePartitionElement getSubRangePartitionElement(SubRangePartitionElementClient elementClient) { + SingleRangeClientPartition singleRangeClientPartition = elementClient.getSingleRangeClientPartition(); + SingleRangePartition subSingleRangePartition = (SingleRangePartition)extensionClientConverter.getPartitionDesc(singleRangeClientPartition); + SubRangePartitionElement rangeSubPartitionElement = new SubRangePartitionElement( + subSingleRangePartition + ); + return rangeSubPartitionElement; + } + + private SubHashPartitionElement getSubHashPartitionElement(SubHashPartitionElementClient s) { + Property property1 = null; + if (s.getStringProperty() != null) { + property1 = new Property(s.getStringProperty().getKey(), s.getStringProperty().getValue()); + } + return new SubHashPartitionElement(QualifiedName.of(s.getQualifiedName()), property1); + } + + private SubListPartitionElement getSubListPartitionElement(SubListPartitionElementClient ele) { + Property property2 = null; + if (ele.getEngine() != null) { + property2 = new Property(ExtensionPropertyKey.TABLE_ENGINE.getValue(), ele.getEngine()); + } + List expressionList2 = null; + if (ele.getExpressionList() != null) { + expressionList2 = ele.getExpressionList().stream().map( + expr -> { + return (BaseExpression)extensionClientConverter.getLanguageParser().parseExpression(expr); + } + ).collect(Collectors.toList()); + } + return new SubListPartitionElement(QualifiedName.of(ele.getQualifiedName()), ele.getDefaultListExpr(), expressionList2, property2); + } + + private SubListPartition getSubListPartition(SubListPartitionClient subPartitionClient) { + BaseExpression expression = getExpression(subPartitionClient.getExpression()); + List columnList = getIdentifiers(subPartitionClient.getColumnList()); + return new SubListPartition(expression, columnList); + } + + private SubHashPartition getSubHashPartition(SubHashPartitionClient subPartitionClient) { + SubHashPartitionClient subHashPartitionClient = subPartitionClient; + BaseExpression expression = getExpression(subHashPartitionClient.getExpression()); + LongLiteral count = null; + if (subHashPartitionClient.getSubpartitionCount() != null) { + count = new LongLiteral(String.valueOf(subHashPartitionClient.getSubpartitionCount())); + } + return new SubHashPartition(expression, count); + } + + private SubKeyPartition getSubKeyPartition(SubKeyPartitionClient subPartitionClient) { + SubKeyPartitionClient subKeyPartitionClient = subPartitionClient; + List collect = subKeyPartitionClient.getColumnList().stream() + .map(Identifier::new) + .collect(Collectors.toList()); + + Long subPartitionCount = subKeyPartitionClient.getSubPartitionCount(); + LongLiteral longLiteral = extensionClientConverter.getLongLiteral(subPartitionCount); + return new SubKeyPartition(collect, longLiteral); + } + + private BaseSubPartition getSubRangePartition(SubRangePartitionClient subPartitionClient) { + BaseSubPartition subPartition; + SubRangePartitionClient subRangePartitionClient = subPartitionClient; + String expression = subRangePartitionClient.getExpression(); + BaseExpression subExpression = getExpression(expression); + List subColumnList = null; + if (subRangePartitionClient.getColumnList() != null) { + subColumnList = subRangePartitionClient.getColumnList().stream().map( + c -> new Identifier(c) + ).collect(Collectors.toList()); + } + List singleRangePartitionList = subRangePartitionClient.getSingleRangePartitionList(); + List singlePartitionElementList = null; + if (singleRangePartitionList != null) { + singlePartitionElementList = singleRangePartitionList.stream() + .map(s -> extensionClientConverter.toRangePartitionElement(s)).collect(Collectors.toList()); + } + subPartition = new SubRangePartition(subExpression, subColumnList, singlePartitionElementList); + return subPartition; + } + +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/dto/HashPartitionProperty.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/dto/HashPartitionProperty.java new file mode 100644 index 0000000..c94abe4 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/dto/HashPartitionProperty.java @@ -0,0 +1,30 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.dto; + +import com.alibaba.fastjson.JSON; + +import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; +import com.aliyun.fastmodel.transform.oceanbase.client.dto.hash.HashPartitionClient; +import com.aliyun.fastmodel.transform.oceanbase.format.OceanBasePropertyKey; + +/** + * hash partition property + * + * @author panguanjing + * @date 2024/2/22 + */ +public class HashPartitionProperty extends BaseClientProperty { + + public HashPartitionProperty() { + setKey(OceanBasePropertyKey.PARTITION.getValue()); + } + + @Override + public String valueString() { + return JSON.toJSONString(value); + } + + @Override + public void setValueString(String value) { + this.setValue(JSON.parseObject(value, HashPartitionClient.class)); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/dto/hash/HashPartitionClient.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/dto/hash/HashPartitionClient.java new file mode 100644 index 0000000..0f79246 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/dto/hash/HashPartitionClient.java @@ -0,0 +1,29 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.dto.hash; + +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * HashPartitionClient + * + * @author panguanjing + * @date 2024/2/22 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class HashPartitionClient { + + private Long partitionCount; + + private String expression; + + private SubHashPartitionClient subHashPartitionClient; + + private List partitionElementClientList; +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/dto/hash/HashPartitionElementClient.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/dto/hash/HashPartitionElementClient.java new file mode 100644 index 0000000..8cce88c --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/dto/hash/HashPartitionElementClient.java @@ -0,0 +1,29 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.dto.hash; + +import java.util.List; + +import com.aliyun.fastmodel.transform.api.client.dto.property.StringProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Desc: + * + * @author panguanjing + * @date 2024/2/22 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class HashPartitionElementClient { + private String qualifiedName; + + private Long num; + + private StringProperty property; + + private List subPartitionList; +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/dto/hash/SubHashPartitionClient.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/dto/hash/SubHashPartitionClient.java new file mode 100644 index 0000000..debaf4f --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/dto/hash/SubHashPartitionClient.java @@ -0,0 +1,21 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.dto.hash; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Desc: + * + * @author panguanjing + * @date 2024/2/22 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SubHashPartitionClient { + private String expression; + private Long subpartitionCount; +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/dto/hash/SubHashPartitionElementClient.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/dto/hash/SubHashPartitionElementClient.java new file mode 100644 index 0000000..d554b41 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/dto/hash/SubHashPartitionElementClient.java @@ -0,0 +1,29 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.dto.hash; + +import com.aliyun.fastmodel.transform.api.client.dto.property.StringProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Desc: + * + * @author panguanjing + * @date 2024/2/22 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SubHashPartitionElementClient { + /** + * name + */ + private String qualifiedName; + + /** + * engine + */ + private StringProperty stringProperty; +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/SubPartitionClient.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/SubPartitionClient.java new file mode 100644 index 0000000..528ce80 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/SubPartitionClient.java @@ -0,0 +1,10 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.property; + +/** + * abstract sub partition client + * + * @author panguanjing + * @date 2024/2/25 + */ +public abstract class SubPartitionClient { +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/SubPartitionElementClient.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/SubPartitionElementClient.java new file mode 100644 index 0000000..1696783 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/SubPartitionElementClient.java @@ -0,0 +1,10 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.property; + +/** + * PartitionElementClient + * + * @author panguanjing + * @date 2024/2/28 + */ +public abstract class SubPartitionElementClient { +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/hash/HashPartitionClient.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/hash/HashPartitionClient.java new file mode 100644 index 0000000..4260608 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/hash/HashPartitionClient.java @@ -0,0 +1,30 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.property.hash; + +import java.util.List; + +import com.aliyun.fastmodel.transform.oceanbase.client.property.SubPartitionClient; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * HashPartitionClient + * + * @author panguanjing + * @date 2024/2/22 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class HashPartitionClient { + + private Long partitionCount; + + private String expression; + + private SubPartitionClient subPartitionClient; + + private List partitionElementClientList; +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/hash/HashPartitionElementClient.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/hash/HashPartitionElementClient.java new file mode 100644 index 0000000..6a23524 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/hash/HashPartitionElementClient.java @@ -0,0 +1,29 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.property.hash; + +import java.util.List; + +import com.aliyun.fastmodel.transform.api.client.dto.property.StringProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Desc: + * + * @author panguanjing + * @date 2024/2/22 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class HashPartitionElementClient { + private String qualifiedName; + + private Long num; + + private StringProperty property; + + private List subPartitionList; +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/hash/HashPartitionProperty.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/hash/HashPartitionProperty.java new file mode 100644 index 0000000..521f3eb --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/hash/HashPartitionProperty.java @@ -0,0 +1,29 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.property.hash; + +import com.alibaba.fastjson.JSON; + +import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; +import com.aliyun.fastmodel.transform.oceanbase.format.OceanBasePropertyKey; + +/** + * hash partition property + * + * @author panguanjing + * @date 2024/2/22 + */ +public class HashPartitionProperty extends BaseClientProperty { + + public HashPartitionProperty() { + setKey(OceanBasePropertyKey.PARTITION.getValue()); + } + + @Override + public String valueString() { + return JSON.toJSONString(value); + } + + @Override + public void setValueString(String value) { + this.setValue(JSON.parseObject(value, HashPartitionClient.class)); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/hash/SubHashPartitionClient.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/hash/SubHashPartitionClient.java new file mode 100644 index 0000000..4cc2eeb --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/hash/SubHashPartitionClient.java @@ -0,0 +1,22 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.property.hash; + +import com.aliyun.fastmodel.transform.oceanbase.client.property.SubPartitionClient; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Desc: + * + * @author panguanjing + * @date 2024/2/22 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SubHashPartitionClient extends SubPartitionClient { + private String expression; + private Long subpartitionCount; +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/hash/SubHashPartitionElementClient.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/hash/SubHashPartitionElementClient.java new file mode 100644 index 0000000..f0317a8 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/hash/SubHashPartitionElementClient.java @@ -0,0 +1,30 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.property.hash; + +import com.aliyun.fastmodel.transform.api.client.dto.property.StringProperty; +import com.aliyun.fastmodel.transform.oceanbase.client.property.SubPartitionElementClient; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Desc: + * + * @author panguanjing + * @date 2024/2/22 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SubHashPartitionElementClient extends SubPartitionElementClient { + /** + * name + */ + private String qualifiedName; + + /** + * engine + */ + private StringProperty stringProperty; +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/hash/SubHashTemplatePartitionClient.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/hash/SubHashTemplatePartitionClient.java new file mode 100644 index 0000000..92d87c1 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/hash/SubHashTemplatePartitionClient.java @@ -0,0 +1,27 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.property.hash; + +import java.util.List; + +import com.aliyun.fastmodel.transform.oceanbase.client.property.SubPartitionClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.SubPartitionElementClient; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Desc: + * + * @author panguanjing + * @date 2024/2/28 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class SubHashTemplatePartitionClient extends SubPartitionClient { + + private String expression; + + private List subPartitionElementClientList; +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/key/KeyPartitionClient.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/key/KeyPartitionClient.java new file mode 100644 index 0000000..634054a --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/key/KeyPartitionClient.java @@ -0,0 +1,31 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.property.key; + +import java.util.List; + +import com.aliyun.fastmodel.transform.oceanbase.client.property.SubPartitionClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.hash.HashPartitionElementClient; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * KeyPartitionClient + * + * @author panguanjing + * @date 2024/2/26 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class KeyPartitionClient { + + private Long partitionCount; + + private List columnList; + + private SubPartitionClient subPartitionClient; + + private List partitionElementClientList; +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/key/KeyPartitionProperty.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/key/KeyPartitionProperty.java new file mode 100644 index 0000000..02c26b1 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/key/KeyPartitionProperty.java @@ -0,0 +1,29 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.property.key; + +import com.alibaba.fastjson.JSON; + +import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; +import com.aliyun.fastmodel.transform.oceanbase.format.OceanBasePropertyKey; + +/** + * KeyPartitionProperty + * + * @author panguanjing + * @date 2024/2/22 + */ +public class KeyPartitionProperty extends BaseClientProperty { + + public KeyPartitionProperty() { + setKey(OceanBasePropertyKey.PARTITION.getValue()); + } + + @Override + public String valueString() { + return JSON.toJSONString(value); + } + + @Override + public void setValueString(String value) { + this.setValue(JSON.parseObject(value, KeyPartitionClient.class)); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/key/SubKeyPartitionClient.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/key/SubKeyPartitionClient.java new file mode 100644 index 0000000..e9f0932 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/key/SubKeyPartitionClient.java @@ -0,0 +1,26 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.property.key; + +import java.util.List; + +import com.aliyun.fastmodel.transform.oceanbase.client.property.SubPartitionClient; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * key partition client + * + * @author panguanjing + * @date 2024/2/22 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SubKeyPartitionClient extends SubPartitionClient { + private Long subPartitionCount; + + private List columnList; + +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/key/SubKeyTemplatePartitionClient.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/key/SubKeyTemplatePartitionClient.java new file mode 100644 index 0000000..1816514 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/key/SubKeyTemplatePartitionClient.java @@ -0,0 +1,27 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.property.key; + +import java.util.List; + +import com.aliyun.fastmodel.transform.oceanbase.client.property.SubPartitionClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.SubPartitionElementClient; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * SubKeyTemplatePartitionClient + * + * @author panguanjing + * @date 2024/2/28 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SubKeyTemplatePartitionClient extends SubPartitionClient { + + private List columnList; + + private List subPartitionElementClients; +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/list/ListPartitionClient.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/list/ListPartitionClient.java new file mode 100644 index 0000000..3dc4536 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/list/ListPartitionClient.java @@ -0,0 +1,31 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.property.list; + +import java.util.List; + +import com.aliyun.fastmodel.transform.oceanbase.client.property.SubPartitionClient; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * ListPartitionClient + * + * @author panguanjing + * @date 2024/2/23 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class ListPartitionClient { + private String expression; + + private List columns; + + private Long partitionCount; + + private SubPartitionClient subPartitionClient; + + private List partitionElementClientList; +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/list/ListPartitionElementClient.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/list/ListPartitionElementClient.java new file mode 100644 index 0000000..9c90665 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/list/ListPartitionElementClient.java @@ -0,0 +1,32 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.property.list; + +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * ListPartitionElementClient + * + * @author panguanjing + * @date 2024/2/26 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class ListPartitionElementClient { + private String qualifiedName; + + private Boolean defaultExpr; + + private List expressionList; + + private Long num; + + private String engine; + + private List subPartitionElementList; +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/list/ListPartitionProperty.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/list/ListPartitionProperty.java new file mode 100644 index 0000000..982b5c8 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/list/ListPartitionProperty.java @@ -0,0 +1,29 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.property.list; + +import com.alibaba.fastjson.JSON; + +import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; +import com.aliyun.fastmodel.transform.oceanbase.format.OceanBasePropertyKey; + +/** + * list partition property + * + * @author panguanjing + * @date 2024/2/26 + */ +public class ListPartitionProperty extends BaseClientProperty { + + public ListPartitionProperty() { + setKey(OceanBasePropertyKey.PARTITION.getValue()); + } + + @Override + public String valueString() { + return JSON.toJSONString(value); + } + + @Override + public void setValueString(String value) { + this.setValue(JSON.parseObject(value, ListPartitionClient.class)); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/list/ListSubPartitionElementClient.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/list/ListSubPartitionElementClient.java new file mode 100644 index 0000000..2bf0fb0 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/list/ListSubPartitionElementClient.java @@ -0,0 +1,28 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.property.list; + +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * ListSubPartitionElementClient + * + * @author panguanjing + * @date 2024/2/26 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class ListSubPartitionElementClient { + private String qualifiedName; + + private Boolean defaultListExpr; + + private List expressionList; + + private String engine; +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/list/SubListPartitionClient.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/list/SubListPartitionClient.java new file mode 100644 index 0000000..808c9cd --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/list/SubListPartitionClient.java @@ -0,0 +1,26 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.property.list; + +import java.util.List; + +import com.aliyun.fastmodel.transform.oceanbase.client.property.SubPartitionClient; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * SubListPartitionClient + * + * @author panguanjing + * @date 2024/2/26 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SubListPartitionClient extends SubPartitionClient { + + private String expression; + + private List columnList; +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/list/SubListPartitionElementClient.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/list/SubListPartitionElementClient.java new file mode 100644 index 0000000..2eaa3b8 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/list/SubListPartitionElementClient.java @@ -0,0 +1,29 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.property.list; + +import java.util.List; + +import com.aliyun.fastmodel.transform.oceanbase.client.property.SubPartitionElementClient; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * ListSubPartitionElementClient + * + * @author panguanjing + * @date 2024/2/26 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SubListPartitionElementClient extends SubPartitionElementClient { + private String qualifiedName; + + private Boolean defaultListExpr; + + private List expressionList; + + private String engine; +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/list/SubListTemplatePartitionClient.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/list/SubListTemplatePartitionClient.java new file mode 100644 index 0000000..e2dfba0 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/list/SubListTemplatePartitionClient.java @@ -0,0 +1,30 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.property.list; + +import java.util.List; + +import com.aliyun.fastmodel.transform.oceanbase.client.property.SubPartitionClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.SubPartitionElementClient; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Desc: + * + * @author panguanjing + * @date 2024/2/18 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class SubListTemplatePartitionClient extends SubPartitionClient { + + private String expression; + + private List columnList; + + private List subPartitionElementClientList; + +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/range/RangePartitionClient.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/range/RangePartitionClient.java new file mode 100644 index 0000000..731bd55 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/range/RangePartitionClient.java @@ -0,0 +1,32 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.property.range; + +import java.util.List; + +import com.aliyun.fastmodel.transform.oceanbase.client.property.SubPartitionClient; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * Desc: + * + * @author panguanjing + * @date 2024/2/22 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class RangePartitionClient { + + private List columns; + + private Long partitionCount; + + private String baseExpression; + + private List rangePartitionElementClients; + + private SubPartitionClient rangeSubPartitionClient; +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/range/RangePartitionElementClient.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/range/RangePartitionElementClient.java new file mode 100644 index 0000000..7fd274e --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/range/RangePartitionElementClient.java @@ -0,0 +1,28 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.property.range; + +import java.util.List; + +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.SingleRangeClientPartition; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * RangePartitionElementClient + * + * @author panguanjing + * @date 2024/2/22 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class RangePartitionElementClient { + + private Long id; + + private SingleRangeClientPartition singleRangeClientPartition; + + private List rangeSubPartitionElementClients; +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/range/RangePartitionProperty.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/range/RangePartitionProperty.java new file mode 100644 index 0000000..8897fc7 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/range/RangePartitionProperty.java @@ -0,0 +1,29 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.property.range; + +import com.alibaba.fastjson.JSON; + +import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; +import com.aliyun.fastmodel.transform.oceanbase.format.OceanBasePropertyKey; + +/** + * RangePartitionProperty + * + * @author panguanjing + * @date 2024/2/22 + */ +public class RangePartitionProperty extends BaseClientProperty { + + public RangePartitionProperty() { + setKey(OceanBasePropertyKey.PARTITION.getValue()); + } + + @Override + public String valueString() { + return JSON.toJSONString(value); + } + + @Override + public void setValueString(String value) { + this.value = JSON.parseObject(value, RangePartitionClient.class); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/range/SubRangePartitionClient.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/range/SubRangePartitionClient.java new file mode 100644 index 0000000..c4685d7 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/range/SubRangePartitionClient.java @@ -0,0 +1,27 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.property.range; + +import java.util.List; + +import com.aliyun.fastmodel.transform.oceanbase.client.property.SubPartitionClient; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * RangeSubPartitionClient + * + * @author panguanjing + * @date 2024/2/22 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SubRangePartitionClient extends SubPartitionClient { + private String expression; + + private List columnList; + + private List singleRangePartitionList; +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/range/SubRangePartitionElementClient.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/range/SubRangePartitionElementClient.java new file mode 100644 index 0000000..6b47042 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/range/SubRangePartitionElementClient.java @@ -0,0 +1,22 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.property.range; + +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.SingleRangeClientPartition; +import com.aliyun.fastmodel.transform.oceanbase.client.property.SubPartitionElementClient; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * range sub partition element client + * + * @author panguanjing + * @date 2024/2/22 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SubRangePartitionElementClient extends SubPartitionElementClient { + private SingleRangeClientPartition singleRangeClientPartition; +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/range/SubRangeTemplatePartitionClient.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/range/SubRangeTemplatePartitionClient.java new file mode 100644 index 0000000..b968843 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/client/property/range/SubRangeTemplatePartitionClient.java @@ -0,0 +1,30 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.property.range; + +import java.util.List; + +import com.aliyun.fastmodel.transform.oceanbase.client.property.SubPartitionClient; +import com.aliyun.fastmodel.transform.oceanbase.client.property.SubPartitionElementClient; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * SubRangeTemplatePartition + * + * @author panguanjing + * @date 2024/2/18 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SubRangeTemplatePartitionClient extends SubPartitionClient { + + private String expression; + + private List columnList; + + private List subPartitionElementClientList; + +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/context/OceanBaseContext.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/context/OceanBaseContext.java new file mode 100644 index 0000000..2e3a35c --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/context/OceanBaseContext.java @@ -0,0 +1,32 @@ +package com.aliyun.fastmodel.transform.oceanbase.context; + +import com.aliyun.fastmodel.transform.api.context.TransformContext; + +/** + * OceanBaseContext + * + * @author panguanjing + * @date 2024/2/2 + */ +public class OceanBaseContext extends TransformContext { + public OceanBaseContext(TransformContext context) { + super(context); + } + + public OceanBaseContext(Builder tBuilder) { + super(tBuilder); + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder extends TransformContext.Builder { + + @Override + public OceanBaseContext build() { + return new OceanBaseContext(this); + } + } + +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/format/OceanBaseMysqlExpressionVisitor.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/format/OceanBaseMysqlExpressionVisitor.java new file mode 100644 index 0000000..e404719 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/format/OceanBaseMysqlExpressionVisitor.java @@ -0,0 +1,49 @@ +package com.aliyun.fastmodel.transform.oceanbase.format; + +import java.util.stream.Collectors; + +import com.aliyun.fastmodel.core.tree.expr.atom.TableOrColumn; +import com.aliyun.fastmodel.transform.api.format.DefaultExpressionVisitor; +import com.aliyun.fastmodel.transform.oceanbase.context.OceanBaseContext; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.OceanBaseMysqlCharDataType; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +/** + * DorisExpressionVisitor + * + * @author panguanjing + * @date 2024/1/20 + */ +public class OceanBaseMysqlExpressionVisitor extends DefaultExpressionVisitor implements OceanBaseMysqlAstVisitor { + public OceanBaseMysqlExpressionVisitor(OceanBaseContext context) {} + + @Override + public String visitTableOrColumn(TableOrColumn tableOrColumn, Void context) { + return super.visitTableOrColumn(tableOrColumn, context); + } + + @Override + public String visitOceanBaseCharDataType(OceanBaseMysqlCharDataType oceanBaseMysqlCharDataType, Void context) { + StringBuilder stringBuilder = new StringBuilder(); + String dataTypeName = oceanBaseMysqlCharDataType.getDataTypeName(); + stringBuilder.append(dataTypeName); + if (CollectionUtils.isNotEmpty(oceanBaseMysqlCharDataType.getArguments())) { + stringBuilder.append(oceanBaseMysqlCharDataType.getArguments().stream() + .map(this::process) + .collect(Collectors.joining(",", "(", ")"))); + } + if (oceanBaseMysqlCharDataType.getCharsetKey() != null) { + stringBuilder.append(StringUtils.SPACE + oceanBaseMysqlCharDataType.getCharsetKey().getValue()); + } + if (oceanBaseMysqlCharDataType.getCharsetName() != null) { + stringBuilder.append(StringUtils.SPACE + oceanBaseMysqlCharDataType.getCharsetName()); + } + if (oceanBaseMysqlCharDataType.getCollation() != null) { + stringBuilder.append(" COLLATE "); + stringBuilder.append(oceanBaseMysqlCharDataType.getCollation()); + } + return stringBuilder.toString(); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/format/OceanBaseMysqlOutVisitor.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/format/OceanBaseMysqlOutVisitor.java new file mode 100644 index 0000000..7032fa7 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/format/OceanBaseMysqlOutVisitor.java @@ -0,0 +1,843 @@ +package com.aliyun.fastmodel.transform.oceanbase.format; + +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; + +import com.aliyun.fastmodel.core.formatter.FastModelVisitor; +import com.aliyun.fastmodel.core.tree.Property; +import com.aliyun.fastmodel.core.tree.QualifiedName; +import com.aliyun.fastmodel.core.tree.datatype.BaseDataType; +import com.aliyun.fastmodel.core.tree.expr.BaseExpression; +import com.aliyun.fastmodel.core.tree.expr.Identifier; +import com.aliyun.fastmodel.core.tree.expr.atom.FunctionCall; +import com.aliyun.fastmodel.core.tree.expr.literal.BooleanLiteral; +import com.aliyun.fastmodel.core.tree.expr.literal.LongLiteral; +import com.aliyun.fastmodel.core.tree.statement.table.AddCols; +import com.aliyun.fastmodel.core.tree.statement.table.ColumnDefinition; +import com.aliyun.fastmodel.core.tree.statement.table.CreateTable; +import com.aliyun.fastmodel.core.tree.statement.table.PartitionedBy; +import com.aliyun.fastmodel.core.tree.statement.table.SetTableProperties; +import com.aliyun.fastmodel.core.tree.statement.table.UnSetTableProperties; +import com.aliyun.fastmodel.core.tree.statement.table.constraint.BaseConstraint; +import com.aliyun.fastmodel.core.tree.statement.table.index.IndexColumnName; +import com.aliyun.fastmodel.core.tree.statement.table.index.IndexExpr; +import com.aliyun.fastmodel.core.tree.statement.table.index.IndexSortKey; +import com.aliyun.fastmodel.core.tree.statement.table.index.TableIndex; +import com.aliyun.fastmodel.core.tree.util.IdentifierUtil; +import com.aliyun.fastmodel.core.tree.util.PropertyUtil; +import com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.CheckExpressionConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.ForeignKeyConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.UniqueKeyExprConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.SingleRangePartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.LessThanPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.ListPartitionValue; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.PartitionValue; +import com.aliyun.fastmodel.transform.api.format.PropertyValueType; +import com.aliyun.fastmodel.transform.oceanbase.context.OceanBaseContext; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.OceanBaseHashPartitionBy; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.OceanBaseKeyPartitionBy; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.OceanBaseListPartitionBy; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.OceanBaseRangePartitionBy; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.SubHashPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.SubKeyPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.SubListPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.SubRangePartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.HashPartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.ListPartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.RangePartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubHashPartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubListPartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubPartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubPartitionList; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubRangePartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.template.SubHashTemplatePartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.template.SubKeyTemplatePartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.template.SubListTemplatePartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.template.SubRangeTemplatePartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; + +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.COLUMN_AUTO_INCREMENT; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_PARTITION_RAW; +import static java.util.stream.Collectors.joining; + +/** + * out visitor + * + * @author panguanjing + * @date 2024/2/2 + */ +public class OceanBaseMysqlOutVisitor extends FastModelVisitor implements OceanBaseMysqlAstVisitor { + private final OceanBaseContext context; + + public OceanBaseMysqlOutVisitor(OceanBaseContext context) { + this.context = context; + } + + @Override + public Boolean visitCreateTable(CreateTable node, Integer indent) { + builder.append("CREATE"); + if (node.getCreateOrReplace() != null && node.getCreateOrReplace()) { + builder.append(" OR REPLACE"); + } + builder.append(" TABLE "); + if (node.isNotExists()) { + builder.append("IF NOT EXISTS "); + } + String tableName = getCode(node.getQualifiedName()); + builder.append(tableName); + int newIndent = indent + 1; + if (!node.isColumnEmpty()) { + builder.append(" \n(\n"); + String elementIndent = indentString(newIndent); + builder.append(formatColumnList(node.getColumnDefines(), elementIndent)); + if (!node.isConstraintEmpty()) { + Iterator iterator = node.getConstraintStatements().stream() + .iterator(); + while (iterator.hasNext()) { + builder.append(",\n"); + process(iterator.next(), newIndent); + } + } + if (!node.isIndexEmpty()) { + Iterator iterator = node.getTableIndexList().iterator(); + while (iterator.hasNext()) { + builder.append(",\n"); + process(iterator.next(), newIndent); + } + } + builder.append(newLine(")")); + } + if (node.getComment() != null) { + builder.append(formatComment(node.getComment(), isEndNewLine(builder.toString()))); + } + if (node.getPartitionedBy() != null) { + if (!isEndNewLine(builder.toString())) { + builder.append("\n"); + } + PartitionedBy partitionedBy = node.getPartitionedBy(); + process(partitionedBy); + } else { + String propertyValue = PropertyUtil.getPropertyValue(node.getProperties(), TABLE_PARTITION_RAW.getValue()); + if (StringUtils.isNotBlank(propertyValue)) { + if (!isEndNewLine(builder.toString())) { + builder.append("\n"); + } + builder.append(propertyValue); + } + } + List properties = node.getProperties(); + builder.append(formatProperty(properties)); + removeNewLine(builder); + return true; + } + + @Override + protected String formatColumnDefinition(ColumnDefinition column, Integer max) { + BaseDataType dataType = column.getDataType(); + String col = formatColName(column.getColName(), max); + StringBuilder sb = new StringBuilder().append(col); + if (dataType != null) { + sb.append(" ").append(formatDataType(dataType)); + } + boolean isPrimary = column.getPrimary() != null && column.getPrimary(); + if (isPrimary) { + sb.append(" PRIMARY KEY"); + } + List columnProperties = column.getColumnProperties(); + boolean isNotNull = column.getNotNull() != null && column.getNotNull(); + if (isNotNull) { + sb.append(" NOT NULL"); + } + if (column.getDefaultValue() != null) { + String expressionValue = formatExpression(column.getDefaultValue()); + if (column.getDefaultValue() instanceof FunctionCall) { + sb.append(" DEFAULT (").append(expressionValue).append(")"); + } else { + sb.append(" DEFAULT ").append(expressionValue); + } + } + //auto increment + String autoIncrement = PropertyUtil.getPropertyValue(columnProperties, COLUMN_AUTO_INCREMENT.getValue()); + if (StringUtils.equalsIgnoreCase(BooleanLiteral.TRUE, autoIncrement)) { + sb.append(" ").append("AUTO_INCREMENT"); + } + sb.append(formatComment(column.getComment(), isEndNewLine(sb.toString()))); + return sb.toString(); + } + + /** + * table_option + * 配置信息 + * + * @param properties + * @return + */ + @Override + protected String formatProperty(List properties) { + if (properties == null) { + return StringUtils.EMPTY; + } + StringBuilder stringBuilder = new StringBuilder(); + for (Property property : properties) { + String name = property.getName(); + ExtensionPropertyKey byValue = ExtensionPropertyKey.getByValue(name); + if (byValue != null && !byValue.isSupportPrint()) { + continue; + } + if (StringUtils.equalsIgnoreCase(name, OceanBasePropertyKey.COMMENT.getValue())) { + continue; + } + if (StringUtils.equalsIgnoreCase(name, OceanBasePropertyKey.SORT_KEY.getValue())) { + stringBuilder.append(OceanBasePropertyKey.SORT_KEY.getValue()).append("("); + stringBuilder.append(property.getValue()); + stringBuilder.append(")"); + stringBuilder.append(StringUtils.LF); + continue; + } + OceanBasePropertyKey oceanBasePropertyKey = OceanBasePropertyKey.getByValue(name); + if (oceanBasePropertyKey == null) { + stringBuilder.append(name); + stringBuilder.append("="); + stringBuilder.append(formatStringLiteral(property.getValue())); + stringBuilder.append(StringUtils.LF); + continue; + } + if (StringUtils.equalsIgnoreCase(name, OceanBasePropertyKey.CHARSET_KEY.getValue())) { + stringBuilder.append("DEFAULT"); + stringBuilder.append(" CHARSET ").append(property.getValue()); + stringBuilder.append(StringUtils.LF); + continue; + } + if (StringUtils.equalsIgnoreCase(name, OceanBasePropertyKey.COLLATE.getValue())) { + stringBuilder.append("COLLATE "); + stringBuilder.append(property.getValue()); + stringBuilder.append(StringUtils.LF); + continue; + } + PropertyValueType valueType = oceanBasePropertyKey.getValueType(); + if (valueType == PropertyValueType.IDENTIFIER || valueType == PropertyValueType.NUMBER_LITERAL) { + stringBuilder.append(name); + stringBuilder.append(" "); + stringBuilder.append(property.getValue()); + stringBuilder.append(StringUtils.LF); + continue; + } + if (valueType == PropertyValueType.STRING_LITERAL) { + stringBuilder.append(name); + stringBuilder.append(" "); + stringBuilder.append(formatStringLiteral(property.getValue())); + stringBuilder.append(StringUtils.LF); + } + } + return stringBuilder.toString(); + } + + @Override + public Boolean visitOceanBaseHashPartitionBy(OceanBaseHashPartitionBy oceanBaseHashPartitionBy, Integer context) { + // PARTITION BY HASH LeftParen expr RightParen subpartition_option? (PARTITIONS INTNUM)? opt_hash_partition_list? + builder.append("PARTITION BY HASH ("); + String expr = formatExpression(oceanBaseHashPartitionBy.getExpression()); + builder.append(expr); + builder.append(")"); + if (oceanBaseHashPartitionBy.getSubPartition() != null) { + builder.append(" "); + process(oceanBaseHashPartitionBy.getSubPartition()); + } + appendPartitionCount(oceanBaseHashPartitionBy.getPartitionCount()); + appendHashPartitionElements(oceanBaseHashPartitionBy.getHashPartitionElements()); + return true; + } + + private void appendHashPartitionElements(List hashPartitionElements) { + if (!CollectionUtils.isNotEmpty(hashPartitionElements)) { + return; + } + builder.append("\n("); + Iterator iterator = hashPartitionElements.iterator(); + HashPartitionElement next = iterator.next(); + process(next); + while (iterator.hasNext()) { + builder.append(",\n"); + next = iterator.next(); + process(next); + } + builder.append(")"); + } + + private void appendPartitionCount(LongLiteral partitionCount) { + if (partitionCount != null) { + builder.append(" PARTITIONS "); + builder.append(partitionCount.getValue()); + } + } + + @Override + public Boolean visitOceanBaseRangePartitionBy(OceanBaseRangePartitionBy oceanBaseRangePartitionBy, Integer context) { + /** + * PARTITION BY RANGE LeftParen expr RightParen subpartition_option? (PARTITIONS INTNUM)? opt_range_partition_list + * | PARTITION BY RANGE COLUMNS LeftParen column_name_list RightParen subpartition_option? (PARTITIONS INTNUM)? opt_range_partition_list + */ + builder.append("PARTITION BY RANGE "); + if (oceanBaseRangePartitionBy.getBaseExpression() != null) { + builder.append("("); + String expr = formatExpression(oceanBaseRangePartitionBy.getBaseExpression()); + builder.append(expr); + builder.append(")"); + } + if (oceanBaseRangePartitionBy.getColumnDefinitions() != null) { + appendColumnList(oceanBaseRangePartitionBy.getColumnDefinitions().stream().map(x -> x.getColName()).collect(Collectors.toList())); + } + if (oceanBaseRangePartitionBy.getSubPartition() != null) { + builder.append(" "); + process(oceanBaseRangePartitionBy.getSubPartition()); + } + appendPartitionCount(oceanBaseRangePartitionBy.getPartitionCount()); + if (CollectionUtils.isNotEmpty(oceanBaseRangePartitionBy.getSingleRangePartitionList())) { + int index = 1; + builder.append("\n("); + List singleRangePartitionList = oceanBaseRangePartitionBy.getSingleRangePartitionList(); + Iterator iterator = singleRangePartitionList.iterator(); + RangePartitionElement next = iterator.next(); + process(next, index); + while (iterator.hasNext()) { + builder.append(",\n"); + next = iterator.next(); + process(next, index); + } + builder.append(")"); + } + return true; + } + + private void appendColumnList(List columnList) { + builder.append("COLUMNS ("); + String columns = columnList.stream().map( + c -> formatExpression(c) + ).collect(Collectors.joining(",")); + builder.append(columns); + builder.append(")"); + } + + @Override + public Boolean visitRangePartitionElement(RangePartitionElement rangePartitionElement, Integer context) { + //PARTITION relation_factor VALUES LESS THAN range_partition_expr (ID INTNUM)? partition_attributes_option? subpartition_list? + builder.append("PARTITION"); + SingleRangePartition singleRangePartition = rangePartitionElement.getSingleRangePartition(); + builder.append(" ").append(formatExpression(singleRangePartition.getName())); + builder.append(" VALUES LESS THAN "); + process(rangePartitionElement.getSingleRangePartition().getPartitionKey()); + if (rangePartitionElement.getIdCount() != null) { + builder.append(" ID ").append(rangePartitionElement.getIdCount().getValue()); + } + if (rangePartitionElement.getSingleRangePartition().getPropertyList() != null) { + List properties = rangePartitionElement.getSingleRangePartition().getPropertyList(); + String attribute = properties.stream().map(p -> { + return p.getName() + "=" + p.getValue(); + }).collect(Collectors.joining(",")); + builder.append(attribute); + } + if (rangePartitionElement.getSubPartitionList() != null) { + process(rangePartitionElement.getSubPartitionList()); + } + return true; + } + + @Override + public Boolean visitLessThanPartitionKey(LessThanPartitionKey lessThanPartitionKey, Integer context) { + if (lessThanPartitionKey.isMaxValue()) { + builder.append("MAXVALUE"); + } else { + ListPartitionValue partitionValues = lessThanPartitionKey.getPartitionValues(); + builder.append("("); + List partitionValueList = partitionValues.getPartitionValueList(); + String collect = partitionValueList.stream().map(p -> { + if (p.isMaxValue()) { + return "MAXVALUE"; + } + return formatExpression(p.getStringLiteral()); + }).collect(Collectors.joining(",")); + builder.append(collect); + builder.append(")"); + } + return true; + } + + @Override + public Boolean visitOceanBaseListPartitionBy(OceanBaseListPartitionBy oceanBaseListPartitionBy, Integer context) { + //PARTITION BY BISON_LIST LeftParen expr RightParen subpartition_option? (PARTITIONS INTNUM)? opt_list_partition_list + // | PARTITION BY BISON_LIST COLUMNS LeftParen column_name_list RightParen subpartition_option? (PARTITIONS INTNUM)? + // opt_list_partition_list + builder.append("PARTITION BY LIST "); + BaseExpression baseExpression = oceanBaseListPartitionBy.getBaseExpression(); + if (baseExpression != null) { + builder.append("("); + String e = formatExpression(baseExpression); + builder.append(e); + builder.append(")"); + } else { + builder.append("COLUMNS("); + String columnNameList = oceanBaseListPartitionBy.getColumnDefinitions().stream().map(c -> { + return formatColName(c.getColName(), 0); + }).collect(Collectors.joining(",")); + builder.append(columnNameList); + builder.append(")"); + } + if (oceanBaseListPartitionBy.getSubPartition() != null) { + builder.append(" "); + process(oceanBaseListPartitionBy.getSubPartition()); + } + appendPartitionCount(oceanBaseListPartitionBy.getPartitionCount()); + int index = 1; + if (oceanBaseListPartitionBy.getPartitionElementList() != null) { + builder.append("\n("); + Iterator iterator = oceanBaseListPartitionBy.getPartitionElementList().iterator(); + ListPartitionElement next = iterator.next(); + process(next, index); + while (iterator.hasNext()) { + builder.append(",\n"); + next = iterator.next(); + process(next, index); + } + builder.append(")"); + } + return true; + } + + @Override + public Boolean visitOceanBaseKeyPartitionBy(OceanBaseKeyPartitionBy oceanBaseKeyPartitionBy, Integer context) { + //PARTITION BY KEY LeftParen column_name_list? RightParen subpartition_option? (PARTITIONS INTNUM)? opt_hash_partition_list? + builder.append("PARTITION BY KEY ("); + if (oceanBaseKeyPartitionBy.getColumnDefinitions() != null) { + String columnList = oceanBaseKeyPartitionBy.getColumnDefinitions().stream() + .map(c -> formatExpression(c.getColName())).collect(Collectors.joining(",")); + builder.append(columnList); + } + builder.append(")"); + if (oceanBaseKeyPartitionBy.getSubPartition() != null) { + process(oceanBaseKeyPartitionBy.getSubPartition()); + } + if (oceanBaseKeyPartitionBy.getPartitionCount() != null) { + appendPartitionCount(oceanBaseKeyPartitionBy.getPartitionCount()); + } + appendHashPartitionElements(oceanBaseKeyPartitionBy.getHashPartitionElements()); + return true; + } + + @Override + public Boolean visitListPartitionElement(ListPartitionElement listPartitionElement, Integer context) { + // PARTITION relation_factor VALUES IN list_partition_expr (ID INTNUM)? partition_attributes_option? subpartition_list? + builder.append("PARTITION "); + QualifiedName qualifiedName = listPartitionElement.getQualifiedName(); + builder.append(formatName(qualifiedName)); + builder.append(" VALUES IN "); + if (BooleanUtils.isTrue(listPartitionElement.getDefaultExpr())) { + builder.append("(DEFAULT)"); + } else { + List expressionList = listPartitionElement.getExpressionList(); + String listExpr = expressionList.stream().map(this::formatExpression).collect(Collectors.joining(",")); + builder.append("("); + builder.append(listExpr); + builder.append(")"); + } + if (listPartitionElement.getNum() != null) { + builder.append(" ID "); + builder.append(listPartitionElement.getNum().getValue()); + } + if (listPartitionElement.getProperty() != null) { + Property property = listPartitionElement.getProperty(); + builder.append(property.getName() + "=" + property.getValue()); + } + if (listPartitionElement.getSubPartitionList() != null) { + process(listPartitionElement.getSubPartitionList()); + } + return true; + } + + @Override + public Boolean visitHashPartitionElement(HashPartitionElement hashPartitionElement, Integer context) { + //PARTITION relation_factor (ID INTNUM)? partition_attributes_option? subpartition_list? + builder.append("PARTITION "); + QualifiedName qualifiedName = hashPartitionElement.getQualifiedName(); + builder.append(formatName(qualifiedName)); + if (hashPartitionElement.getNum() != null) { + builder.append(" ID "); + builder.append(hashPartitionElement.getNum().getValue()); + } + if (hashPartitionElement.getProperty() != null) { + Property property = hashPartitionElement.getProperty(); + builder.append(property.getName() + "=" + property.getValue()); + } + if (hashPartitionElement.getSubPartitionList() != null) { + process(hashPartitionElement.getSubPartitionList(), 1); + } + return true; + } + + @Override + public Boolean visitSubPartitionList(SubPartitionList subPartitionList, Integer context) { + builder.append("(\n"); + Iterator iterator = subPartitionList.getSubPartitionElementList().iterator(); + process(iterator.next(), context); + while (iterator.hasNext()) { + builder.append(",\n"); + process(iterator.next(), context); + } + builder.append("\n)"); + return true; + } + + @Override + public Boolean visitHashSubPartitionElement(SubHashPartitionElement hashSubPartitionElement, Integer context) { + // SUBPARTITION relation_factor partition_attributes_option? + String indent = indentString(context); + builder.append(indent); + builder.append("SUBPARTITION "); + builder.append(formatName(hashSubPartitionElement.getQualifiedName())); + if (hashSubPartitionElement.getProperty() != null) { + Property property = hashSubPartitionElement.getProperty(); + builder.append(property.getName() + "=" + property.getValue()); + } + return true; + } + + @Override + public Boolean visitListSubPartitionElement(SubListPartitionElement listSubPartitionElement, Integer context) { + // SUBPARTITION relation_factor VALUES IN list_partition_expr partition_attributes_option? + String indent = indentString(context); + builder.append(indent); + builder.append("SUBPARTITION "); + builder.append(formatName(listSubPartitionElement.getQualifiedName())); + builder.append(" VALUES IN "); + if (listSubPartitionElement.getExpressionList() != null) { + List expressionList = listSubPartitionElement.getExpressionList(); + String listExpr = expressionList.stream().map(this::formatExpression).collect(Collectors.joining(",")); + builder.append("("); + builder.append(listExpr); + builder.append(")"); + } + if (listSubPartitionElement.getProperty() != null) { + Property property = listSubPartitionElement.getProperty(); + builder.append(property.getName() + "=" + property.getValue()); + } + return true; + } + + @Override + public Boolean visitRangeSubPartitionElement(SubRangePartitionElement rangeSubPartitionElement, Integer context) { + //SUBPARTITION relation_factor VALUES LESS THAN range_partition_expr partition_attributes_option? + String indent = indentString(context); + builder.append(indent); + builder.append("SUBPARTITION "); + SingleRangePartition singleRangePartition = rangeSubPartitionElement.getSingleRangePartition(); + builder.append(" ").append(formatExpression(singleRangePartition.getName())); + builder.append(" VALUES LESS THAN "); + process(rangeSubPartitionElement.getSingleRangePartition().getPartitionKey()); + if (rangeSubPartitionElement.getSingleRangePartition().getPropertyList() != null) { + List properties = singleRangePartition.getPropertyList(); + String attribute = properties.stream().map(p -> { + return p.getName() + "=" + p.getValue(); + }).collect(Collectors.joining(",")); + builder.append(attribute); + } + return true; + } + + @Override + public Boolean visitSubRangeTemplatePartition(SubRangeTemplatePartition subRangeTemplatePartition, Integer context) { + // SUBPARTITION BY RANGE LeftParen expr RightParen SUBPARTITION TEMPLATE opt_range_subpartition_list + // | SUBPARTITION BY RANGE COLUMNS LeftParen column_name_list RightParen SUBPARTITION TEMPLATE opt_range_subpartition_list + builder.append("\nSUBPARTITION BY RANGE "); + if (subRangeTemplatePartition.getColumnList() != null) { + appendColumnList(subRangeTemplatePartition.getColumnList()); + } else { + builder.append("("); + String expr = formatExpression(subRangeTemplatePartition.getExpression()); + builder.append(expr); + builder.append(")"); + } + builder.append("\nSUBPARTITION TEMPLATE"); + if (subRangeTemplatePartition.getSubPartitionList() != null) { + builder.append(" "); + process(subRangeTemplatePartition.getSubPartitionList()); + } + return true; + } + + @Override + public Boolean visitSubHashTemplatePartition(SubHashTemplatePartition subHashTemplatePartition, Integer context) { + //SUBPARTITION BY HASH LeftParen expr RightParen SUBPARTITION TEMPLATE opt_hash_subpartition_list + builder.append("\nSUBPARTITION BY HASH "); + if (subHashTemplatePartition.getExpression() != null) { + builder.append("("); + String expr = formatExpression(subHashTemplatePartition.getExpression()); + builder.append(expr); + builder.append(")"); + } + builder.append("\nSUBPARTITION TEMPLATE"); + if (subHashTemplatePartition.getSubPartitionList() != null) { + builder.append(" "); + process(subHashTemplatePartition.getSubPartitionList()); + } + return true; + } + + @Override + public Boolean visitSubListTemplatePartition(SubListTemplatePartition subListTemplatePartition, Integer context) { + //SUBPARTITION BY BISON_LIST LeftParen expr RightParen SUBPARTITION TEMPLATE opt_list_subpartition_list + // | SUBPARTITION BY BISON_LIST COLUMNS LeftParen column_name_list RightParen SUBPARTITION TEMPLATE opt_list_subpartition_list + builder.append("\nSUBPARTITION BY LIST "); + if (subListTemplatePartition.getColumnList() != null) { + appendColumnList(subListTemplatePartition.getColumnList()); + } else { + appendExpression(subListTemplatePartition.getExpression()); + } + builder.append("\nSUBPARTITION TEMPLATE"); + if (subListTemplatePartition.getSubPartitionList() != null) { + builder.append(" "); + process(subListTemplatePartition.getSubPartitionList()); + } + return true; + } + + private void appendExpression(BaseExpression expression) { + builder.append("("); + String expr = formatExpression(expression); + builder.append(expr); + builder.append(")"); + } + + @Override + public Boolean visitSubKeyTemplatePartition(SubKeyTemplatePartition subKeyTemplatePartition, Integer context) { + //SUBPARTITION BY KEY LeftParen column_name_list RightParen SUBPARTITION TEMPLATE opt_hash_subpartition_list + builder.append("\nSUBPARTITION BY KEY "); + appendColumnList(subKeyTemplatePartition.getColumnList()); + builder.append("\nSUBPARTITION TEMPLATE"); + if (subKeyTemplatePartition.getSubPartitionList() != null) { + builder.append(" "); + process(subKeyTemplatePartition.getSubPartitionList()); + } + return true; + } + + @Override + public Boolean visitSubHashPartition(SubHashPartition subHashPartition, Integer context) { + //SUBPARTITION BY HASH LeftParen expr RightParen (SUBPARTITIONS INTNUM)? + builder.append("SUBPARTITION BY HASH "); + appendExpression(subHashPartition.getExpression()); + if (subHashPartition.getSubpartitionCount() != null) { + builder.append(" SUBPARTITIONS "); + builder.append(subHashPartition.getSubpartitionCount().getValue()); + } + return true; + } + + @Override + public Boolean visitSubRangePartition(SubRangePartition subRangePartition, Integer context) { + //SUBPARTITION BY (RANGE|BISON_LIST) COLUMNS LeftParen column_name_list RightParen + //SUBPARTITION BY (RANGE|BISON_LIST) LeftParen expr RightParen + builder.append("SUBPARTITION BY RANGE "); + if (subRangePartition.getColumnList() != null) { + appendColumnList(subRangePartition.getColumnList()); + } else { + appendExpression(subRangePartition.getExpression()); + } + return true; + } + + @Override + public Boolean visitSubListPartition(SubListPartition subListPartition, Integer context) { + //SUBPARTITION BY (RANGE|BISON_LIST) COLUMNS LeftParen column_name_list RightParen + //SUBPARTITION BY (RANGE|BISON_LIST) LeftParen expr RightParen + builder.append("SUBPARTITION BY LIST "); + if (subListPartition.getColumnList() != null) { + appendColumnList(subListPartition.getColumnList()); + } else { + appendExpression(subListPartition.getExpression()); + } + return true; + } + + @Override + public Boolean visitSubKeyPartition(SubKeyPartition subKeyPartition, Integer context) { + //SUBPARTITION BY KEY LeftParen column_name_list RightParen (SUBPARTITIONS INTNUM)? + builder.append("SUBPARTITION BY KEY ("); + List columnList = subKeyPartition.getColumnList(); + String e = columnList.stream().map(c -> c.getValue()).collect(Collectors.joining(",")); + builder.append(e); + builder.append(")"); + if (subKeyPartition.getSubpartitionCount() != null) { + builder.append(" SUBPARTITIONS "); + builder.append(subKeyPartition.getSubpartitionCount().getValue()); + } + return true; + } + + @Override + public Boolean visitCheckExpressionConstraint(CheckExpressionConstraint checkExpressionConstraint, Integer context) { + //(CONSTRAINT opt_constraint_name)? CHECK LeftParen expr RightParen check_state? + Identifier name = checkExpressionConstraint.getName(); + if (!IdentifierUtil.isSysIdentifier(name)) { + builder.append(indentString(context)).append(CONSTRAINT).append(formatExpression(name)); + builder.append(" CHECK"); + } else { + builder.append(indentString(context)).append("CHECK"); + } + appendExpression(checkExpressionConstraint.getExpression()); + if (checkExpressionConstraint.getEnforced() != null) { + if (checkExpressionConstraint.getEnforced()) { + builder.append(" ENFORCED"); + } else { + builder.append(" NOT ENFORCED"); + } + } + return true; + } + + @Override + public Boolean visitForeignKeyConstraint(ForeignKeyConstraint foreignKeyConstraint, Integer context) { + // (CONSTRAINT opt_constraint_name)? FOREIGN KEY index_name? LeftParen column_name_list RightParen references_clause + // REFERENCES relation_factor LeftParen column_name_list RightParen (MATCH match_action)? (opt_reference_option_list reference_option)? + Identifier name = foreignKeyConstraint.getName(); + if (!IdentifierUtil.isSysIdentifier(name)) { + builder.append(indentString(context)).append(CONSTRAINT).append(formatExpression(name)); + builder.append(" FOREIGN KEY"); + } else { + builder.append(indentString(context)).append("FOREIGN KEY"); + } + if (foreignKeyConstraint.getIndexName() != null) { + builder.append(" ").append(formatExpression(foreignKeyConstraint.getIndexName())); + } + builder.append("("); + List colNames = foreignKeyConstraint.getColNames(); + String collect = colNames.stream().map(c -> formatExpression(c)).collect(joining(",")); + builder.append(collect).append(")"); + //reference + builder.append(" REFERENCES "); + builder.append(formatName(foreignKeyConstraint.getReferenceTable())); + + String referenceColumns = foreignKeyConstraint.getReferenceColNames().stream().map(c -> formatExpression(c)).collect(joining(",")); + builder.append("(").append(referenceColumns).append(")"); + + if (foreignKeyConstraint.getMatchAction() != null) { + builder.append(" MATCH ").append(foreignKeyConstraint.getMatchAction().name()); + } + + if (foreignKeyConstraint.getReferenceAction() != null) { + //ON (DELETE|UPDATE) reference_action + builder.append(" ON "); + builder.append(foreignKeyConstraint.getReferenceOperator().name()); + builder.append(" ").append(foreignKeyConstraint.getReferenceAction().getValue()); + } + return true; + } + + @Override + public Boolean visitPartitionedBy(PartitionedBy partitionedBy, Integer context) { + if (partitionedBy instanceof OceanBaseHashPartitionBy) { + OceanBaseHashPartitionBy oceanBaseHashPartitionBy = (OceanBaseHashPartitionBy)partitionedBy; + return visitOceanBaseHashPartitionBy(oceanBaseHashPartitionBy, context); + } + if (partitionedBy instanceof OceanBaseListPartitionBy) { + OceanBaseListPartitionBy oceanBaseListPartitionBy = (OceanBaseListPartitionBy)partitionedBy; + return visitOceanBaseListPartitionBy(oceanBaseListPartitionBy, context); + } + if (partitionedBy instanceof OceanBaseKeyPartitionBy) { + OceanBaseKeyPartitionBy oceanBaseKeyPartitionBy = (OceanBaseKeyPartitionBy)partitionedBy; + return visitOceanBaseKeyPartitionBy(oceanBaseKeyPartitionBy, context); + } + if (partitionedBy instanceof OceanBaseRangePartitionBy) { + OceanBaseRangePartitionBy oceanBaseRangePartitionBy = (OceanBaseRangePartitionBy)partitionedBy; + return visitOceanBaseRangePartitionBy(oceanBaseRangePartitionBy, context); + } + return super.visitPartitionedBy(partitionedBy, context); + + } + + @Override + public Boolean visitUniqueKeyExprConstraint(UniqueKeyExprConstraint uniqueKeyExprConstraint, Integer context) { + // UNIQUE key_or_index? index_name? index_using_algorithm? LeftParen sort_column_list RightParen opt_index_options? (partition_option | + // auto_partition_option)? + Identifier name = uniqueKeyExprConstraint.getName(); + if (!IdentifierUtil.isSysIdentifier(name)) { + builder.append(indentString(context)).append(CONSTRAINT).append(formatExpression(name)); + builder.append(" UNIQUE KEY("); + } else { + builder.append(indentString(context)).append("UNIQUE KEY("); + } + Iterator iterator = uniqueKeyExprConstraint.getIndexSortKeys().iterator(); + process(iterator.next(), context); + while (iterator.hasNext()) { + builder.append(","); + builder.append(iterator.next()); + } + builder.append(")"); + return true; + } + + @Override + public Boolean visitIndexColumnName(IndexColumnName indexColumnName, Integer context) { + //column_name (LeftParen INTNUM RightParen)? (ASC | DESC)? (ID INTNUM)? + builder.append(formatExpression(indexColumnName.getColumnName())); + if (indexColumnName.getColumnLength() != null) { + builder.append("("); + builder.append(indexColumnName.getColumnLength().getValue()); + builder.append(")"); + } + if (indexColumnName.getSortType() != null) { + builder.append(" "); + builder.append(indexColumnName.getSortType().name()); + } + return true; + } + + @Override + public Boolean visitIndexExpr(IndexExpr indexExpr, Integer context) { + // LeftParen expr RightParen (ASC | DESC)? (ID INTNUM)? + builder.append("("); + String expr = formatExpression(indexExpr.getExpression()); + builder.append(expr); + builder.append(")"); + if (indexExpr.getSortType() != null) { + builder.append(" ").append(indexExpr.getSortType().name()); + } + return true; + } + + @Override + public Boolean visitAddCols(AddCols addCols, Integer context) { + builder.append("ALTER TABLE ").append(getCode(addCols.getQualifiedName())); + List columnDefineList = addCols.getColumnDefineList(); + String collect = columnDefineList.stream().map( + c -> "\nADD COLUMN " + formatColumnDefinition(c, context + 1) + ).collect(joining(",")); + builder.append(collect); + return true; + } + + @Override + public Boolean visitSetTableProperties(SetTableProperties setTableProperties, Integer context) { + builder.append("ALTER TABLE ").append(getCode(setTableProperties.getQualifiedName())); + builder.append(" "); + builder.append(formatProperty(setTableProperties.getProperties())); + return true; + } + + @Override + public Boolean visitUnSetTableProperties(UnSetTableProperties unSetTableProperties, Integer context) { + builder.append("ALTER TABLE ").append(getCode(unSetTableProperties.getQualifiedName())); + builder.append(" "); + String collect = unSetTableProperties.getPropertyKeys().stream().map(x -> x + "=''").collect(joining(",")); + builder.append(collect); + return true; + } + + @Override + protected String formatExpression(BaseExpression baseExpression) { + return new OceanBaseMysqlExpressionVisitor(context).process(baseExpression); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/format/OceanBasePropertyKey.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/format/OceanBasePropertyKey.java new file mode 100644 index 0000000..c12a6bb --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/format/OceanBasePropertyKey.java @@ -0,0 +1,139 @@ +package com.aliyun.fastmodel.transform.oceanbase.format; + +import com.aliyun.fastmodel.transform.api.format.PropertyKey; +import com.aliyun.fastmodel.transform.api.format.PropertyValueType; +import lombok.Getter; +import org.apache.commons.lang3.StringUtils; + +/** + * OceanBasePropertyKey + * + * @author panguanjing + * @date 2024/1/20 + */ +@Getter +public enum OceanBasePropertyKey implements PropertyKey { + /** + * on update + */ + SORT_KEY("sortkey"), + + /** + * table mode + */ + TABLE_MODE("table_mode"), + + /** + * DUPLICATE_SCOPE + */ + DUPLICATE_SCOPE("duplicate_scope"), + + /** + * comment + */ + COMMENT("comment"), + + /** + * COMPRESSION + */ + COMPRESSION("compression"), + + /** + * charset key + */ + CHARSET_KEY("charset_key", PropertyValueType.IDENTIFIER), + + /** + * collate + */ + COLLATE("collate", PropertyValueType.IDENTIFIER), + + /** + * row format + */ + ROW_FORMAT("row_format", PropertyValueType.IDENTIFIER), + + /** + * PCTFREE + */ + PCTFREE("pctfree", PropertyValueType.NUMBER_LITERAL), + + /** + * progressive_merge_num + */ + PROGRESSIVE_MERGE_NUM("progressive_merge_num", PropertyValueType.NUMBER_LITERAL), + /** + * block size + */ + BLOCK_SIZE("block_size", PropertyValueType.NUMBER_LITERAL), + /** + * table id + */ + TABLE_ID("table_id", PropertyValueType.NUMBER_LITERAL), + /** + * replica num + */ + REPLICA_NUM("replica_num", PropertyValueType.NUMBER_LITERAL), + /** + * storage format version + */ + STORAGE_FORMAT_VERSION("storage_format_version", PropertyValueType.NUMBER_LITERAL), + /** + * tablet size + */ + TABLET_SIZE("tablet_size", PropertyValueType.NUMBER_LITERAL), + /** + * id + */ + MAX_USED_PART_ID("max_used_part_id", PropertyValueType.NUMBER_LITERAL), + + /** + * PARALLEL + */ + PARALLEL("parallel", PropertyValueType.NUMBER_LITERAL), + + /** + * Partition + */ + PARTITION("partition", PropertyValueType.EXPRESSION); + + private final String value; + + private final boolean supportPrint; + + private final PropertyValueType valueType; + + OceanBasePropertyKey(String value) { + this(value, true, PropertyValueType.STRING_LITERAL); + } + + OceanBasePropertyKey(String value, PropertyValueType propertyValueType) { + this(value, true, propertyValueType); + } + + OceanBasePropertyKey(String value, boolean supportPrint, PropertyValueType valueType) { + this.value = value; + this.supportPrint = supportPrint; + this.valueType = valueType; + } + + public static OceanBasePropertyKey getByValue(String value) { + OceanBasePropertyKey[] keys = OceanBasePropertyKey.values(); + for (OceanBasePropertyKey oceanBasePropertyKey : keys) { + if (StringUtils.equalsIgnoreCase(oceanBasePropertyKey.getValue(), value)) { + return oceanBasePropertyKey; + } + } + return null; + } + + @Override + public String getValue() { + return this.value; + } + + @Override + public boolean isSupportPrint() { + return this.supportPrint; + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/OceanBaseMysqlAstBuilder.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/OceanBaseMysqlAstBuilder.java new file mode 100644 index 0000000..5053373 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/OceanBaseMysqlAstBuilder.java @@ -0,0 +1,1714 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser; + +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import com.aliyun.fastmodel.common.parser.ParserHelper; +import com.aliyun.fastmodel.common.utils.StripUtils; +import com.aliyun.fastmodel.core.tree.Comment; +import com.aliyun.fastmodel.core.tree.ListNode; +import com.aliyun.fastmodel.core.tree.Node; +import com.aliyun.fastmodel.core.tree.Property; +import com.aliyun.fastmodel.core.tree.QualifiedName; +import com.aliyun.fastmodel.core.tree.datatype.BaseDataType; +import com.aliyun.fastmodel.core.tree.datatype.DataTypeParameter; +import com.aliyun.fastmodel.core.tree.datatype.NumericParameter; +import com.aliyun.fastmodel.core.tree.expr.ArithmeticBinaryExpression; +import com.aliyun.fastmodel.core.tree.expr.BaseExpression; +import com.aliyun.fastmodel.core.tree.expr.BitOperationExpression; +import com.aliyun.fastmodel.core.tree.expr.ComparisonExpression; +import com.aliyun.fastmodel.core.tree.expr.Identifier; +import com.aliyun.fastmodel.core.tree.expr.IsConditionExpression; +import com.aliyun.fastmodel.core.tree.expr.LogicalBinaryExpression; +import com.aliyun.fastmodel.core.tree.expr.atom.Cast; +import com.aliyun.fastmodel.core.tree.expr.atom.FunctionCall; +import com.aliyun.fastmodel.core.tree.expr.atom.InPredicate; +import com.aliyun.fastmodel.core.tree.expr.atom.IntervalExpression; +import com.aliyun.fastmodel.core.tree.expr.atom.TableOrColumn; +import com.aliyun.fastmodel.core.tree.expr.enums.ArithmeticOperator; +import com.aliyun.fastmodel.core.tree.expr.enums.BitOperator; +import com.aliyun.fastmodel.core.tree.expr.enums.ComparisonOperator; +import com.aliyun.fastmodel.core.tree.expr.enums.IntervalQualifiers; +import com.aliyun.fastmodel.core.tree.expr.enums.IsType; +import com.aliyun.fastmodel.core.tree.expr.enums.LikeOperator; +import com.aliyun.fastmodel.core.tree.expr.enums.LogicalOperator; +import com.aliyun.fastmodel.core.tree.expr.literal.BaseLiteral; +import com.aliyun.fastmodel.core.tree.expr.literal.BooleanLiteral; +import com.aliyun.fastmodel.core.tree.expr.literal.DateLiteral; +import com.aliyun.fastmodel.core.tree.expr.literal.DecimalLiteral; +import com.aliyun.fastmodel.core.tree.expr.literal.ListStringLiteral; +import com.aliyun.fastmodel.core.tree.expr.literal.LongLiteral; +import com.aliyun.fastmodel.core.tree.expr.literal.NullLiteral; +import com.aliyun.fastmodel.core.tree.expr.literal.StringLiteral; +import com.aliyun.fastmodel.core.tree.expr.literal.TimestampLiteral; +import com.aliyun.fastmodel.core.tree.expr.similar.BetweenPredicate; +import com.aliyun.fastmodel.core.tree.expr.similar.LikePredicate; +import com.aliyun.fastmodel.core.tree.expr.similar.NotExpression; +import com.aliyun.fastmodel.core.tree.statement.table.ColumnDefinition; +import com.aliyun.fastmodel.core.tree.statement.table.CreateTable; +import com.aliyun.fastmodel.core.tree.statement.table.PartitionedBy; +import com.aliyun.fastmodel.core.tree.statement.table.TableElement; +import com.aliyun.fastmodel.core.tree.statement.table.constraint.BaseConstraint; +import com.aliyun.fastmodel.core.tree.statement.table.constraint.DefaultValueConstraint; +import com.aliyun.fastmodel.core.tree.statement.table.constraint.NotNullConstraint; +import com.aliyun.fastmodel.core.tree.statement.table.constraint.PrimaryConstraint; +import com.aliyun.fastmodel.core.tree.statement.table.constraint.UniqueConstraint; +import com.aliyun.fastmodel.core.tree.statement.table.index.IndexColumnName; +import com.aliyun.fastmodel.core.tree.statement.table.index.IndexExpr; +import com.aliyun.fastmodel.core.tree.statement.table.index.IndexSortKey; +import com.aliyun.fastmodel.core.tree.statement.table.index.SortType; +import com.aliyun.fastmodel.core.tree.statement.table.index.TableIndex; +import com.aliyun.fastmodel.core.tree.util.IdentifierUtil; +import com.aliyun.fastmodel.transform.api.context.ReverseContext; +import com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.Algorithm; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.CheckExpressionConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.ForeignKeyConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.ForeignKeyConstraint.MatchAction; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.ForeignKeyConstraint.ReferenceAction; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.ForeignKeyConstraint.ReferenceOperator; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.UniqueKeyExprConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.SingleRangePartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.LessThanPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.ListPartitionValue; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.PartitionKey; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.PartitionValue; +import com.aliyun.fastmodel.transform.oceanbase.format.OceanBasePropertyKey; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Binary_type_iContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Bit_exprContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Bit_type_iContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Blob_type_iContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Bool_priContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Bool_type_iContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Character_type_iContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Column_attributeContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Column_definitionContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Column_definition_refContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Column_nameContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Column_refContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Complex_func_exprContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Complex_string_literalContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Constraint_nameContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Create_table_stmtContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Cur_timestamp_funcContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Data_typeContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Data_type_precisionContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Date_year_type_iContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Datetime_type_iContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.ExprContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Float_type_iContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Geo_type_iContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Hash_partition_elementContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Hash_partition_optionContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Hash_subpartition_elementContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Index_nameContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Index_using_algorithmContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Int_type_iContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Json_type_iContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Key_partition_optionContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.List_partition_elementContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.List_partition_optionContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.List_subpartition_elementContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.LiteralContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Normal_relation_factorContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Now_or_signed_literalContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Number_literalContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Number_type_iContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Opt_column_attribute_listContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Opt_column_partition_optionContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Opt_constraint_nameContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Opt_hash_subpartition_listContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Opt_list_subpartition_listContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Opt_range_subpartition_listContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Out_of_line_constraintContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Out_of_line_indexContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Out_of_line_unique_indexContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Parallel_optionContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Partition_attributes_optionContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Precision_decimal_numContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Precision_int_numContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.PredicateContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Range_exprContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Range_partition_elementContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Range_partition_exprContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Range_partition_optionContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Range_subpartition_elementContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Reference_actionContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Reference_optionContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.References_clauseContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Relation_factorContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Relation_nameContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Relation_name_or_stringContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Simple_func_exprContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Sort_column_keyContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Sql_stmtContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Stmt_listContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.String_length_iContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.String_val_listContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Subpartition_individual_optionContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Subpartition_template_optionContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Table_optionContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Table_option_listContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser.Text_type_iContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParserBaseVisitor; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.OceanBaseMysqlCharDataType; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.OceanBaseMysqlCharDataType.CharsetKey; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.OceanBaseMysqlDataTypeName; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.OceanBaseMysqlGenericDataType; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.OceanBaseMysqlGenericDataType.SignEnum; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.OceanBaseHashPartitionBy; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.OceanBaseKeyPartitionBy; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.OceanBaseListPartitionBy; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.OceanBaseRangePartitionBy; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.BaseSubPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.SubHashPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.SubKeyPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.SubListPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.SubRangePartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.HashPartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.ListPartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.RangePartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubHashPartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubListPartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubPartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubPartitionList; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubRangePartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.template.SubHashTemplatePartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.template.SubKeyTemplatePartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.template.SubListTemplatePartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.template.SubRangeTemplatePartition; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import org.antlr.v4.runtime.tree.TerminalNode; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; + +/** + * OceanBaseAstBuilder + * + * @author panguanjing + * @date 2024/2/2 + */ +public class OceanBaseMysqlAstBuilder extends OBParserBaseVisitor { + + private final ReverseContext reverseContext; + + public OceanBaseMysqlAstBuilder(ReverseContext reverseContext) { + this.reverseContext = reverseContext; + } + + @Override + public Node visitSql_stmt(Sql_stmtContext ctx) { + return visit(ctx.stmt_list()); + } + + @Override + public Node visitStmt_list(Stmt_listContext ctx) { + return visit(ctx.stmt()); + } + + @Override + public Node visitCreate_table_stmt(Create_table_stmtContext ctx) { + QualifiedName qualifiedName = (QualifiedName)visit(ctx.relation_factor()); + boolean isNotExist = ctx.EXISTS() != null && ctx.not() != null; + List visit = ParserHelper.visit(this, ctx.table_element_list().table_element(), TableElement.class); + List columnDefinitions = visit.stream().filter( + t -> t instanceof ColumnDefinition + ).map(t -> { + return (ColumnDefinition)t; + }).collect(Collectors.toList()); + + // + List constraints = visit.stream().filter( + t -> t instanceof BaseConstraint + ).map(t -> (BaseConstraint)t).collect(Collectors.toList()); + + PartitionedBy partitionedBy = toPartitionBy(ctx); + List properties = buildProperties(ctx); + List tableIndexList = visit.stream().filter( + t -> t instanceof TableIndex + ).map(t -> (TableIndex)t).collect(Collectors.toList()); + return CreateTable.builder() + .ifNotExist(isNotExist) + .columns(columnDefinitions) + .tableName(qualifiedName) + .constraints(constraints) + .partition(partitionedBy) + .properties(properties) + .comment(getComment(properties)) + .tableIndex(tableIndexList) + .build(); + } + + @Override + public Node visitOut_of_line_index(Out_of_line_indexContext ctx) { + Identifier indexName = null; + if (ctx.index_name() != null) { + indexName = (Identifier)visit(ctx.index_name()); + } + List indexColumnNames = null; + if (ctx.sort_column_list() != null) { + indexColumnNames = ParserHelper.visit(this, ctx.sort_column_list().sort_column_key(), IndexSortKey.class); + } + List property = null; + if (ctx.opt_index_options() != null) { + property = ParserHelper.visit(this, ctx.opt_index_options().index_option(), Property.class); + } + TableIndex tableIndex = new TableIndex( + indexName, indexColumnNames, property + ); + return tableIndex; + } + + @Override + public Node visitIndex_name(Index_nameContext ctx) { + return visit(ctx.relation_name()); + } + + @Override + public Node visitSort_column_key(Sort_column_keyContext ctx) { + Identifier columnName = null; + if (ctx.column_name() != null) { + columnName = (Identifier)visit(ctx.column_name()); + } + LongLiteral columnLength = null; + SortType sortType = null; + if (ctx.DESC() != null) { + sortType = SortType.DESC; + } + if (ctx.ASC() != null) { + sortType = SortType.ASC; + } + if (columnName != null) { + if (ctx.LeftParen() != null && ctx.INTNUM() != null) { + columnLength = new LongLiteral(ctx.INTNUM(0).getText()); + } + return new IndexColumnName(columnName, columnLength, sortType); + } else { + BaseExpression baseExpression = (BaseExpression)visit(ctx.expr()); + return new IndexExpr(baseExpression, sortType); + } + } + + private Comment getComment(List properties) { + if (properties == null || properties.isEmpty()) { + return null; + } + Optional property = properties.stream().filter( + p -> StringUtils.equalsIgnoreCase(p.getName(), OceanBasePropertyKey.COMMENT.getValue()) + ).findFirst(); + if (property.isEmpty()) { + return null; + } + return new Comment(property.get().getValue()); + } + + @Override + public Node visitRelation_factor(Relation_factorContext ctx) { + if (ctx.normal_relation_factor() != null) { + return visit(ctx.normal_relation_factor()); + } + return visit(ctx.dot_relation_factor()); + } + + @Override + public Node visitRelation_name(Relation_nameContext ctx) { + return ParserHelper.getIdentifier(ctx); + } + + @Override + public Node visitNormal_relation_factor(Normal_relation_factorContext ctx) { + List list = ParserHelper.visit(this, ctx.relation_name(), Identifier.class); + return QualifiedName.of(list); + } + + @Override + public Node visitColumn_name(Column_nameContext ctx) { + return ParserHelper.getIdentifier(ctx); + } + + @Override + public Node visitColumn_definition(Column_definitionContext ctx) { + Identifier colName = (Identifier)visit(ctx.column_definition_ref()); + BaseDataType baseDataType = (BaseDataType)visit(ctx.data_type()); + ListNode node = null; + if (ctx.opt_column_attribute_list() != null) { + node = (ListNode)visit(ctx.opt_column_attribute_list()); + } + List properties = toColumnProperty(node); + return ColumnDefinition.builder() + .colName(colName) + .dataType(baseDataType) + .comment(toComment(node)) + .notNull(toNotNull(node)) + .primary(toPrimary(node)) + .defaultValue(toDefaultValue(node)) + .properties(properties) + .build(); + } + + private List toColumnProperty(ListNode ctx) { + List listNode = ParserHelper.getListNode(ctx, Property.class); + return listNode; + } + + private Comment toComment(ListNode optColumnAttributeListContext) { + if (optColumnAttributeListContext == null) { + return null; + } + Comment comment = ParserHelper.getNode(optColumnAttributeListContext, Comment.class); + return comment; + } + + @Override + public Node visitColumn_definition_ref(Column_definition_refContext ctx) { + return visit(ctx.column_name()); + } + + @Override + public Node visitOut_of_line_constraint(Out_of_line_constraintContext ctx) { + Identifier constraintName = null; + if (ctx.opt_constraint_name() != null) { + constraintName = (Identifier)visit(ctx.opt_constraint_name()); + } else { + constraintName = IdentifierUtil.sysIdentifier(); + } + //primary key + if (ctx.out_of_line_primary_index() != null) { + List colNames = ParserHelper.visit(this, + ctx.out_of_line_primary_index().column_name_list().column_name(), Identifier.class); + PrimaryConstraint primaryConstraint = new PrimaryConstraint( + constraintName, + colNames + ); + return primaryConstraint; + } + //unique key + Out_of_line_unique_indexContext outOfLineUniqueIndexContext = ctx.out_of_line_unique_index(); + if (outOfLineUniqueIndexContext != null) { + List sortKeys = ParserHelper.visit(this, + outOfLineUniqueIndexContext.sort_column_list().sort_column_key(), IndexSortKey.class); + Algorithm algorithm = null; + Identifier indexName = null; + Index_nameContext indexNameContext = outOfLineUniqueIndexContext.index_name(); + if (indexNameContext != null) { + indexName = (Identifier)visit(indexNameContext); + } + Index_using_algorithmContext indexUsingAlgorithmContext = outOfLineUniqueIndexContext.index_using_algorithm(); + if (indexUsingAlgorithmContext != null) { + if (indexUsingAlgorithmContext.BTREE() != null) { + algorithm = Algorithm.BTREE; + } + if (indexUsingAlgorithmContext.HASH() != null) { + algorithm = Algorithm.HASH; + } + } + UniqueKeyExprConstraint uniqueConstraint = new UniqueKeyExprConstraint( + constraintName, indexName, sortKeys, algorithm + ); + return uniqueConstraint; + } + //check constraint + if (ctx.CHECK() != null) { + BaseExpression expression = null; + if (ctx.expr() != null) { + expression = (BaseExpression)visit(ctx.expr()); + } + Boolean enforced = null; + if (ctx.check_state() != null) { + enforced = ctx.check_state().NOT() == null; + } + return new CheckExpressionConstraint(constraintName, expression, enforced); + } + + //foreign reference + if (ctx.FOREIGN() != null) { + return getForeignKeyConstraint(ctx, constraintName); + } + return super.visitOut_of_line_constraint(ctx); + } + + private ForeignKeyConstraint getForeignKeyConstraint(Out_of_line_constraintContext ctx, Identifier constraintName) { + List colNames = null; + if (ctx.column_name_list() != null) { + colNames = ParserHelper.visit(this, ctx.column_name_list().column_name(), Identifier.class); + } + QualifiedName referenceTable = null; + Identifier indexName = null; + if (ctx.index_name() != null) { + indexName = (Identifier)visit(ctx.index_name()); + } + List referenceColNames = null; + References_clauseContext referencesClauseContext = ctx.references_clause(); + MatchAction matchAction = null; + ReferenceAction referenceAction = null; + ReferenceOperator referenceOperator = null; + referenceTable = (QualifiedName)visit(referencesClauseContext.relation_factor()); + referenceColNames = ParserHelper.visit(this, referencesClauseContext.column_name_list().column_name(), Identifier.class); + if (referencesClauseContext.match_action() != null) { + matchAction = MatchAction.valueOf(referencesClauseContext.match_action().getText().toUpperCase()); + } + Reference_optionContext referenceOptionContext = referencesClauseContext.reference_option(); + if (referenceOptionContext != null) { + if (referenceOptionContext.UPDATE() != null) { + referenceOperator = ReferenceOperator.UPDATE; + } else if (referenceOptionContext.DELETE() != null) { + referenceOperator = ReferenceOperator.DELETE; + } + Reference_actionContext referenceActionContext = referenceOptionContext.reference_action(); + referenceAction = getAction(referenceActionContext); + } + return new ForeignKeyConstraint(constraintName, indexName, colNames, referenceTable, referenceColNames, matchAction, referenceOperator, + referenceAction); + } + + private ReferenceAction getAction(Reference_actionContext referenceActionContext) { + if (referenceActionContext == null) { + return null; + } + if (referenceActionContext.RESTRICT() != null) { + return ReferenceAction.RESTRICT; + } + if (referenceActionContext.CASCADE() != null) { + return ReferenceAction.CASCADE; + } + if (referenceActionContext.NO() != null && referenceActionContext.ACTION() != null) { + return ReferenceAction.NO_ACTION; + } + if (referenceActionContext.SET() != null && referenceActionContext.DEFAULT() != null) { + return ReferenceAction.SET_DEFAULT; + } + if (referenceActionContext.SET() != null && referenceActionContext.NULLX() != null) { + return ReferenceAction.SET_NULL; + } + return null; + } + + @Override + public Node visitData_type(Data_typeContext ctx) { + return super.visitData_type(ctx); + } + + @Override + public Node visitInt_type_i(Int_type_iContext ctx) { + Identifier identifier = null; + if (ctx.BIGINT() != null) { + identifier = new Identifier(ctx.BIGINT().getText()); + } + if (ctx.INTEGER() != null) { + identifier = new Identifier(ctx.INTEGER().getText()); + } + + if (ctx.TINYINT() != null) { + identifier = new Identifier(ctx.TINYINT().getText()); + } + + if (ctx.SMALLINT() != null) { + identifier = new Identifier(ctx.SMALLINT().getText()); + } + + if (ctx.MEDIUMINT() != null) { + identifier = new Identifier(ctx.MEDIUMINT().getText()); + } + + List arguments = getDataTypeParameters(ctx.precision_int_num()); + + Boolean zeroFill = null; + if (ctx.ZEROFILL() != null) { + zeroFill = true; + } + SignEnum signEnum = null; + if (ctx.UNSIGNED() != null) { + signEnum = SignEnum.UNSIGNED; + } else if (ctx.SIGNED() != null) { + signEnum = SignEnum.SIGNED; + } + return new OceanBaseMysqlGenericDataType( + identifier, arguments, + zeroFill, signEnum + ); + } + + private List getDataTypeParameters(Precision_int_numContext ctx) { + List arguments = Lists.newArrayList(); + if (ctx == null) { + return arguments; + } + for (TerminalNode terminalNode : ctx.INTNUM()) { + NumericParameter numericParameter = new NumericParameter(terminalNode.getText()); + arguments.add(numericParameter); + } + return arguments; + } + + @Override + public Node visitFloat_type_i(Float_type_iContext ctx) { + String name = null; + if (ctx.FLOAT() != null) { + name = ctx.FLOAT().getText(); + } + if (ctx.DOUBLE() != null) { + if (ctx.PRECISION() != null) { + name = OceanBaseMysqlDataTypeName.DOUBLE_PRECISION.getValue(); + } else { + name = OceanBaseMysqlDataTypeName.DOUBLE.getValue(); + } + } + Boolean zeroFill = ctx.ZEROFILL() != null; + SignEnum signEnum = null; + if (ctx.UNSIGNED() != null) { + signEnum = SignEnum.UNSIGNED; + } else if (ctx.SIGNED() != null) { + signEnum = SignEnum.SIGNED; + } + + List dataTypeParameters = null; + + if (ctx.precision_int_num() != null) { + dataTypeParameters = getDataTypeParameters(ctx.precision_int_num()); + } + if (ctx.data_type_precision() != null) { + dataTypeParameters = getDataTypeParameterByPrecision(ctx.data_type_precision()); + } + return new OceanBaseMysqlGenericDataType( + name, dataTypeParameters, zeroFill, signEnum + ); + } + + private List getDataTypeParameterByPrecision(Data_type_precisionContext dataTypePrecisionContext) { + if (dataTypePrecisionContext.precision_int_num() != null) { + return getDataTypeParameters(dataTypePrecisionContext.precision_int_num()); + } + Precision_decimal_numContext precisionDecimalNumContext = dataTypePrecisionContext.precision_decimal_num(); + NumericParameter numericParameter = new NumericParameter(precisionDecimalNumContext.DECIMAL_VAL().getText()); + return Lists.newArrayList(numericParameter); + } + + @Override + public Node visitNumber_type_i(Number_type_iContext ctx) { + String name = null; + if (ctx.DECIMAL() != null) { + name = ctx.DECIMAL().getText(); + } + if (ctx.NUMBER() != null) { + name = ctx.NUMBER().getText(); + } + if (ctx.FIXED() != null) { + name = ctx.FIXED().getText(); + } + List list = getDataTypeParameters(ctx.precision_int_num()); + Boolean zeroFill = ctx.ZEROFILL() != null; + SignEnum signEnum = null; + if (ctx.UNSIGNED() != null) { + signEnum = SignEnum.UNSIGNED; + } + if (ctx.SIGNED() != null) { + signEnum = SignEnum.SIGNED; + } + return new OceanBaseMysqlGenericDataType(name, list, zeroFill, signEnum); + } + + @Override + public Node visitBool_type_i(Bool_type_iContext ctx) { + if (ctx.BOOL() != null) { + return new OceanBaseMysqlGenericDataType(ctx.BOOL().getText(), null, null, null); + } + if (ctx.BOOLEAN() != null) { + return new OceanBaseMysqlGenericDataType(ctx.BOOLEAN().getText(), null, null, null); + } + return null; + } + + @Override + public Node visitJson_type_i(Json_type_iContext ctx) { + return new OceanBaseMysqlGenericDataType(ctx.JSON().getText(), null, null, null); + } + + @Override + public Node visitBit_type_i(Bit_type_iContext ctx) { + List list = getDataTypeParameters(ctx.precision_int_num()); + return new OceanBaseMysqlGenericDataType(ctx.BIT().getText(), list, null, null); + } + + @Override + public Node visitText_type_i(Text_type_iContext ctx) { + String name = null; + if (ctx.TINYTEXT() != null) { + name = ctx.TINYTEXT().getText(); + } + if (ctx.TEXT() != null) { + name = ctx.TEXT().getText(); + } + if (ctx.MEDIUMTEXT() != null) { + name = ctx.MEDIUMTEXT().getText(); + } + if (ctx.LONGTEXT() != null) { + name = ctx.LONGTEXT().getText(); + } + List list = null; + if (ctx.string_length_i() != null) { + NumericParameter numericParameter = new NumericParameter(ctx.string_length_i().number_literal().getText()); + list.add(numericParameter); + } + return new OceanBaseMysqlGenericDataType(name, list, null, null); + } + + @Override + public Node visitCharacter_type_i(Character_type_iContext ctx) { + String name = null; + if (ctx.CHARACTER() != null) { + name = ctx.CHARACTER().getText(); + } + if (ctx.NCHAR() != null) { + name = ctx.NCHAR().getText(); + } + if (ctx.VARCHAR() != null) { + name = ctx.VARCHAR().getText(); + } + + if (ctx.NVARCHAR() != null) { + name = ctx.NVARCHAR().getText(); + } + List list = getDataTypeFromStringLength(ctx.string_length_i()); + CharsetKey charSet = null; + if (ctx.charset_key() != null) { + charSet = ctx.charset_key().CHARACTER() != null ? CharsetKey.CHARACTER_SET : CharsetKey.CHARSET; + } + String charsetName = null; + if (ctx.charset_name() != null) { + charsetName = ctx.charset_name().getText(); + } + String collation = null; + if (ctx.collation() != null) { + collation = StripUtils.strip(ctx.collation().collation_name().getText()); + } + return new OceanBaseMysqlCharDataType(name, list, charSet, charsetName, collation); + } + + private static List getDataTypeFromStringLength(String_length_iContext ctx) { + List list = Lists.newArrayList(); + if (ctx == null) { + return list; + } + NumericParameter numericParameter = new NumericParameter(ctx.number_literal().getText()); + list.add(numericParameter); + return list; + } + + @Override + public Node visitGeo_type_i(Geo_type_iContext ctx) { + return new OceanBaseMysqlGenericDataType(ctx.getText(), null, null, null); + } + + @Override + public Node visitDatetime_type_i(Datetime_type_iContext ctx) { + String name = null; + if (ctx.DATETIME() != null) { + name = ctx.DATETIME().getText(); + } + if (ctx.TIME() != null) { + name = ctx.TIME().getText(); + } + if (ctx.TIMESTAMP() != null) { + name = ctx.TIMESTAMP().getText(); + } + List list = getDataTypeParameters(ctx.precision_int_num()); + return new OceanBaseMysqlGenericDataType(name, list, null, null); + } + + @Override + public Node visitDate_year_type_i(Date_year_type_iContext ctx) { + String name = null; + if (ctx.DATE() != null) { + name = ctx.DATE().getText(); + } + if (ctx.YEAR() != null) { + name = ctx.YEAR().getText(); + } + List list = getDataTypeParameters(ctx.precision_int_num()); + return new OceanBaseMysqlGenericDataType(name, list, null, null); + } + + @Override + public Node visitBlob_type_i(Blob_type_iContext ctx) { + String name = null; + if (ctx.BLOB() != null) { + name = ctx.BLOB().getText(); + } + if (ctx.MEDIUMBLOB() != null) { + name = ctx.MEDIUMBLOB().getText(); + } + if (ctx.TINYBLOB() != null) { + name = ctx.TINYBLOB().getText(); + } + if (ctx.LONGBLOB() != null) { + name = ctx.LONGBLOB().getText(); + } + List list = getDataTypeFromStringLength(ctx.string_length_i()); + return new OceanBaseMysqlGenericDataType(name, list, null, null); + } + + @Override + public Node visitBinary_type_i(Binary_type_iContext ctx) { + String name = null; + if (ctx.BINARY() != null) { + name = ctx.BINARY().getText(); + } + if (ctx.VARBINARY() != null) { + name = ctx.VARBINARY().getText(); + } + List list = getDataTypeFromStringLength(ctx.string_length_i()); + return new OceanBaseMysqlGenericDataType(name, list, null, null); + } + + @Override + public Node visitOpt_column_attribute_list(Opt_column_attribute_listContext ctx) { + List list = Lists.newArrayList(); + if (ctx.opt_column_attribute_list() != null) { + int childCount = ctx.opt_column_attribute_list().getChildCount(); + for (int i = 0; i < childCount; i++) { + Node node = visit(ctx.opt_column_attribute_list().getChild(i)); + list.add(node); + } + } + Column_attributeContext columnAttributeContext = ctx.column_attribute(); + if (columnAttributeContext != null) { + Node node = visit(columnAttributeContext); + list.add(node); + } + return new ListNode(list); + } + + @Override + public Node visitColumn_attribute(Column_attributeContext ctx) { + //not null + if (ctx.not() != null && ctx.NULLX() != null) { + return new NotNullConstraint(IdentifierUtil.sysIdentifier()); + } + //comment + if (ctx.COMMENT() != null) { + TerminalNode terminalNode = ctx.STRING_VALUE(); + return new Comment(StripUtils.strip(terminalNode.getText())); + } + //check + if (ctx.CHECK() != null) { + Identifier identifier = IdentifierUtil.sysIdentifier(); + if (ctx.opt_constraint_name() != null) { + identifier = (Identifier)visit(ctx.opt_constraint_name()); + } + BaseExpression expression = (BaseExpression)visit(ctx.expr()); + Boolean enforced = null; + if (ctx.check_state() != null) { + enforced = ctx.check_state().NOT() == null && ctx.check_state().ENFORCED() != null; + } + return new CheckExpressionConstraint(identifier, expression, enforced); + } + //COLLATE + if (ctx.COLLATE() != null) { + String collateName = StripUtils.strip(ctx.collation_name().getText()); + return new Property(OceanBasePropertyKey.COLLATE.getValue(), collateName); + } + //default + if (ctx.DEFAULT() != null) { + BaseExpression baseExpression = (BaseExpression)visit(ctx.now_or_signed_literal()); + return new DefaultValueConstraint(IdentifierUtil.sysIdentifier(), baseExpression); + } + + //unique key + if (ctx.UNIQUE() != null && ctx.KEY() != null) { + return new UniqueConstraint(IdentifierUtil.sysIdentifier(), Lists.newArrayList()); + } + //primary key + if (ctx.PRIMARY() != null || ctx.KEY() != null) { + return new PrimaryConstraint(IdentifierUtil.sysIdentifier(), Lists.newArrayList()); + } + //auto_increment + if (ctx.AUTO_INCREMENT() != null) { + return new Property(ExtensionPropertyKey.COLUMN_AUTO_INCREMENT.getValue(), String.valueOf(Boolean.TRUE)); + } + return super.visitColumn_attribute(ctx); + } + + @Override + public Node visitOpt_constraint_name(Opt_constraint_nameContext ctx) { + return visit(ctx.constraint_name()); + } + + @Override + public Node visitConstraint_name(Constraint_nameContext ctx) { + return visit(ctx.relation_name()); + } + + private BaseExpression toDefaultValue(ListNode optColumnAttributeListContext) { + if (optColumnAttributeListContext == null) { + return null; + } + DefaultValueConstraint defaultValueConstraint = ParserHelper.getNode(optColumnAttributeListContext, DefaultValueConstraint.class); + if (defaultValueConstraint == null) { + return null; + } + return defaultValueConstraint.getValue(); + } + + @Override + public Node visitNow_or_signed_literal(Now_or_signed_literalContext ctx) { + if (ctx.signed_literal() != null) { + return visit(ctx.signed_literal()); + } + return visit(ctx.cur_timestamp_func()); + } + + @Override + public Node visitCur_timestamp_func(Cur_timestamp_funcContext ctx) { + String text = ctx.now_synonyms_func().getText(); + List args = null; + if (ctx.INTNUM() != null) { + args = Lists.newArrayList(); + LongLiteral longLiteral = new LongLiteral(ctx.INTNUM().getText()); + args.add(longLiteral); + } + return new FunctionCall(QualifiedName.of(text), false, args); + } + + @Override + public Node visitLiteral(LiteralContext ctx) { + if (ctx.BOOL_VALUE() != null) { + return new BooleanLiteral(ctx.BOOL_VALUE().getText()); + } + if (ctx.DATE_VALUE() != null) { + String value = ctx.DATE_VALUE().getText(); + return parseDateValue(value); + } + if (ctx.INTNUM() != null) { + return new LongLiteral(ctx.INTNUM().getText()); + } + if (ctx.DECIMAL_VAL() != null) { + return new DecimalLiteral(ctx.DECIMAL_VAL().getText()); + } + if (ctx.NULLX() != null) { + return new NullLiteral(); + } + return super.visitLiteral(ctx); + } + + @Override + public Node visitComplex_string_literal(Complex_string_literalContext ctx) { + if (ctx.STRING_VALUE() != null && ctx.string_val_list() == null) { + String value = StripUtils.strip(ctx.STRING_VALUE().getText()); + return new StringLiteral(value); + } + if (ctx.string_val_list() != null) { + String value = StripUtils.strip(ctx.STRING_VALUE().getText()); + StringLiteral stringLiteral = new StringLiteral(value); + List list = ctx.string_val_list().STRING_VALUE().stream().map(x -> { + String text = x.getText(); + return new StringLiteral(StripUtils.strip(text)); + }).collect(Collectors.toList()); + List all = Lists.newArrayList(stringLiteral); + all.addAll(list); + return new ListStringLiteral(all); + } + return super.visitComplex_string_literal(ctx); + } + + private Node parseDateValue(String value) { + if (StringUtils.startsWithIgnoreCase(value, "DATE")) { + String substring = StringUtils.substring(value, "DATE".length()); + return new DateLiteral(substring); + } + if (StringUtils.startsWithIgnoreCase(value, "TIMESTAMP")) { + String substring = StringUtils.substring(value, "TIMESTAMP".length()); + return new TimestampLiteral(substring); + } + return null; + } + + @Override + public Node visitNumber_literal(Number_literalContext ctx) { + if (ctx.INTNUM() != null) { + return new LongLiteral(ctx.INTNUM().getText()); + } + if (ctx.DECIMAL_VAL() != null) { + return new DecimalLiteral(ctx.DECIMAL_VAL().getText()); + } + return super.visitNumber_literal(ctx); + } + + private Boolean toPrimary(ListNode optColumnAttributeListContext) { + if (optColumnAttributeListContext == null) { + return null; + } + PrimaryConstraint primaryConstraint = ParserHelper.getNode(optColumnAttributeListContext, PrimaryConstraint.class); + if (primaryConstraint == null) { + return null; + } + return primaryConstraint != null; + } + + private Boolean toNotNull(ListNode optColumnAttributeListContext) { + if (optColumnAttributeListContext == null) { + return null; + } + NotNullConstraint visit = ParserHelper.getNode(optColumnAttributeListContext, NotNullConstraint.class); + if (visit == null) { + return null; + } + return visit != null; + } + + private PartitionedBy toPartitionBy(Create_table_stmtContext ctx) { + if (ctx.opt_partition_option() == null) { + return null; + } + return (PartitionedBy)visit(ctx.opt_partition_option()); + } + + @Override + public Node visitOpt_column_partition_option(Opt_column_partition_optionContext ctx) { + return super.visitOpt_column_partition_option(ctx); + } + + @Override + public Node visitHash_partition_option(Hash_partition_optionContext ctx) { + LongLiteral partitionCount = null; + if (ctx.INTNUM() != null) { + partitionCount = new LongLiteral(ctx.INTNUM().getText()); + } + BaseExpression expression = (BaseExpression)visit(ctx.expr()); + BaseSubPartition subPartition = null; + if (ctx.subpartition_option() != null) { + subPartition = (BaseSubPartition)visit(ctx.subpartition_option()); + } + List hashPartitionElements = null; + if (ctx.opt_hash_partition_list() != null) { + hashPartitionElements = ParserHelper.visit(this, ctx.opt_hash_partition_list().hash_partition_list().hash_partition_element(), + HashPartitionElement.class); + } + OceanBaseHashPartitionBy oceanBaseHashPartitionBy = new OceanBaseHashPartitionBy( + partitionCount, expression, subPartition, hashPartitionElements + ); + return oceanBaseHashPartitionBy; + } + + @Override + public Node visitList_partition_option(List_partition_optionContext ctx) { + List columns = null; + if (ctx.COLUMNS() != null) { + columns = ParserHelper.visit(this, ctx.column_name_list().column_name(), Identifier.class).stream() + .map(c -> { + return ColumnDefinition.builder().colName(c).build(); + }).collect(Collectors.toList()); + } + BaseExpression expression = null; + if (ctx.expr() != null) { + expression = (BaseExpression)visit(ctx.expr()); + } + LongLiteral partitionCount = null; + if (ctx.INTNUM() != null) { + partitionCount = new LongLiteral(ctx.INTNUM().getText()); + } + BaseSubPartition subPartition = null; + if (ctx.subpartition_option() != null) { + subPartition = (BaseSubPartition)visit(ctx.subpartition_option()); + } + + List listPartitionElements = null; + if (ctx.opt_list_partition_list() != null) { + listPartitionElements = ParserHelper.visit(this, ctx.opt_list_partition_list().list_partition_list().list_partition_element(), + ListPartitionElement.class); + } + OceanBaseListPartitionBy oceanBaseListPartitionBy = new OceanBaseListPartitionBy( + columns, expression, partitionCount, subPartition, listPartitionElements + ); + return oceanBaseListPartitionBy; + } + + @Override + public Node visitKey_partition_option(Key_partition_optionContext ctx) { + List columns = null; + if (ctx.column_name_list() != null) { + columns = ParserHelper.visit(this, ctx.column_name_list().column_name(), Identifier.class) + .stream().map( + c -> ColumnDefinition.builder().colName(c).build() + ).collect(Collectors.toList()); + } + LongLiteral partitionCount = getLongLiteral(ctx); + BaseSubPartition subPartition = null; + if (ctx.subpartition_option() != null) { + subPartition = (BaseSubPartition)visit(ctx.subpartition_option()); + } + + List hashPartitionElements = null; + if (ctx.opt_hash_partition_list() != null) { + hashPartitionElements = ParserHelper.visit(this, ctx.opt_hash_partition_list().hash_partition_list().hash_partition_element(), + HashPartitionElement.class); + } + return new OceanBaseKeyPartitionBy( + columns, partitionCount, subPartition, hashPartitionElements + ); + } + + @Override + public Node visitColumn_ref(Column_refContext ctx) { + QualifiedName qualifiedName = null; + if (ctx.column_name() != null) { + Identifier col = (Identifier)visit(ctx.column_name()); + qualifiedName = QualifiedName.of(col.getValue()); + } else { + qualifiedName = QualifiedName.of(ctx.getText()); + } + return new TableOrColumn(qualifiedName); + } + + @Override + public Node visitSubpartition_individual_option(Subpartition_individual_optionContext ctx) { + BaseExpression expression = null; + if (ctx.expr() != null) { + expression = (BaseExpression)visit(ctx.expr()); + } + List columns = null; + if (ctx.column_name_list() != null) { + columns = ParserHelper.visit(this, ctx.column_name_list().column_name(), Identifier.class) + .stream() + .collect(Collectors.toList()); + } + LongLiteral count = getPartitionCount(ctx.INTNUM()); + if (ctx.RANGE() != null) { + return new SubRangePartition(expression, columns, null); + } + if (ctx.BISON_LIST() != null) { + return new SubListPartition(expression, columns); + } + if (ctx.HASH() != null) { + return new SubHashPartition(expression, count); + } + if (ctx.KEY() != null) { + return new SubKeyPartition(columns, count); + } + return super.visitSubpartition_individual_option(ctx); + } + + private static LongLiteral getLongLiteral(Key_partition_optionContext ctx) { + LongLiteral partitionCount = null; + if (ctx.INTNUM() != null) { + partitionCount = new LongLiteral(ctx.INTNUM().getText()); + } + return partitionCount; + } + + @Override + public Node visitRange_partition_option(Range_partition_optionContext ctx) { + List columns = null; + if (ctx.COLUMNS() != null) { + columns = ParserHelper.visit(this, ctx.column_name_list().column_name(), Identifier.class) + .stream() + .map(c -> ColumnDefinition.builder().colName(c).build()) + .collect(Collectors.toList()); + } + LongLiteral partitionCount = getPartitionCount(ctx.INTNUM()); + BaseSubPartition subPartition = null; + if (ctx.subpartition_option() != null) { + subPartition = (BaseSubPartition)visit(ctx.subpartition_option()); + } + BaseExpression expression = null; + if (ctx.expr() != null) { + expression = (BaseExpression)visit(ctx.expr()); + } + List singleRangePartitionList = null; + if (ctx.opt_range_partition_list() != null) { + singleRangePartitionList = ParserHelper.visit(this, + ctx.opt_range_partition_list().range_partition_list().range_partition_element(), RangePartitionElement.class); + } + return new OceanBaseRangePartitionBy( + columns, + partitionCount, + subPartition, + expression, + singleRangePartitionList + ); + } + + @Override + public Node visitSubpartition_template_option(Subpartition_template_optionContext ctx) { + BaseExpression expression = null; + if (ctx.expr() != null) { + expression = (BaseExpression)visit(ctx.expr()); + } + List columnList = null; + if (ctx.COLUMNS() != null) { + columnList = ParserHelper.visit(this, ctx.column_name_list().column_name(), Identifier.class); + } + List elements = null; + if (ctx.opt_hash_subpartition_list() != null) { + elements = ParserHelper.visit(this, ctx.opt_hash_subpartition_list().hash_subpartition_list().hash_subpartition_element(), + SubPartitionElement.class); + } + if (ctx.RANGE() != null) { + // SUBPARTITION BY RANGE LeftParen expr RightParen SUBPARTITION TEMPLATE opt_range_subpartition_list + // | SUBPARTITION BY RANGE COLUMNS LeftParen column_name_list RightParen SUBPARTITION TEMPLATE opt_range_subpartition_list + + SubPartitionList subPartitionList = null; + List partitionList = null; + if (ctx.opt_range_subpartition_list() != null) { + partitionList = ParserHelper.visit(this, ctx.opt_range_subpartition_list().range_subpartition_list().range_subpartition_element(), + SubPartitionElement.class); + subPartitionList = new SubPartitionList(partitionList); + } + return new SubRangeTemplatePartition(expression, columnList, subPartitionList); + } + if (ctx.HASH() != null) { + SubPartitionList subPartitionList = null; + if (elements != null) { + subPartitionList = new SubPartitionList(elements); + } + return new SubHashTemplatePartition(expression, subPartitionList); + } + + if (ctx.BISON_LIST() != null) { + SubPartitionList subPartitionList = null; + List listSubPartitionElements = null; + if (ctx.opt_list_subpartition_list() != null) { + listSubPartitionElements = ParserHelper.visit(this, + ctx.opt_list_subpartition_list().list_subpartition_list().list_subpartition_element(), + SubPartitionElement.class); + subPartitionList = new SubPartitionList(listSubPartitionElements); + } + return new SubListTemplatePartition(expression, columnList, subPartitionList); + } + + if (ctx.KEY() != null) { + SubPartitionList subPartitionList = null; + if (elements != null) { + subPartitionList = new SubPartitionList(elements); + } + return new SubKeyTemplatePartition(columnList, subPartitionList); + } + return super.visitSubpartition_template_option(ctx); + } + + @Override + public Node visitRange_partition_element(Range_partition_elementContext ctx) { + QualifiedName name = (QualifiedName)visit(ctx.relation_factor()); + PartitionKey partitionKey = null; + if (ctx.range_partition_expr() != null) { + partitionKey = (PartitionKey)visit(ctx.range_partition_expr()); + } + List propertyList = null; + if (ctx.partition_attributes_option() != null) { + Property property = (Property)visit(ctx.partition_attributes_option()); + propertyList = Lists.newArrayList(); + propertyList.add(property); + } + LongLiteral longLiteral = getPartitionCount(ctx.INTNUM()); + SubPartitionList subPartitionList = null; + if (ctx.subpartition_list() != null) { + subPartitionList = (SubPartitionList)visit(ctx.subpartition_list()); + } + Identifier identifier = name.getOriginalParts().get(name.getOriginalParts().size() - 1); + SingleRangePartition singleRangePartition = new SingleRangePartition( + identifier, false, + partitionKey, propertyList + ); + return new RangePartitionElement(longLiteral, singleRangePartition, subPartitionList); + } + + @Override + public Node visitOpt_hash_subpartition_list(Opt_hash_subpartition_listContext ctx) { + List list = ParserHelper.visit(this, + ctx.hash_subpartition_list().hash_subpartition_element(), + SubPartitionElement.class + ); + return new SubPartitionList(list); + } + + @Override + public Node visitHash_subpartition_element(Hash_subpartition_elementContext ctx) { + QualifiedName qualifiedName = (QualifiedName)visit(ctx.relation_factor()); + Property property = null; + if (ctx.partition_attributes_option() != null) { + property = (Property)visit(ctx.partition_attributes_option()); + } + return new SubHashPartitionElement(qualifiedName, property); + } + + @Override + public Node visitOpt_range_subpartition_list(Opt_range_subpartition_listContext ctx) { + List list = ParserHelper.visit(this, ctx.range_subpartition_list().range_subpartition_element(), + SubPartitionElement.class); + return new SubPartitionList(list); + } + + @Override + public Node visitRange_subpartition_element(Range_subpartition_elementContext ctx) { + Identifier name = null; + if (ctx.relation_factor() != null) { + QualifiedName qualifiedName = (QualifiedName)visit(ctx.relation_factor()); + name = qualifiedName.getOriginalParts().get(qualifiedName.getOriginalParts().size() - 1); + } + PartitionKey partitionKey = null; + if (ctx.range_partition_expr() != null) { + partitionKey = (PartitionKey)visit(ctx.range_partition_expr()); + } + + List propertyList = null; + if (ctx.partition_attributes_option() != null) { + propertyList = Lists.newArrayList(); + Property property = (Property)visit(ctx.partition_attributes_option()); + propertyList.add(property); + } + SingleRangePartition singleRangePartition = new SingleRangePartition( + name, false, partitionKey, propertyList + ); + return new SubRangePartitionElement(singleRangePartition); + } + + @Override + public Node visitList_subpartition_element(List_subpartition_elementContext ctx) { + QualifiedName qualifiedName = (QualifiedName)visit(ctx.relation_factor()); + Boolean defaultExpr = null; + List expressionList = null; + if (ctx.list_partition_expr() != null) { + if (ctx.list_partition_expr().DEFAULT() != null) { + defaultExpr = true; + } else { + expressionList = ParserHelper.visit(this, ctx.list_partition_expr().list_expr().expr(), BaseExpression.class); + } + } + Property property = null; + if (ctx.partition_attributes_option() != null) { + property = (Property)visit(ctx.partition_attributes_option()); + } + return new SubListPartitionElement(qualifiedName, defaultExpr, expressionList, property); + } + + @Override + public Node visitHash_partition_element(Hash_partition_elementContext ctx) { + QualifiedName qualifiedName = (QualifiedName)visit(ctx.relation_factor()); + LongLiteral num = getPartitionCount(ctx.INTNUM()); + Property property = null; + if (ctx.partition_attributes_option() != null) { + property = (Property)visit(ctx.partition_attributes_option()); + } + SubPartitionList subPartitionList = null; + if (ctx.subpartition_list() != null) { + subPartitionList = (SubPartitionList)visit(ctx.subpartition_list()); + } + return new HashPartitionElement(qualifiedName, num, property, subPartitionList); + } + + @Override + public Node visitList_partition_element(List_partition_elementContext ctx) { + QualifiedName qualifiedName = (QualifiedName)visit(ctx.relation_factor()); + Boolean defaultExpr = null; + List expressionList = null; + if (ctx.list_partition_expr().DEFAULT() != null) { + defaultExpr = true; + } else { + expressionList = ParserHelper.visit(this, ctx.list_partition_expr().list_expr().expr(), BaseExpression.class); + } + LongLiteral num = null; + if (ctx.INTNUM() != null) { + num = getPartitionCount(ctx.INTNUM()); + } + Property property = null; + if (ctx.partition_attributes_option() != null) { + property = (Property)visit(ctx.partition_attributes_option()); + } + SubPartitionList subPartitionList = null; + if (ctx.subpartition_list() != null) { + subPartitionList = (SubPartitionList)visit(ctx.subpartition_list()); + } + return new ListPartitionElement(qualifiedName, defaultExpr, expressionList, num, property, subPartitionList); + } + + @Override + public Node visitOpt_list_subpartition_list(Opt_list_subpartition_listContext ctx) { + List elementList = ParserHelper.visit(this, ctx.list_subpartition_list().list_subpartition_element(), + SubPartitionElement.class); + return new SubPartitionList(elementList); + } + + @Override + public Node visitPartition_attributes_option(Partition_attributes_optionContext ctx) { + return new Property(ctx.ENGINE_().getText(), ctx.INNODB().getText()); + } + + @Override + public Node visitRange_partition_expr(Range_partition_exprContext ctx) { + boolean maxValue = ctx.MAXVALUE() != null; + ListPartitionValue partitionValues = null; + if (ctx.range_expr_list() != null) { + List valueList = ParserHelper.visit(this, ctx.range_expr_list().range_expr(), PartitionValue.class); + partitionValues = new ListPartitionValue(valueList); + } + return new LessThanPartitionKey(maxValue, partitionValues); + } + + @Override + public Node visitRange_expr(Range_exprContext ctx) { + boolean maxValue = ctx.MAXVALUE() != null; + BaseExpression stringLiteral = null; + if (ctx.expr() != null) { + stringLiteral = (BaseExpression)visit(ctx.expr()); + } + return new PartitionValue(maxValue, stringLiteral); + } + + @Override + public Node visitExpr(ExprContext ctx) { + if (ctx.NOT() != null) { + BaseExpression baseExpression = (BaseExpression)visit(ctx.expr(0)); + return new NotExpression(ParserHelper.getLocation(ctx), baseExpression); + } + if (ctx.LeftParen() != null) { + BaseExpression baseExpression = (BaseExpression)visit(ctx.expr(0)); + baseExpression.setParenthesized(true); + return baseExpression; + } + if (ctx.bool_pri() != null) { + BaseExpression baseExpression = (BaseExpression)visit(ctx.bool_pri()); + if (ctx.IS() != null) { + return getIsConditionExpression(ctx, null, baseExpression); + } + return baseExpression; + } + BaseExpression left = (BaseExpression)visit(ctx.expr(0)); + BaseExpression right = (BaseExpression)visit(ctx.expr(1)); + LogicalOperator operator = getOperator(ctx); + return new LogicalBinaryExpression(operator, left, right); + } + + private static IsConditionExpression getIsConditionExpression(ExprContext ctx, IsType isType, BaseExpression baseExpression) { + TerminalNode terminalNode = ctx.BOOL_VALUE(); + if (ctx.not() != null) { + if (StringUtils.equalsIgnoreCase(terminalNode.getText(), "TRUE")) { + isType = IsType.NOT_TRUE; + } else if (StringUtils.equalsIgnoreCase(terminalNode.getText(), "FALSE")) { + isType = IsType.NOT_FALSE; + } + } else { + if (StringUtils.equalsIgnoreCase(terminalNode.getText(), "TRUE")) { + isType = IsType.TRUE; + } else if (StringUtils.equalsIgnoreCase(terminalNode.getText(), "FALSE")) { + isType = IsType.FALSE; + } + } + return new IsConditionExpression(baseExpression, isType); + } + + @Override + public Node visitBool_pri(Bool_priContext ctx) { + ComparisonOperator comparisonOperator = getComparisonOperator(ctx); + if (comparisonOperator != null && ctx.predicate() != null) { + BaseExpression left = (BaseExpression)visit(ctx.bool_pri()); + BaseExpression right = (BaseExpression)visit(ctx.predicate()); + return new ComparisonExpression(ParserHelper.getLocation(ctx), ParserHelper.getOrigin(ctx), comparisonOperator, left, right); + } + return super.visitBool_pri(ctx); + } + + private ComparisonOperator getComparisonOperator(Bool_priContext ctx) { + if (ctx.COMP_EQ() != null) { + return ComparisonOperator.EQUAL; + } + if (ctx.COMP_GT() != null) { + return ComparisonOperator.GREATER_THAN; + } + if (ctx.COMP_GE() != null) { + return ComparisonOperator.GREATER_THAN_OR_EQUAL; + } + if (ctx.COMP_LE() != null) { + return ComparisonOperator.LESS_THAN_OR_EQUAL; + } + if (ctx.COMP_LT() != null) { + return ComparisonOperator.LESS_THAN; + } + if (ctx.COMP_NE() != null) { + return ComparisonOperator.NOT_EQUAL_MS; + } + if (ctx.COMP_NSEQ() != null) { + return ComparisonOperator.NS_EQUAL; + } + return null; + } + + @Override + public Node visitPredicate(PredicateContext ctx) { + //in + if (ctx.IN() != null) { + InPredicate inPredicate = null; + BaseExpression baseExpression = (BaseExpression)visit(ctx.bit_expr(0)); + BaseExpression valueList = (BaseExpression)visit(ctx.in_expr()); + inPredicate = new InPredicate(baseExpression, valueList); + if (ctx.not() != null) { + return new NotExpression(ParserHelper.getLocation(ctx), inPredicate); + } else { + return inPredicate; + } + } + //between and + if (ctx.BETWEEN() != null) { + BaseExpression value = (BaseExpression)visit(ctx.bit_expr(0)); + BaseExpression min = (BaseExpression)visit(ctx.bit_expr(1)); + BaseExpression max = (BaseExpression)visit(ctx.predicate()); + BetweenPredicate betweenPredicate = new BetweenPredicate(value, min, max); + if (ctx.not() != null) { + return new NotExpression(ParserHelper.getLocation(ctx), betweenPredicate); + } + return betweenPredicate; + } + //like + if (ctx.LIKE() != null) { + BaseExpression left = (BaseExpression)visit(ctx.bit_expr(0)); + LikeOperator operator = LikeOperator.LIKE; + BaseExpression target = null; + if (CollectionUtils.isNotEmpty(ctx.simple_expr())) { + target = (BaseExpression)visit(ctx.simple_expr(0)); + } else { + target = (BaseExpression)visit(ctx.string_val_list(0)); + } + LikePredicate likePredicate = new LikePredicate(ParserHelper.getLocation(ctx), ParserHelper.getOrigin(ctx), left, operator, null, + target); + if (ctx.not() != null) { + return new NotExpression(ParserHelper.getLocation(ctx), likePredicate); + } else { + return likePredicate; + } + } + //REGEXP + if (ctx.REGEXP() != null) { + LikeOperator operator = LikeOperator.REGEXP; + BaseExpression left = (BaseExpression)visit(ctx.bit_expr(0)); + BaseExpression target = null; + if (ctx.bit_expr().size() > 1) { + target = (BaseExpression)visit(ctx.bit_expr(1)); + } else { + target = (BaseExpression)visit(ctx.string_val_list(0)); + } + LikePredicate likePredicate = new LikePredicate(ParserHelper.getLocation(ctx), ParserHelper.getOrigin(ctx), left, operator, null, + target); + if (ctx.not() != null) { + return new NotExpression(ParserHelper.getLocation(ctx), likePredicate); + } else { + return likePredicate; + } + } + return super.visitPredicate(ctx); + } + + @Override + public Node visitString_val_list(String_val_listContext ctx) { + List stringLiteralList = ctx.STRING_VALUE().stream().map( + s -> { + String text = s.getText(); + String t = StripUtils.strip(text); + return new StringLiteral(t); + } + ).collect(Collectors.toList()); + return new ListStringLiteral(ParserHelper.getLocation(ctx), ParserHelper.getOrigin(ctx), stringLiteralList); + } + + @Override + public Node visitBit_expr(Bit_exprContext ctx) { + if (ctx.simple_expr() != null) { + return visit(ctx.simple_expr()); + } + + if (ctx.INTERVAL() != null) { + BaseLiteral intervalValue = (BaseLiteral)visit(ctx.bit_expr(0)); + IntervalQualifiers intervalQualifiers = IntervalQualifiers.getIntervalQualifiers(ctx.date_unit().getText()); + BaseExpression baseExpression = (BaseExpression)visit(ctx.expr()); + return new IntervalExpression(ParserHelper.getLocation(ctx), ParserHelper.getOrigin(ctx), + intervalValue, intervalQualifiers, baseExpression, null); + } + + BitOperator operator = getBitOperator(ctx); + if (operator != null) { + BaseExpression left = (BaseExpression)visit(ctx.bit_expr(0)); + BaseExpression right = (BaseExpression)visit(ctx.bit_expr(1)); + return new BitOperationExpression(ParserHelper.getLocation(ctx), ParserHelper.getOrigin(ctx), operator, left, right); + } + + ArithmeticOperator arithmeticOperator = getArithmeticOperator(ctx); + if (arithmeticOperator != null) { + BaseExpression left = (BaseExpression)visit(ctx.bit_expr(0)); + BaseExpression right = (BaseExpression)visit(ctx.bit_expr(1)); + return new ArithmeticBinaryExpression(ParserHelper.getLocation(ctx), ParserHelper.getOrigin(ctx), arithmeticOperator, left, right); + } + + return null; + } + + private ArithmeticOperator getArithmeticOperator(Bit_exprContext ctx) { + if (ctx.DIV() != null || ctx.Div() != null) { + return ArithmeticOperator.DIVIDE; + } + if (ctx.MOD() != null || ctx.Mod() != null) { + return ArithmeticOperator.MOD; + } + if (ctx.Plus() != null) { + return ArithmeticOperator.ADD; + } + if (ctx.Star() != null) { + return ArithmeticOperator.STAR; + } + if (ctx.Minus() != null) { + return ArithmeticOperator.SUBTRACT; + } + return null; + } + + private BitOperator getBitOperator(Bit_exprContext ctx) { + if (ctx.And() != null) { + return BitOperator.AMPERSAND; + } + if (ctx.Caret() != null) { + return BitOperator.BITWISE_XOR; + } + + if (ctx.Or() != null) { + return BitOperator.BITWISE; + } + + if (ctx.SHIFT_LEFT() != null) { + return BitOperator.SHIFT_LEFT; + } + + if (ctx.SHIFT_RIGHT() != null) { + return BitOperator.SHIFT_RIGHT; + } + return null; + } + + private LogicalOperator getOperator(ExprContext ctx) { + if (ctx.AND() != null || ctx.AND_OP() != null) { + return LogicalOperator.AND; + } + if (ctx.OR() != null || ctx.CNNOP() != null) { + return LogicalOperator.OR; + } + return null; + } + + private LongLiteral getPartitionCount(TerminalNode intnumText) { + if (intnumText == null) { + return null; + } + return new LongLiteral(intnumText.getText()); + } + + private List buildProperties(Create_table_stmtContext ctx) { + Table_option_listContext tableOptionListContext = ctx.table_option_list(); + if (tableOptionListContext == null) { + return ImmutableList.of(); + } + if (tableOptionListContext.table_option_list_space_seperated() != null) { + List list = ParserHelper.visit(this, tableOptionListContext.table_option_list_space_seperated().table_option(), + Property.class); + return list; + } + return null; + } + + @Override + public Node visitTable_option(Table_optionContext ctx) { + if (ctx.SORTKEY() != null) { + List list = ParserHelper.visit(this, ctx.column_name_list().column_name(), Identifier.class); + String cols = list.stream().map(Identifier::getValue).collect(Collectors.joining(",")); + return new Property(OceanBasePropertyKey.SORT_KEY.getValue(), cols); + } + if (ctx.TABLE_MODE() != null) { + TerminalNode terminalNode = ctx.STRING_VALUE(); + return new Property(OceanBasePropertyKey.TABLE_MODE.getValue(), StripUtils.strip(terminalNode.getText())); + } + if (ctx.COMMENT() != null) { + TerminalNode terminalNode = ctx.STRING_VALUE(); + return new Property(OceanBasePropertyKey.COMMENT.getValue(), StripUtils.strip(terminalNode.getText())); + } + if (ctx.COMPRESSION() != null) { + TerminalNode terminalNode = ctx.STRING_VALUE(); + return new Property(OceanBasePropertyKey.COMPRESSION.getValue(), StripUtils.strip(terminalNode.getText())); + } + if (ctx.charset_key() != null) { + String value = StripUtils.strip(ctx.charset_name().getText()); + return new Property(OceanBasePropertyKey.CHARSET_KEY.getValue(), value); + } + if (ctx.collation_name() != null) { + String value = StripUtils.strip(ctx.collation_name().getText()); + return new Property(OceanBasePropertyKey.COLLATE.getValue(), value); + } + + if (ctx.ROW_FORMAT() != null) { + return new Property(OceanBasePropertyKey.ROW_FORMAT.getValue(), StripUtils.strip(ctx.row_format_option().getText())); + } + if (ctx.PCTFREE() != null) { + return new Property(OceanBasePropertyKey.PCTFREE.getValue(), ctx.INTNUM().getText()); + } + if (ctx.ENGINE_() != null) { + Node node = visit(ctx.relation_name_or_string()); + if (node instanceof StringLiteral) { + StringLiteral stringLiteral = (StringLiteral)node; + return new Property(ExtensionPropertyKey.TABLE_ENGINE.getValue(), stringLiteral.getValue()); + } else if (node instanceof Identifier) { + Identifier identifier = (Identifier)node; + return new Property(ExtensionPropertyKey.TABLE_ENGINE.getValue(), identifier.getValue()); + } + } + return super.visitTable_option(ctx); + } + + @Override + public Node visitRelation_name_or_string(Relation_name_or_stringContext ctx) { + if (ctx.relation_name() != null) { + return visit(ctx.relation_name()); + } + if (ctx.STRING_VALUE() != null) { + String v = StripUtils.strip(ctx.STRING_VALUE().getText()); + return new StringLiteral(v); + } + if (ctx.ALL() != null) { + return new Identifier(ctx.ALL().getText()); + } + return super.visitRelation_name_or_string(ctx); + } + + @Override + public Node visitSimple_func_expr(Simple_func_exprContext ctx) { + QualifiedName functionName = null; + if (ctx.function_name() != null) { + functionName = QualifiedName.of(ctx.function_name().getText()); + } else if (ctx.func_name != null) { + String text = ctx.func_name.getText(); + functionName = QualifiedName.of(text); + } + List arguments = null; + if (ctx.expr() != null) { + arguments = ParserHelper.visit(this, ctx.expr(), BaseExpression.class); + } else if (ctx.expr_list() != null) { + arguments = ParserHelper.visit(this, ctx.expr_list().expr(), BaseExpression.class); + } + return new FunctionCall(ParserHelper.getLocation(ctx), ParserHelper.getOrigin(ctx), + functionName, + ctx.DISTINCT() != null, arguments + ); + } + + @Override + public Node visitComplex_func_expr(Complex_func_exprContext ctx) { + if (ctx.CAST() != null) { + BaseExpression expression = (BaseExpression)visit(ctx.expr().expr(0)); + BaseDataType dataType = (BaseDataType)visit(ctx.cast_data_type()); + return new Cast(ParserHelper.getLocation(ctx), ParserHelper.getOrigin(ctx), expression, dataType); + } + return super.visitComplex_func_expr(ctx); + } + + @Override + public Node visitParallel_option(Parallel_optionContext ctx) { + if (ctx.NOPARALLEL() != null) { + return new Property(OceanBasePropertyKey.PARALLEL.getValue(), ctx.NOPARALLEL().getText()); + } + return new Property(OceanBasePropertyKey.PARALLEL.getValue(), ctx.INTNUM().getText()); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/OceanBaseMysqlLanguageParser.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/OceanBaseMysqlLanguageParser.java new file mode 100644 index 0000000..37ac277 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/OceanBaseMysqlLanguageParser.java @@ -0,0 +1,58 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser; + +import com.aliyun.fastmodel.common.parser.ParserHelper; +import com.aliyun.fastmodel.core.exception.ParseException; +import com.aliyun.fastmodel.core.parser.LanguageParser; +import com.aliyun.fastmodel.core.tree.Node; +import com.aliyun.fastmodel.core.tree.datatype.BaseDataType; +import com.aliyun.fastmodel.transform.api.context.ReverseContext; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBLexer; +import com.aliyun.fastmodel.transform.oceanbase.mysql.parser.OBParser; +import com.google.auto.service.AutoService; +import org.antlr.v4.runtime.ParserRuleContext; + +/** + * OceanBaseMysqlParser + * + * @author panguanjing + * @date 2024/2/2 + */ +@AutoService(LanguageParser.class) +public class OceanBaseMysqlLanguageParser implements LanguageParser { + + @Override + public T parseNode(String text, ReverseContext context) throws ParseException { + ParserRuleContext parserRuleContext = ParserHelper.getNode(text, charStream -> new OBLexer(charStream), + tokenStream -> new OBParser(tokenStream), + parser -> { + OBParser dorisParser = (OBParser)parser; + return dorisParser.sql_stmt(); + } + ); + return (T)parserRuleContext.accept(new OceanBaseMysqlAstBuilder(context)); + } + + @Override + public BaseDataType parseDataType(String text, ReverseContext context) throws ParseException { + ParserRuleContext parserRuleContext = ParserHelper.getNode(text, charStream -> new OBLexer(charStream), + tokenStream -> new OBParser(tokenStream), + parser -> { + OBParser dorisParser = (OBParser)parser; + return dorisParser.data_type(); + } + ); + return (BaseDataType)parserRuleContext.accept(new OceanBaseMysqlAstBuilder(context)); + } + + @Override + public T parseExpression(String text) throws ParseException { + ParserRuleContext parserRuleContext = ParserHelper.getNode(text, charStream -> new OBLexer(charStream), + tokenStream -> new OBParser(tokenStream), + parser -> { + OBParser dorisParser = (OBParser)parser; + return dorisParser.expr(); + } + ); + return (T)parserRuleContext.accept(new OceanBaseMysqlAstBuilder(ReverseContext.builder().build())); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/OceanBaseMysqlCharDataType.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/OceanBaseMysqlCharDataType.java new file mode 100644 index 0000000..3b8e4a9 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/OceanBaseMysqlCharDataType.java @@ -0,0 +1,64 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.core.tree.datatype.DataTypeParameter; +import com.aliyun.fastmodel.core.tree.datatype.GenericDataType; +import com.aliyun.fastmodel.core.tree.datatype.IDataTypeName; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; +import lombok.Getter; + +/** + * oceanbase char data type + * + * @author panguanjing + * @date 2024/2/13 + */ +@Getter +public class OceanBaseMysqlCharDataType extends GenericDataType { + + private final String dataTypeName; + + private final List arguments; + + private final CharsetKey charsetKey; + + private final String charsetName; + + private final String collation; + + public enum CharsetKey { + CHARSET("CHARSET"), + + CHARACTER_SET("CHARACTER SET"); + @Getter + String value; + + CharsetKey(String value) { + this.value = value; + } + + } + + public OceanBaseMysqlCharDataType(String dataTypeName, List parameters, CharsetKey charsetKey, String charsetName, + String collation) { + super(dataTypeName); + this.dataTypeName = dataTypeName; + this.arguments = parameters; + this.charsetKey = charsetKey; + this.charsetName = charsetName; + this.collation = collation; + } + + @Override + public IDataTypeName getTypeName() { + return OceanBaseMysqlDataTypeName.getByValue(dataTypeName); + } + + @Override + public R accept(IAstVisitor visitor, C context) { + OceanBaseMysqlAstVisitor oceanBaseMysqlAstVisitor = (OceanBaseMysqlAstVisitor)visitor; + return oceanBaseMysqlAstVisitor.visitOceanBaseCharDataType(this, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/OceanBaseMysqlDataTypeName.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/OceanBaseMysqlDataTypeName.java new file mode 100644 index 0000000..97b939b --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/OceanBaseMysqlDataTypeName.java @@ -0,0 +1,113 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree; + +import com.aliyun.fastmodel.core.tree.datatype.IDataTypeName; +import com.aliyun.fastmodel.transform.api.datatype.simple.ISimpleDataTypeName; +import com.aliyun.fastmodel.transform.api.datatype.simple.SimpleDataTypeName; +import org.apache.commons.lang3.StringUtils; + +/** + * OceanBaseMysqlDataTypeName + * + * @author panguanjing + * @date 2024/2/2 + */ +public enum OceanBaseMysqlDataTypeName implements ISimpleDataTypeName { + + TINYINT("TINYINT", Dimension.ZERO, SimpleDataTypeName.NUMBER), + INT("INT", Dimension.ZERO, SimpleDataTypeName.NUMBER), + BIGINT("BIGINT", Dimension.ZERO, SimpleDataTypeName.NUMBER), + MEDIUMINT("MEDIUMINT", Dimension.ZERO, SimpleDataTypeName.NUMBER), + BOOL("BOOL", Dimension.ZERO, SimpleDataTypeName.BOOLEAN), + BOOLEAN("BOOLEAN", Dimension.ZERO, SimpleDataTypeName.BOOLEAN), + INTEGER("INTEGER", Dimension.ZERO, SimpleDataTypeName.NUMBER), + SMALLINT("SMALLINT", Dimension.ZERO, SimpleDataTypeName.NUMBER), + FLOAT("FLOAT", Dimension.ZERO, SimpleDataTypeName.NUMBER), + DOUBLE("DOUBLE", Dimension.ZERO, SimpleDataTypeName.NUMBER), + BIT("BIT", Dimension.ZERO, SimpleDataTypeName.NUMBER), + DOUBLE_PRECISION("DOUBLE PRECISION", Dimension.ZERO, SimpleDataTypeName.NUMBER), + DECIMAL("DECIMAL", Dimension.TWO, SimpleDataTypeName.NUMBER), + NUMBER("NUMBER", Dimension.TWO, SimpleDataTypeName.NUMBER), + FIXED("FIXED", Dimension.TWO, SimpleDataTypeName.NUMBER), + DATETIME("DATETIME", Dimension.ZERO, SimpleDataTypeName.DATE), + TIMESTAMP("TIMESTAMP", Dimension.ZERO, SimpleDataTypeName.DATE), + DATE("DATE", Dimension.ZERO, SimpleDataTypeName.DATE), + TIME("TIME", Dimension.ZERO, SimpleDataTypeName.DATE), + YEAR("YEAR", Dimension.ZERO, SimpleDataTypeName.DATE), + + CHAR("CHAR", Dimension.ONE, SimpleDataTypeName.STRING), + NCHAR("NCHAR", Dimension.ONE, SimpleDataTypeName.STRING), + CHARACTER("CHARACTER", Dimension.ONE, SimpleDataTypeName.STRING), + VARCHAR("VARCHAR", Dimension.ONE, SimpleDataTypeName.STRING), + NVARCHAR("NVARCHAR", Dimension.ONE, SimpleDataTypeName.STRING), + BINARY("BINARY", Dimension.ONE, SimpleDataTypeName.STRING), + VARBINARY("VARBINARY", Dimension.ONE, SimpleDataTypeName.STRING), + + TINYBLOB("TINYBLOB", Dimension.ZERO, SimpleDataTypeName.STRING), + BLOB("BLOB", Dimension.ZERO, SimpleDataTypeName.STRING), + MEDIUMBLOB("MEDIUMBLOB", Dimension.ZERO, SimpleDataTypeName.STRING), + LONGBLOB("LONGBLOB", Dimension.ZERO, SimpleDataTypeName.STRING), + TINYTEXT("TINYTEXT", Dimension.ZERO, SimpleDataTypeName.STRING), + TEXT("TEXT", Dimension.ZERO, SimpleDataTypeName.STRING), + MEDIUMTEXT("MEDIUMTEXT", Dimension.ZERO, SimpleDataTypeName.STRING), + LONGTEXT("LONGTEXT", Dimension.ZERO, SimpleDataTypeName.STRING), + + JSON("JSON", Dimension.ZERO, SimpleDataTypeName.STRING), + + GEOMETRY("GEOMETRY", Dimension.ZERO, SimpleDataTypeName.STRING), + + POINT("POINT", Dimension.ZERO, SimpleDataTypeName.STRING), + + LINESTRING("LINESTRING", Dimension.ZERO, SimpleDataTypeName.STRING), + + POLYGON("POLYGON", Dimension.ZERO, SimpleDataTypeName.STRING), + + MULTIPOINT("MULTIPOINT", Dimension.ZERO, SimpleDataTypeName.STRING), + + MULTILINESTRING("MULTILINESTRING", Dimension.ZERO, SimpleDataTypeName.STRING), + + MULTIPOLYGON("MULTIPOLYGON", Dimension.ZERO, SimpleDataTypeName.STRING), + + GEOMETRYCOLLECTION("GEOMETRYCOLLECTION", Dimension.ZERO, SimpleDataTypeName.STRING); + + private final String value; + + private final Dimension dimension; + + private final SimpleDataTypeName simpleDataTypeName; + + OceanBaseMysqlDataTypeName(String value, Dimension dimension, SimpleDataTypeName simpleDataTypeName) { + this.value = value; + this.dimension = dimension; + this.simpleDataTypeName = simpleDataTypeName; + } + + public static IDataTypeName getByValue(String name) { + OceanBaseMysqlDataTypeName[] oceanBaseMysqlDataTypeNames = OceanBaseMysqlDataTypeName.values(); + for (OceanBaseMysqlDataTypeName oceanBaseMysqlDataTypeName : oceanBaseMysqlDataTypeNames) { + if (StringUtils.equalsIgnoreCase(oceanBaseMysqlDataTypeName.getValue(), name)) { + return oceanBaseMysqlDataTypeName; + } + } + return null; + } + + @Override + public String getName() { + return name(); + } + + @Override + public String getValue() { + return value; + } + + @Override + public Dimension getDimension() { + return dimension; + } + + @Override + public SimpleDataTypeName getSimpleDataTypeName() { + return simpleDataTypeName; + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/OceanBaseMysqlGenericDataType.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/OceanBaseMysqlGenericDataType.java new file mode 100644 index 0000000..1919f7c --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/OceanBaseMysqlGenericDataType.java @@ -0,0 +1,55 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.core.tree.datatype.DataTypeParameter; +import com.aliyun.fastmodel.core.tree.datatype.GenericDataType; +import com.aliyun.fastmodel.core.tree.datatype.IDataTypeName; +import com.aliyun.fastmodel.core.tree.expr.Identifier; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; +import lombok.Getter; + +/** + * OceanBaseMysqlGenericDataType + * + * @author panguanjing + * @date 2024/2/2 + */ +@Getter +public class OceanBaseMysqlGenericDataType extends GenericDataType { + + public enum SignEnum { + UNSIGNED, + SIGNED + } + + private final Boolean zeroFill; + + private final SignEnum signEnum; + + public OceanBaseMysqlGenericDataType(String dataTypeName, + List arguments, Boolean zeroFill, SignEnum signEnum) { + super(dataTypeName, arguments); + this.zeroFill = zeroFill; + this.signEnum = signEnum; + } + + public OceanBaseMysqlGenericDataType(Identifier name, + List arguments, Boolean zeroFill, SignEnum signEnum) { + super(name, arguments); + this.zeroFill = zeroFill; + this.signEnum = signEnum; + } + + @Override + public IDataTypeName getTypeName() { + return OceanBaseMysqlDataTypeName.getByValue(this.getName()); + } + + @Override + public R accept(IAstVisitor visitor, C context) { + OceanBaseMysqlAstVisitor oceanBaseMysqlAstVisitor = (OceanBaseMysqlAstVisitor)visitor; + return oceanBaseMysqlAstVisitor.visitOceanBaseMysqlGenericDataType(this, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/OceanBaseHashPartitionBy.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/OceanBaseHashPartitionBy.java new file mode 100644 index 0000000..6100a3c --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/OceanBaseHashPartitionBy.java @@ -0,0 +1,40 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.core.tree.expr.BaseExpression; +import com.aliyun.fastmodel.core.tree.expr.literal.LongLiteral; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.BaseSubPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.HashPartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; +import lombok.Getter; + +/** + * base oceanbase partition by + * + * @author panguanjing + * @date 2024/2/6 + */ +@Getter +public class OceanBaseHashPartitionBy extends OceanBasePartitionBy { + + private final BaseExpression expression; + private final BaseSubPartition subPartition; + private final List hashPartitionElements; + + public OceanBaseHashPartitionBy(LongLiteral partitionCount, + BaseExpression expression, + BaseSubPartition subPartition, List hashPartitionElements) { + super(partitionCount); + this.expression = expression; + this.subPartition = subPartition; + this.hashPartitionElements = hashPartitionElements; + } + + @Override + public R accept(IAstVisitor visitor, C context) { + OceanBaseMysqlAstVisitor mysqlAstVisitor = (OceanBaseMysqlAstVisitor)visitor; + return mysqlAstVisitor.visitOceanBaseHashPartitionBy(this, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/OceanBaseKeyPartitionBy.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/OceanBaseKeyPartitionBy.java new file mode 100644 index 0000000..15be4c4 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/OceanBaseKeyPartitionBy.java @@ -0,0 +1,38 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.core.tree.expr.literal.LongLiteral; +import com.aliyun.fastmodel.core.tree.statement.table.ColumnDefinition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.BaseSubPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.HashPartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; +import lombok.Getter; + +/** + * base oceanbase partition by + * + * @author panguanjing + * @date 2024/2/6 + */ +@Getter +public class OceanBaseKeyPartitionBy extends OceanBasePartitionBy { + + private final BaseSubPartition subPartition; + + private final List hashPartitionElements; + + public OceanBaseKeyPartitionBy(List columnDefinitions, + LongLiteral partitionCount, BaseSubPartition subPartition, List hashPartitionElements) { + super(columnDefinitions, partitionCount); + this.subPartition = subPartition; + this.hashPartitionElements = hashPartitionElements; + } + + @Override + public R accept(IAstVisitor visitor, C context) { + OceanBaseMysqlAstVisitor mysqlAstVisitor = (OceanBaseMysqlAstVisitor)visitor; + return mysqlAstVisitor.visitOceanBaseKeyPartitionBy(this, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/OceanBaseListPartitionBy.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/OceanBaseListPartitionBy.java new file mode 100644 index 0000000..b60215e --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/OceanBaseListPartitionBy.java @@ -0,0 +1,42 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.core.tree.expr.BaseExpression; +import com.aliyun.fastmodel.core.tree.expr.literal.LongLiteral; +import com.aliyun.fastmodel.core.tree.statement.table.ColumnDefinition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.BaseSubPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.ListPartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; +import lombok.Getter; + +/** + * base oceanbase partition by + * + * @author panguanjing + * @date 2024/2/6 + */ +@Getter +public class OceanBaseListPartitionBy extends OceanBasePartitionBy { + + private final BaseSubPartition subPartition; + + private final BaseExpression baseExpression; + + private final List partitionElementList; + + public OceanBaseListPartitionBy(List columnDefinitions, + BaseExpression baseExpression, LongLiteral partitionCount, BaseSubPartition subPartition, List partitionElementList) { + super(columnDefinitions, partitionCount); + this.subPartition = subPartition; + this.baseExpression = baseExpression; + this.partitionElementList = partitionElementList; + } + + @Override + public R accept(IAstVisitor visitor, C context) { + OceanBaseMysqlAstVisitor mysqlAstVisitor = (OceanBaseMysqlAstVisitor)visitor; + return mysqlAstVisitor.visitOceanBaseListPartitionBy(this, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/OceanBasePartitionBy.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/OceanBasePartitionBy.java new file mode 100644 index 0000000..18729e2 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/OceanBasePartitionBy.java @@ -0,0 +1,37 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.core.tree.expr.literal.LongLiteral; +import com.aliyun.fastmodel.core.tree.statement.table.ColumnDefinition; +import com.aliyun.fastmodel.core.tree.statement.table.PartitionedBy; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; +import lombok.Getter; + +/** + * base oceanbase partition by + * + * @author panguanjing + * @date 2024/2/6 + */ +@Getter +public abstract class OceanBasePartitionBy extends PartitionedBy { + + private final LongLiteral partitionCount; + + public OceanBasePartitionBy(List columnDefinitions, LongLiteral partitionCount) { + super(columnDefinitions); + this.partitionCount = partitionCount; + } + + public OceanBasePartitionBy(LongLiteral partitionCount) { + this(null, partitionCount); + } + + @Override + public R accept(IAstVisitor visitor, C context) { + OceanBaseMysqlAstVisitor mysqlAstVisitor = (OceanBaseMysqlAstVisitor)visitor; + return mysqlAstVisitor.visitOceanBasePartitionBy(this, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/OceanBaseRangePartitionBy.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/OceanBaseRangePartitionBy.java new file mode 100644 index 0000000..470accb --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/OceanBaseRangePartitionBy.java @@ -0,0 +1,43 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.core.tree.expr.BaseExpression; +import com.aliyun.fastmodel.core.tree.expr.literal.LongLiteral; +import com.aliyun.fastmodel.core.tree.statement.table.ColumnDefinition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.BaseSubPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.RangePartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; +import lombok.Getter; + +/** + * base oceanbase partition by + * + * @author panguanjing + * @date 2024/2/6 + */ +@Getter +public class OceanBaseRangePartitionBy extends OceanBasePartitionBy { + + private final BaseSubPartition subPartition; + + private final BaseExpression baseExpression; + + private final List singleRangePartitionList; + + public OceanBaseRangePartitionBy(List columnDefinitions, + LongLiteral partitionCount, BaseSubPartition subPartition, BaseExpression baseExpression, + List singleRangePartitionList) { + super(columnDefinitions, partitionCount); + this.subPartition = subPartition; + this.baseExpression = baseExpression; + this.singleRangePartitionList = singleRangePartitionList; + } + + @Override + public R accept(IAstVisitor visitor, C context) { + OceanBaseMysqlAstVisitor mysqlAstVisitor = (OceanBaseMysqlAstVisitor)visitor; + return mysqlAstVisitor.visitOceanBaseRangePartitionBy(this, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/BaseSubPartition.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/BaseSubPartition.java new file mode 100644 index 0000000..5a348ef --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/BaseSubPartition.java @@ -0,0 +1,20 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc; + +import com.aliyun.fastmodel.core.tree.AbstractNode; +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; + +/** + * sub partition + * + * @author panguanjing + * @date 2024/2/2 + */ +public abstract class BaseSubPartition extends AbstractNode { + + @Override + public R accept(IAstVisitor visitor, C context) { + OceanBaseMysqlAstVisitor extensionAstVisitor = (OceanBaseMysqlAstVisitor)visitor; + return extensionAstVisitor.visitBaseSubPartition(this, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/SubHashPartition.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/SubHashPartition.java new file mode 100644 index 0000000..9521d66 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/SubHashPartition.java @@ -0,0 +1,42 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.core.tree.Node; +import com.aliyun.fastmodel.core.tree.expr.BaseExpression; +import com.aliyun.fastmodel.core.tree.expr.literal.LongLiteral; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; +import lombok.Getter; + +/** + * sub hash partition + * + * @author panguanjing + * @date 2024/2/6 + */ +@Getter +public class SubHashPartition extends BaseSubPartition { + + private final BaseExpression expression; + private final LongLiteral subpartitionCount; + + public SubHashPartition(BaseExpression expression, LongLiteral subpartitionCount) { + Preconditions.checkNotNull(expression, "expression can't be null"); + this.expression = expression; + this.subpartitionCount = subpartitionCount; + } + + @Override + public List getChildren() { + return ImmutableList.of(expression, subpartitionCount); + } + + @Override + public R accept(IAstVisitor visitor, C context) { + OceanBaseMysqlAstVisitor extensionAstVisitor = (OceanBaseMysqlAstVisitor)visitor; + return extensionAstVisitor.visitSubHashPartition(this, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/SubKeyPartition.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/SubKeyPartition.java new file mode 100644 index 0000000..988fa9f --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/SubKeyPartition.java @@ -0,0 +1,50 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.core.tree.Node; +import com.aliyun.fastmodel.core.tree.expr.Identifier; +import com.aliyun.fastmodel.core.tree.expr.literal.LongLiteral; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableList.Builder; +import lombok.Getter; + +/** + * sub key partition + * + * @author panguanjing + * @date 2024/2/6 + */ +@Getter +public class SubKeyPartition extends BaseSubPartition { + + private final List columnList; + + private final LongLiteral subpartitionCount; + + public SubKeyPartition(List columnList, LongLiteral subpartitionCount) { + Preconditions.checkNotNull(columnList, "columnList can't be null"); + Preconditions.checkArgument(columnList.size() > 0, "columnList must be set"); + this.columnList = columnList; + this.subpartitionCount = subpartitionCount; + } + + @Override + public List getChildren() { + Builder nodes = ImmutableList.builder(); + nodes.addAll(columnList); + if (subpartitionCount != null) { + nodes.add(subpartitionCount); + } + return nodes.build(); + } + + @Override + public R accept(IAstVisitor visitor, C context) { + OceanBaseMysqlAstVisitor extensionAstVisitor = (OceanBaseMysqlAstVisitor)visitor; + return extensionAstVisitor.visitSubKeyPartition(this, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/SubListPartition.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/SubListPartition.java new file mode 100644 index 0000000..3f26896 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/SubListPartition.java @@ -0,0 +1,39 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.core.tree.Node; +import com.aliyun.fastmodel.core.tree.expr.BaseExpression; +import com.aliyun.fastmodel.core.tree.expr.Identifier; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; +import com.google.common.collect.ImmutableList; +import lombok.Getter; + +/** + * @author panguanjing + * @date 2024/2/6 + */ +@Getter +public class SubListPartition extends BaseSubPartition { + + private final BaseExpression expression; + + private final List columnList; + + public SubListPartition(BaseExpression expression, List columnList) { + this.columnList = columnList; + this.expression = expression; + } + + @Override + public List getChildren() { + return ImmutableList.of(expression); + } + + @Override + public R accept(IAstVisitor visitor, C context) { + OceanBaseMysqlAstVisitor extensionAstVisitor = (OceanBaseMysqlAstVisitor)visitor; + return extensionAstVisitor.visitSubListPartition(this, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/SubRangePartition.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/SubRangePartition.java new file mode 100644 index 0000000..28e0b95 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/SubRangePartition.java @@ -0,0 +1,58 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.core.tree.Node; +import com.aliyun.fastmodel.core.tree.expr.BaseExpression; +import com.aliyun.fastmodel.core.tree.expr.Identifier; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.RangePartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableList.Builder; +import lombok.Getter; + +/** + * sub range partition + * + * @author panguanjing + * @date 2024/2/6 + */ +@Getter +public class SubRangePartition extends BaseSubPartition { + + private final BaseExpression expression; + + private final List columnList; + + private final List singleRangePartitionList; + + public SubRangePartition(BaseExpression expression, List columnList, List singleRangePartitionList) { + this.singleRangePartitionList = singleRangePartitionList; + Preconditions.checkArgument(expression != null || columnList != null, "expression or columnList need not null"); + this.expression = expression; + this.columnList = columnList; + } + + @Override + public List getChildren() { + Builder nodes = ImmutableList.builder(); + if (expression != null) { + nodes.add(expression); + } + if (columnList != null) { + nodes.addAll(columnList); + } + if (singleRangePartitionList != null) { + nodes.addAll(singleRangePartitionList); + } + return nodes.build(); + } + + @Override + public R accept(IAstVisitor visitor, C context) { + OceanBaseMysqlAstVisitor extensionAstVisitor = (OceanBaseMysqlAstVisitor)visitor; + return extensionAstVisitor.visitSubRangePartition(this, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/HashPartitionElement.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/HashPartitionElement.java new file mode 100644 index 0000000..05ab333 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/HashPartitionElement.java @@ -0,0 +1,62 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.core.tree.Node; +import com.aliyun.fastmodel.core.tree.Property; +import com.aliyun.fastmodel.core.tree.QualifiedName; +import com.aliyun.fastmodel.core.tree.expr.literal.LongLiteral; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableList.Builder; +import lombok.Getter; + +/** + * hash partition element + * + * @author panguanjing + * @date 2024/2/7 + */ +@Getter +public class HashPartitionElement extends PartitionElement { + + private final QualifiedName qualifiedName; + + private final LongLiteral num; + + private final Property property; + + private final SubPartitionList subPartitionList; + + public HashPartitionElement(QualifiedName qualifiedName, LongLiteral num, Property property, SubPartitionList subPartitionList) { + this.qualifiedName = qualifiedName; + this.num = num; + this.property = property; + this.subPartitionList = subPartitionList; + } + + @Override + public List getChildren() { + Builder builder = ImmutableList.builder(); + if (qualifiedName != null) { + builder.add(qualifiedName); + } + if (num != null) { + builder.add(num); + } + if (property != null) { + builder.add(property); + } + if (subPartitionList != null) { + builder.add(subPartitionList); + } + return builder.build(); + } + + @Override + public R accept(IAstVisitor visitor, C context) { + OceanBaseMysqlAstVisitor astVisitor = (OceanBaseMysqlAstVisitor)visitor; + return astVisitor.visitHashPartitionElement(this, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/ListPartitionElement.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/ListPartitionElement.java new file mode 100644 index 0000000..98cf2fb --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/ListPartitionElement.java @@ -0,0 +1,55 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.core.tree.Node; +import com.aliyun.fastmodel.core.tree.Property; +import com.aliyun.fastmodel.core.tree.QualifiedName; +import com.aliyun.fastmodel.core.tree.expr.BaseExpression; +import com.aliyun.fastmodel.core.tree.expr.literal.LongLiteral; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; +import com.google.common.collect.ImmutableList; +import lombok.Getter; + +/** + * list partition element + * + * @author panguanjing + * @date 2024/2/7 + */ +@Getter +public class ListPartitionElement extends PartitionElement { + private final QualifiedName qualifiedName; + + private final Boolean defaultExpr; + + private final List expressionList; + + private final LongLiteral num; + + private final Property property; + + private final SubPartitionList subPartitionList; + + public ListPartitionElement(QualifiedName qualifiedName, Boolean defaultExpr, List expressionList, LongLiteral num, + Property property, SubPartitionList subPartitionList) { + this.qualifiedName = qualifiedName; + this.defaultExpr = defaultExpr; + this.expressionList = expressionList; + this.num = num; + this.property = property; + this.subPartitionList = subPartitionList; + } + + @Override + public List getChildren() { + return ImmutableList.of(); + } + + @Override + public R accept(IAstVisitor visitor, C context) { + OceanBaseMysqlAstVisitor astVisitor = (OceanBaseMysqlAstVisitor)visitor; + return astVisitor.visitListPartitionElement(this, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/PartitionElement.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/PartitionElement.java new file mode 100644 index 0000000..515fd98 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/PartitionElement.java @@ -0,0 +1,19 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element; + +import com.aliyun.fastmodel.core.tree.AbstractNode; +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; + +/** + * partition elements + * + * @author panguanjing + * @date 2024/2/7 + */ +public abstract class PartitionElement extends AbstractNode { + @Override + public R accept(IAstVisitor visitor, C context) { + OceanBaseMysqlAstVisitor astVisitor = (OceanBaseMysqlAstVisitor)visitor; + return astVisitor.visitPartitionElement(this, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/RangePartitionElement.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/RangePartitionElement.java new file mode 100644 index 0000000..def6284 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/RangePartitionElement.java @@ -0,0 +1,54 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.core.tree.Node; +import com.aliyun.fastmodel.core.tree.expr.literal.LongLiteral; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.SingleRangePartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; +import com.google.common.collect.ImmutableList.Builder; +import lombok.Getter; + +/** + * RangePartitionElement + * + * @author panguanjing + * @date 2024/2/6 + */ +@Getter +public class RangePartitionElement extends PartitionElement { + + private final LongLiteral idCount; + + private final SingleRangePartition singleRangePartition; + + private final SubPartitionList subPartitionList; + + public RangePartitionElement(LongLiteral idCount, SingleRangePartition singleRangePartition, SubPartitionList subPartitionList) { + this.idCount = idCount; + this.singleRangePartition = singleRangePartition; + this.subPartitionList = subPartitionList; + } + + @Override + public List getChildren() { + Builder immutableList = new Builder(); + if (singleRangePartition != null) { + immutableList.add(singleRangePartition); + } + if (subPartitionList != null) { + immutableList.add(subPartitionList); + } + if (idCount != null) { + immutableList.add(idCount); + } + return immutableList.build(); + } + + @Override + public R accept(IAstVisitor visitor, C context) { + OceanBaseMysqlAstVisitor astVisitor = (OceanBaseMysqlAstVisitor)visitor; + return astVisitor.visitRangePartitionElement(this, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/SubHashPartitionElement.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/SubHashPartitionElement.java new file mode 100644 index 0000000..fc756ca --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/SubHashPartitionElement.java @@ -0,0 +1,48 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.core.tree.Node; +import com.aliyun.fastmodel.core.tree.Property; +import com.aliyun.fastmodel.core.tree.QualifiedName; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableList.Builder; +import lombok.Data; + +/** + * hash sub partition element + * + * @author panguanjing + * @date 2024/2/7 + */ +@Data +public class SubHashPartitionElement extends SubPartitionElement { + private final QualifiedName qualifiedName; + + private final Property property; + + public SubHashPartitionElement(QualifiedName qualifiedName, Property property) { + this.qualifiedName = qualifiedName; + this.property = property; + } + + @Override + public List getChildren() { + Builder builder = ImmutableList.builder(); + if (qualifiedName != null) { + builder.add(qualifiedName); + } + if (property != null) { + builder.add(property); + } + return builder.build(); + } + + @Override + public R accept(IAstVisitor visitor, C context) { + OceanBaseMysqlAstVisitor astVisitor = (OceanBaseMysqlAstVisitor)visitor; + return astVisitor.visitHashSubPartitionElement(this, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/SubListPartitionElement.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/SubListPartitionElement.java new file mode 100644 index 0000000..d60f805 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/SubListPartitionElement.java @@ -0,0 +1,59 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.core.tree.Node; +import com.aliyun.fastmodel.core.tree.Property; +import com.aliyun.fastmodel.core.tree.QualifiedName; +import com.aliyun.fastmodel.core.tree.expr.BaseExpression; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableList.Builder; +import lombok.Getter; + +/** + * list sub partition element + * + * @author panguanjing + * @date 2024/2/7 + */ +@Getter +public class SubListPartitionElement extends SubPartitionElement { + + private final QualifiedName qualifiedName; + + private final Boolean defaultListExpr; + + private final List expressionList; + + private final Property property; + + public SubListPartitionElement(QualifiedName qualifiedName, Boolean defaultListExpr, List expressionList, Property property) { + this.qualifiedName = qualifiedName; + this.defaultListExpr = defaultListExpr; + this.expressionList = expressionList; + this.property = property; + } + + @Override + public List getChildren() { + Builder builder = ImmutableList.builder(); + if (qualifiedName != null) { + builder.add(qualifiedName); + } + if (expressionList != null) { + builder.addAll(expressionList); + } + if (property != null) { + builder.add(property); + } + return builder.build(); + } + + @Override + public R accept(IAstVisitor visitor, C context) { + OceanBaseMysqlAstVisitor astVisitor = (OceanBaseMysqlAstVisitor)visitor; + return astVisitor.visitListSubPartitionElement(this, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/SubPartitionElement.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/SubPartitionElement.java new file mode 100644 index 0000000..738c0c2 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/SubPartitionElement.java @@ -0,0 +1,20 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element; + +import com.aliyun.fastmodel.core.tree.AbstractNode; +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; + +/** + * Desc: + * + * @author panguanjing + * @date 2024/2/7 + */ +public abstract class SubPartitionElement extends AbstractNode { + + @Override + public R accept(IAstVisitor visitor, C context) { + OceanBaseMysqlAstVisitor astVisitor = (OceanBaseMysqlAstVisitor)visitor; + return astVisitor.visitSubPartitionElement(this, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/SubPartitionList.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/SubPartitionList.java new file mode 100644 index 0000000..681b9c2 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/SubPartitionList.java @@ -0,0 +1,34 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.AbstractNode; +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.core.tree.Node; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; +import lombok.Getter; + +/** + * SubPartitionList + * + * @author panguanjing + * @date 2024/2/6 + */ +@Getter +public class SubPartitionList extends AbstractNode { + + private final List subPartitionElementList; + + public SubPartitionList(List subPartitionElementList) {this.subPartitionElementList = subPartitionElementList;} + + @Override + public List getChildren() { + return subPartitionElementList; + } + + @Override + public R accept(IAstVisitor visitor, C context) { + OceanBaseMysqlAstVisitor astVisitor = (OceanBaseMysqlAstVisitor)visitor; + return astVisitor.visitSubPartitionList(this, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/SubRangePartitionElement.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/SubRangePartitionElement.java new file mode 100644 index 0000000..627d218 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/element/SubRangePartitionElement.java @@ -0,0 +1,34 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.core.tree.Node; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.SingleRangePartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; +import com.google.common.collect.ImmutableList; +import lombok.Getter; + +/** + * range sub + * + * @author panguanjing + * @date 2024/2/7 + */ +@Getter +public class SubRangePartitionElement extends SubPartitionElement { + private final SingleRangePartition singleRangePartition; + + public SubRangePartitionElement(SingleRangePartition singleRangePartition) {this.singleRangePartition = singleRangePartition;} + + @Override + public List getChildren() { + return ImmutableList.of(singleRangePartition); + } + + @Override + public R accept(IAstVisitor visitor, C context) { + OceanBaseMysqlAstVisitor astVisitor = (OceanBaseMysqlAstVisitor)visitor; + return astVisitor.visitRangeSubPartitionElement(this, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/template/SubHashTemplatePartition.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/template/SubHashTemplatePartition.java new file mode 100644 index 0000000..921f31b --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/template/SubHashTemplatePartition.java @@ -0,0 +1,50 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.template; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.core.tree.Node; +import com.aliyun.fastmodel.core.tree.expr.BaseExpression; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.BaseSubPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubPartitionList; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableList.Builder; +import lombok.Getter; + +/** + * subhash template partition + * + * @author panguanjing + * @date 2024/2/18 + */ +@Getter +public class SubHashTemplatePartition extends BaseSubPartition { + + private final BaseExpression expression; + + private final SubPartitionList subPartitionList; + + public SubHashTemplatePartition(BaseExpression expression, SubPartitionList subPartitionList) { + this.expression = expression; + this.subPartitionList = subPartitionList; + } + + @Override + public R accept(IAstVisitor visitor, C context) { + OceanBaseMysqlAstVisitor astVisitor = (OceanBaseMysqlAstVisitor)visitor; + return astVisitor.visitSubHashTemplatePartition(this, context); + } + + @Override + public List getChildren() { + Builder builder = ImmutableList.builder(); + if (expression != null) { + builder.add(expression); + } + if (subPartitionList != null) { + builder.add(subPartitionList); + } + return builder.build(); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/template/SubKeyTemplatePartition.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/template/SubKeyTemplatePartition.java new file mode 100644 index 0000000..21477ed --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/template/SubKeyTemplatePartition.java @@ -0,0 +1,51 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.template; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.core.tree.Node; +import com.aliyun.fastmodel.core.tree.expr.Identifier; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.BaseSubPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubPartitionList; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableList.Builder; +import lombok.Getter; + +/** + * Desc: + * + * @author panguanjing + * @date 2024/2/18 + */ +@Getter +public class SubKeyTemplatePartition extends BaseSubPartition { + + private final List columnList; + + private final SubPartitionList subPartitionList; + + public SubKeyTemplatePartition(List columnList, SubPartitionList subPartitionList) { + this.columnList = columnList; + this.subPartitionList = subPartitionList; + } + + @Override + public R accept(IAstVisitor visitor, C context) { + OceanBaseMysqlAstVisitor astVisitor = (OceanBaseMysqlAstVisitor)visitor; + return astVisitor.visitSubKeyTemplatePartition(this, context); + } + + @Override + public List getChildren() { + Builder builder = ImmutableList.builder(); + if (columnList != null) { + builder.addAll(columnList); + } + if (subPartitionList != null) { + builder.add(subPartitionList); + } + + return builder.build(); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/template/SubListTemplatePartition.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/template/SubListTemplatePartition.java new file mode 100644 index 0000000..a73e5eb --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/template/SubListTemplatePartition.java @@ -0,0 +1,54 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.template; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.core.tree.Node; +import com.aliyun.fastmodel.core.tree.expr.BaseExpression; +import com.aliyun.fastmodel.core.tree.expr.Identifier; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.BaseSubPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubPartitionList; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableList.Builder; +import lombok.Getter; + +/** + * Desc: + * + * @author panguanjing + * @date 2024/2/18 + */ +@Getter +public class SubListTemplatePartition extends BaseSubPartition { + + private final BaseExpression expression; + + private final List columnList; + + private final SubPartitionList subPartitionList; + + public SubListTemplatePartition(BaseExpression expression, List columnList, SubPartitionList subPartitionList) { + this.expression = expression; + this.columnList = columnList; + this.subPartitionList = subPartitionList; + } + + @Override + public R accept(IAstVisitor visitor, C context) { + OceanBaseMysqlAstVisitor astVisitor = (OceanBaseMysqlAstVisitor)visitor; + return astVisitor.visitSubListTemplatePartition(this, context); + } + + @Override + public List getChildren() { + Builder builder = ImmutableList.builder(); + if (expression != null) { + builder.add(expression); + } + if (subPartitionList != null) { + builder.add(subPartitionList); + } + return builder.build(); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/template/SubRangeTemplatePartition.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/template/SubRangeTemplatePartition.java new file mode 100644 index 0000000..b731876 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/partition/desc/template/SubRangeTemplatePartition.java @@ -0,0 +1,58 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.template; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.IAstVisitor; +import com.aliyun.fastmodel.core.tree.Node; +import com.aliyun.fastmodel.core.tree.expr.BaseExpression; +import com.aliyun.fastmodel.core.tree.expr.Identifier; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.BaseSubPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubPartitionList; +import com.aliyun.fastmodel.transform.oceanbase.parser.visitor.OceanBaseMysqlAstVisitor; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableList.Builder; +import lombok.Getter; + +/** + * SubRangeTemplatePartition + * + * @author panguanjing + * @date 2024/2/18 + */ +@Getter +public class SubRangeTemplatePartition extends BaseSubPartition { + + private final BaseExpression expression; + + private final List columnList; + + private final SubPartitionList subPartitionList; + + public SubRangeTemplatePartition(BaseExpression expression, List columnList, + SubPartitionList subPartitionList) { + this.expression = expression; + this.columnList = columnList; + this.subPartitionList = subPartitionList; + } + + @Override + public R accept(IAstVisitor visitor, C context) { + OceanBaseMysqlAstVisitor astVisitor = (OceanBaseMysqlAstVisitor)visitor; + return astVisitor.visitSubRangeTemplatePartition(this, context); + } + + @Override + public List getChildren() { + Builder builder = ImmutableList.builder(); + if (expression != null) { + builder.add(expression); + } + if (columnList != null) { + builder.addAll(columnList); + } + if (subPartitionList != null) { + builder.add(subPartitionList); + } + return builder.build(); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/visitor/OceanBaseMysqlAstVisitor.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/visitor/OceanBaseMysqlAstVisitor.java new file mode 100644 index 0000000..65c0f2f --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/main/java/com/aliyun/fastmodel/transform/oceanbase/parser/visitor/OceanBaseMysqlAstVisitor.java @@ -0,0 +1,143 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.visitor; + +import com.aliyun.fastmodel.transform.api.extension.visitor.ExtensionAstVisitor; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.OceanBaseMysqlCharDataType; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.OceanBaseMysqlGenericDataType; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.OceanBaseHashPartitionBy; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.OceanBaseKeyPartitionBy; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.OceanBaseListPartitionBy; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.OceanBasePartitionBy; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.OceanBaseRangePartitionBy; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.BaseSubPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.SubHashPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.SubKeyPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.SubListPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.SubRangePartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.HashPartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.ListPartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.PartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.RangePartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubHashPartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubListPartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubPartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubPartitionList; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.SubRangePartitionElement; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.template.SubHashTemplatePartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.template.SubKeyTemplatePartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.template.SubListTemplatePartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.template.SubRangeTemplatePartition; + +/** + * Desc: + * + * @author panguanjing + * @date 2024/1/20 + */ +public interface OceanBaseMysqlAstVisitor extends ExtensionAstVisitor { + + default R visitOceanBaseMysqlGenericDataType(OceanBaseMysqlGenericDataType oceanBaseMysqlGenericDataType, C context) { + return visitGenericDataType(oceanBaseMysqlGenericDataType, context); + } + + default R visitSubHashPartition(SubHashPartition subHashPartition, C context) { + return visitBaseSubPartition(subHashPartition, context); + } + + default R visitBaseSubPartition(BaseSubPartition baseSubPartition, C context) { + return visitNode(baseSubPartition, context); + } + + default R visitSubKeyPartition(SubKeyPartition subKeyPartition, C context) { + return visitBaseSubPartition(subKeyPartition, context); + } + + default R visitSubRangePartition(SubRangePartition subRangePartition, C context) { + return visitBaseSubPartition(subRangePartition, context); + } + + default R visitSubListPartition(SubListPartition subListPartition, C context) { + return visitBaseSubPartition(subListPartition, context); + } + + default R visitOceanBaseHashPartitionBy(OceanBaseHashPartitionBy oceanBaseHashPartitionBy, C context) { + return visitOceanBasePartitionBy(oceanBaseHashPartitionBy, context); + } + + default R visitOceanBasePartitionBy(OceanBasePartitionBy oceanBasePartitionBy, C context) { + return visitNode(oceanBasePartitionBy, context); + } + + default R visitOceanBaseKeyPartitionBy(OceanBaseKeyPartitionBy oceanBaseKeyPartitionBy, C context) { + return visitOceanBasePartitionBy(oceanBaseKeyPartitionBy, context); + } + + default R visitOceanBaseRangePartitionBy(OceanBaseRangePartitionBy oceanBaseRangePartitionBy, C context) { + return visitOceanBasePartitionBy(oceanBaseRangePartitionBy, context); + } + + default R visitOceanBaseListPartitionBy(OceanBaseListPartitionBy oceanBaseListPartitionBy, C context) { + return visitOceanBasePartitionBy(oceanBaseListPartitionBy, context); + } + + default R visitRangePartitionElement(RangePartitionElement rangePartitionElement, C context) { + return visitPartitionElement(rangePartitionElement, context); + } + + default R visitPartitionElement(PartitionElement partitionElement, C context) { + return visitNode(partitionElement, context); + } + + default R visitOceanBaseCharDataType(OceanBaseMysqlCharDataType oceanBaseMysqlCharDataType, C context) { + return visitDataType(oceanBaseMysqlCharDataType, context); + } + + default R visitListPartitionElement(ListPartitionElement listPartitionElement, C context) { + return visitPartitionElement(listPartitionElement, context); + } + + default R visitHashPartitionElement(HashPartitionElement hashPartitionElement, C context) { + return visitPartitionElement(hashPartitionElement, context); + } + + default R visitSubPartitionList(SubPartitionList subPartitionList, C context) { + return visitNode(subPartitionList, context); + } + + default R visitRangeSubPartitionElement(SubRangePartitionElement rangeSubPartitionElement, C context) { + return visitSubPartitionElement(rangeSubPartitionElement, context); + } + + default R visitSubPartitionElement(SubPartitionElement subPartitionElement, C context) { + return visitNode(subPartitionElement, context); + } + + default R visitListSubPartitionElement(SubListPartitionElement listSubPartitionElement, + C context) { + return visitSubPartitionElement(listSubPartitionElement, context); + } + + default R visitHashSubPartitionElement(SubHashPartitionElement hashSubPartitionElement, + C context) { + return visitSubPartitionElement(hashSubPartitionElement, context); + } + + default R visitSubRangeTemplatePartition(SubRangeTemplatePartition subRangeTemplatePartition, + C context) { + return visitBaseSubPartition(subRangeTemplatePartition, context); + } + + default R visitSubHashTemplatePartition(SubHashTemplatePartition subHashTemplatePartition, + C context) { + return visitBaseSubPartition(subHashTemplatePartition, context); + } + + default R visitSubListTemplatePartition(SubListTemplatePartition subListTemplatePartition, + C context) { + return visitBaseSubPartition(subListTemplatePartition, context); + } + + default R visitSubKeyTemplatePartition(SubKeyTemplatePartition subKeyTemplatePartition, + C context) { + return visitBaseSubPartition(subKeyTemplatePartition, context); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/BaseOceanbaseTest.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/BaseOceanbaseTest.java new file mode 100644 index 0000000..d3289a5 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/BaseOceanbaseTest.java @@ -0,0 +1,19 @@ +package com.aliyun.fastmodel.transform.oceanbase; + +import java.nio.charset.Charset; + +import lombok.SneakyThrows; +import org.apache.commons.io.IOUtils; + +/** + * Desc: + * + * @author panguanjing + * @date 2024/2/7 + */ +public abstract class BaseOceanbaseTest { + @SneakyThrows + public String getText(String name) { + return IOUtils.resourceToString("/oceanbase/" + name, Charset.defaultCharset()); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/OceanBaseMysqlTransformerTest.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/OceanBaseMysqlTransformerTest.java new file mode 100644 index 0000000..0d13941 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/OceanBaseMysqlTransformerTest.java @@ -0,0 +1,308 @@ +package com.aliyun.fastmodel.transform.oceanbase; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.BaseStatement; +import com.aliyun.fastmodel.core.tree.Comment; +import com.aliyun.fastmodel.core.tree.QualifiedName; +import com.aliyun.fastmodel.core.tree.expr.Identifier; +import com.aliyun.fastmodel.core.tree.statement.table.ColumnDefinition; +import com.aliyun.fastmodel.core.tree.statement.table.CreateTable; +import com.aliyun.fastmodel.core.tree.util.DataTypeUtil; +import com.aliyun.fastmodel.transform.api.dialect.DialectNode; +import com.google.common.collect.Lists; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * OceanBaseMysqlTransformerTest + * + * @author panguanjing + * @date 2024/2/2 + */ +public class OceanBaseMysqlTransformerTest extends BaseOceanbaseTest { + + private OceanBaseMysqlTransformer oceanBaseMysqlTransformer = new OceanBaseMysqlTransformer(); + + @Test + public void transform() { + List columns = Lists.newArrayList(); + ColumnDefinition c = ColumnDefinition.builder() + .colName(new Identifier("c1")) + .dataType(DataTypeUtil.simpleType("bigint", null)) + .build(); + columns.add(c); + CreateTable createTable = CreateTable.builder() + .tableName(QualifiedName.of("abc")) + .columns(columns) + .comment(new Comment("table comment")) + .build(); + DialectNode transform = oceanBaseMysqlTransformer.transform(createTable); + assertEquals("CREATE TABLE abc \n" + + "(\n" + + " c1 BIGINT\n" + + ")\n" + + "COMMENT 'table comment'", transform.getNode()); + } + + @Test + public void reverse() { + String text = getText("simple1.txt"); + DialectNode transform = getDialectNode(text); + assertEquals("CREATE TABLE tbl1 \n" + + "(\n" + + " c1 INT PRIMARY KEY,\n" + + " c2 VARCHAR(50)\n" + + ")", transform.getNode()); + } + + @Test + public void testReverseIndex() { + String text = getText("simple2_index.txt"); + DialectNode transform = getDialectNode(text); + assertEquals("CREATE TABLE tbl2 \n" + + "(\n" + + " c1 INT PRIMARY KEY,\n" + + " c2 INT,\n" + + " c3 INT,\n" + + " INDEX i1 (c2)\n" + + ")", transform.getNode()); + } + + @Test + public void testReverseIndex2() { + String text = getText("simple2_index2.txt"); + DialectNode transform = getDialectNode(text); + assertEquals("CREATE TABLE tbl3 \n" + + "(\n" + + " c1 INT,\n" + + " c2 INT,\n" + + " UNIQUE KEY((c1 + c2)),\n" + + " INDEX i1 ((c1 + 1))\n" + + ")", transform.getNode()); + } + + @Test + public void testReverseHash() { + String text = getText("simple3_hash.txt"); + DialectNode transform = getDialectNode(text); + assertEquals("CREATE TABLE tbl4 \n" + + "(\n" + + " c1 INT PRIMARY KEY,\n" + + " c2 INT\n" + + ")\n" + + "PARTITION BY HASH (c1) PARTITIONS 8", transform.getNode()); + } + + @Test + public void testReverseRange() { + String text = getText("simple3_range.txt"); + DialectNode transform = getDialectNode(text); + assertEquals("CREATE TABLE tbl5 \n" + + "(\n" + + " c1 INT,\n" + + " c2 INT,\n" + + " c3 INT\n" + + ")\n" + + "PARTITION BY RANGE (c1) SUBPARTITION BY KEY (c2,c3) SUBPARTITIONS 5\n" + + "(PARTITION p0 VALUES LESS THAN (0),\n" + + "PARTITION p1 VALUES LESS THAN (100))", transform.getNode()); + } + + @Test + public void testReverseCharset() { + String text = getText("simple4_charset.txt"); + DialectNode transform = getDialectNode(text); + assertEquals("CREATE TABLE tbl6 \n" + + "(\n" + + " c1 VARCHAR(10),\n" + + " c2 VARCHAR(10) CHARSET GBK COLLATE gbk_bin\n" + + ")\n" + + "DEFAULT CHARSET utf8\n" + + "COLLATE utf8mb4_general_ci", transform.getNode()); + } + + @Test + public void testReverseCompress() { + String text = getText("simple5_compress.txt"); + DialectNode transform = getDialectNode(text); + assertEquals("CREATE TABLE tbl7 \n" + + "(\n" + + " c1 INT,\n" + + " c2 INT,\n" + + " c3 VARCHAR(64)\n" + + ")\n" + + "compression 'zstd_1.0'\n" + + "row_format DYNAMIC\n" + + "pctfree 5", transform.getNode()); + } + + @Test + public void testReversePr() { + String text = getText("simple6_pr.txt"); + DialectNode node = getDialectNode(text); + assertEquals("CREATE TABLE tbl8 \n" + + "(\n" + + " c1 INT PRIMARY KEY,\n" + + " c2 INT\n" + + ")\n" + + "parallel 3", node.getNode()); + } + + @Test + public void testReverseAutoIncrement() { + String text = getText("simple7_autoincrement.txt"); + DialectNode node = getDialectNode(text); + assertEquals("CREATE TABLE tbl9 \n" + + "(\n" + + " inv_id BIGINT NOT NULL AUTO_INCREMENT,\n" + + " c1 BIGINT,\n" + + " PRIMARY KEY(inv_id)\n" + + ")\n" + + "PARTITION BY HASH (inv_id) PARTITIONS 8", node.getNode()); + } + + @Test + public void testReverseCheck() { + String text = getText("simple8_check.txt"); + DialectNode node = getDialectNode(text); + assertEquals("CREATE TABLE tbl10 \n" + + "(\n" + + " col1 INT,\n" + + " col2 INT,\n" + + " col3 INT,\n" + + " CONSTRAINT equal_check1 CHECK(col1 = col3 * 2)\n" + + ")", node.getNode()); + } + + @Test + public void testReverseReference() { + String text = getText("simple8_reference.txt"); + DialectNode node = getDialectNode(text); + assertEquals("CREATE TABLE ref_t2 \n" + + "(\n" + + " c1 INT PRIMARY KEY,\n" + + " c2 INT,\n" + + " FOREIGN KEY(c2) REFERENCES ref_t1(c1) ON UPDATE SET NULL\n" + + ")", node.getNode()); + } + + @Test + public void testReversePtCombine1() { + String text = getText("simple9_pt_combine_1.txt"); + DialectNode node = getDialectNode(text); + assertEquals("CREATE TABLE tb1_m_rcr \n" + + "(\n" + + " col1 INT,\n" + + " col2 INT\n" + + ")\n" + + "PARTITION BY RANGE COLUMNS (col1) \n" + + "SUBPARTITION BY RANGE (col2)\n" + + "SUBPARTITION TEMPLATE (\n" + + "SUBPARTITION mp0 VALUES LESS THAN (3),\n" + + "SUBPARTITION mp1 VALUES LESS THAN (6),\n" + + "SUBPARTITION mp2 VALUES LESS THAN (9)\n" + + ")\n" + + "(PARTITION p0 VALUES LESS THAN (100),\n" + + "PARTITION p1 VALUES LESS THAN (200),\n" + + "PARTITION p2 VALUES LESS THAN (300))", node.getNode()); + } + + @Test + public void testReversePtCombine2() { + String text = getText("simple9_pt_combine_2.txt"); + DialectNode node = getDialectNode(text); + assertEquals("CREATE TABLE tbl2_f_llc \n" + + "(\n" + + " col1 INT,\n" + + " col2 DATE\n" + + ")\n" + + "PARTITION BY LIST (col1) SUBPARTITION BY LIST COLUMNS (col2)\n" + + "(PARTITION p0 VALUES IN (100)(\n" + + "SUBPARTITION sp0 VALUES IN ('2021/04/01'),\n" + + "SUBPARTITION sp1 VALUES IN ('2021/07/01'),\n" + + "SUBPARTITION sp2 VALUES IN ('2021/10/01'),\n" + + "SUBPARTITION sp3 VALUES IN ('2022/01/01')\n" + + "),\n" + + "PARTITION p1 VALUES IN (200)(\n" + + "SUBPARTITION sp4 VALUES IN ('2021/04/01'),\n" + + "SUBPARTITION sp5 VALUES IN ('2021/07/01'),\n" + + "SUBPARTITION sp6 VALUES IN ('2021/10/01'),\n" + + "SUBPARTITION sp7 VALUES IN ('2022/01/01')\n" + + "))", node.getNode()); + } + + @Test + public void testReversePtCombine3() { + String text = getText("simple9_pt_combine_3.txt"); + DialectNode node = getDialectNode(text); + assertEquals("CREATE TABLE tbl3_f_hk \n" + + "(\n" + + " col1 INT,\n" + + " col2 VARCHAR(50)\n" + + ")\n" + + "PARTITION BY HASH (col1) SUBPARTITION BY KEY (col2)\n" + + "(PARTITION p1(\n" + + " SUBPARTITION sp0,\n" + + " SUBPARTITION sp1,\n" + + " SUBPARTITION sp2,\n" + + " SUBPARTITION sp3\n" + + "),\n" + + "PARTITION p2(\n" + + " SUBPARTITION sp4,\n" + + " SUBPARTITION sp5,\n" + + " SUBPARTITION sp6,\n" + + " SUBPARTITION sp7\n" + + "))", node.getNode()); + } + + @Test + public void testReversePtHash() { + String text = getText("simple9_pt_hash.txt"); + DialectNode node = getDialectNode(text); + assertEquals("CREATE TABLE tbl3_h \n" + + "(\n" + + " col1 INT,\n" + + " col2 VARCHAR(50)\n" + + ")\n" + + "PARTITION BY HASH (col1) PARTITIONS 2", node.getNode()); + } + + @Test + public void testReversePtList() { + String text = getText("simple9_pt_list.txt"); + DialectNode node = getDialectNode(text); + assertEquals("CREATE TABLE tbl2_l \n" + + "(\n" + + " col1 INT,\n" + + " col2 DATE\n" + + ")\n" + + "PARTITION BY LIST (col1)\n" + + "(PARTITION p0 VALUES IN (100),\n" + + "PARTITION p1 VALUES IN (200))", node.getNode()); + } + + @Test + public void testReversePtRange() { + String text = getText("simple9_pt_range.txt"); + DialectNode node = getDialectNode(text); + assertEquals("CREATE TABLE tb1_rc \n" + + "(\n" + + " col1 INT,\n" + + " col2 INT\n" + + ")\n" + + "PARTITION BY RANGE COLUMNS (col1)\n" + + "(PARTITION p0 VALUES LESS THAN (100),\n" + + "PARTITION p1 VALUES LESS THAN (200),\n" + + "PARTITION p2 VALUES LESS THAN (300))", node.getNode()); + } + + private DialectNode getDialectNode(String text) { + DialectNode dialectNode = new DialectNode(text); + BaseStatement reverse = oceanBaseMysqlTransformer.reverse(dialectNode); + DialectNode transform = oceanBaseMysqlTransformer.transform(reverse); + return transform; + } + +} \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/client/OceanBaseGeneratorAlterTest.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/client/OceanBaseGeneratorAlterTest.java new file mode 100644 index 0000000..1cee815 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/client/OceanBaseGeneratorAlterTest.java @@ -0,0 +1,260 @@ +package com.aliyun.fastmodel.transform.oceanbase.client; + +import java.util.List; +import java.util.stream.Collectors; + +import com.aliyun.fastmodel.transform.api.client.CodeGenerator; +import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; +import com.aliyun.fastmodel.transform.api.client.dto.property.StringProperty; +import com.aliyun.fastmodel.transform.api.client.dto.request.DdlGeneratorModelRequest; +import com.aliyun.fastmodel.transform.api.client.dto.result.DdlGeneratorResult; +import com.aliyun.fastmodel.transform.api.client.dto.table.Column; +import com.aliyun.fastmodel.transform.api.client.dto.table.Table; +import com.aliyun.fastmodel.transform.api.client.dto.table.TableConfig; +import com.aliyun.fastmodel.transform.api.client.generator.DefaultCodeGenerator; +import com.aliyun.fastmodel.transform.api.dialect.DialectMeta; +import com.aliyun.fastmodel.transform.api.dialect.DialectName; +import com.aliyun.fastmodel.transform.api.dialect.DialectNode; +import com.aliyun.fastmodel.transform.api.dialect.IVersion; +import com.google.common.collect.Lists; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * ddl generator test + * + * @author panguanjing + * @date 2023/9/17 + */ +public class OceanBaseGeneratorAlterTest { + CodeGenerator codeGenerator = new DefaultCodeGenerator(); + + @Test + public void testGeneratorAddColumn() { + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + List oneColumns = Lists.newArrayList(); + Column e1 = Column.builder() + .dataType("int") + .name("c1") + .nullable(true) + .build(); + oneColumns.add(e1); + + List twoColumns = Lists.newArrayList(); + twoColumns.add(e1); + twoColumns.add(Column.builder() + .dataType("int") + .name("c2") + .comment("comment") + .build()); + twoColumns.add(Column.builder() + .dataType("int") + .name("c3") + .comment("comment") + .build()); + Table after = Table.builder() + .database("autotest") + .name("abc") + .columns(twoColumns) + .comment("comment") + .build(); + request.setAfter(after); + Table before = Table.builder() + .database("autotest") + .name("abc") + .columns(oneColumns) + .comment("comment2") + .build(); + request.setBefore(before); + request.setConfig(TableConfig.builder() + .dialectMeta(DialectMeta.getByNameAndVersion(DialectName.OB_MYSQL.getValue(), IVersion.DEFAULT_VERSION)) + .build()); + DdlGeneratorResult generate = codeGenerator.generate(request); + List dialectNodes = generate.getDialectNodes(); + assertEquals("ALTER TABLE autotest.abc\n" + + "ADD COLUMN c2 INT NOT NULL COMMENT 'comment',\n" + + "ADD COLUMN c3 INT NOT NULL COMMENT 'comment';\n" + + "ALTER TABLE autotest.abc SET COMMENT 'comment'", + dialectNodes.stream().map(DialectNode::getNode).collect(Collectors.joining(";\n"))); + } + + @Test + public void testGeneratorDropColumn() { + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + List beforeColumns = Lists.newArrayList(); + + beforeColumns.add(Column.builder() + .dataType("int") + .name("c1") + .nullable(false) + .build()); + + Column build = Column.builder() + .dataType("int") + .name("c2") + .partitionKeyIndex(0) + .partitionKey(true) + .comment("comment") + .build(); + beforeColumns.add(build); + + List afterColumns = Lists.newArrayList(); + afterColumns.add(build); + + Table before = Table.builder() + .database("autotest") + .name("abc") + .columns(beforeColumns) + .comment("comment1") + .build(); + + Table after = Table.builder() + .database("autotest") + .name("abc") + .columns(afterColumns) + .build(); + + request.setBefore(before); + request.setAfter(after); + request.setConfig(TableConfig.builder() + .dialectMeta(DialectMeta.getByNameAndVersion(DialectName.OB_MYSQL.getValue(), IVersion.DEFAULT_VERSION)) + .build()); + DdlGeneratorResult generate = codeGenerator.generate(request); + List dialectNodes = generate.getDialectNodes(); + assertEquals("ALTER TABLE autotest.abc DROP COLUMN c1,\n" + + "ALTER TABLE autotest.abc SET COMMENT ''", dialectNodes.stream().filter(DialectNode::isExecutable).map(DialectNode::getNode) + .collect(Collectors.joining(",\n"))); + } + + @Test + public void testGeneratorModifyColumn() { + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + List beforeColumns = Lists.newArrayList(); + + beforeColumns.add(Column.builder() + .dataType("int") + .name("c1") + .nullable(false) + .build()); + + Column build = Column.builder() + .dataType("int") + .name("c1") + .comment("comment") + .nullable(true) + .build(); + + List afterColumns = Lists.newArrayList(); + afterColumns.add(build); + + Table before = Table.builder() + .database("autotest") + .name("abc") + .columns(beforeColumns) + .build(); + + Table after = Table.builder() + .database("autotest") + .name("abc") + .columns(afterColumns) + .build(); + + request.setBefore(before); + request.setAfter(after); + request.setConfig(TableConfig.builder() + .dialectMeta(DialectMeta.getByNameAndVersion(DialectName.OB_MYSQL.getValue(), IVersion.DEFAULT_VERSION)) + .build()); + DdlGeneratorResult generate = codeGenerator.generate(request); + List dialectNodes = generate.getDialectNodes(); + assertEquals("ALTER TABLE autotest.abc CHANGE COLUMN c1 c1 INT COMMENT 'comment'", dialectNodes.stream().filter(DialectNode::isExecutable) + .map(DialectNode::getNode) + .collect(Collectors.joining(",\n"))); + } + + @Test + public void testGeneratorSetProperties() { + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + List beforeColumns = Lists.newArrayList(); + + beforeColumns.add(Column.builder() + .dataType("int") + .name("c1") + .nullable(false) + .build()); + + StringProperty stringProperty = new StringProperty(); + stringProperty.setKey("default.replication_num"); + stringProperty.setValueString("2"); + List properties = Lists.newArrayList( + stringProperty + ); + Table before = Table.builder() + .database("autotest") + .name("abc") + .columns(beforeColumns) + .build(); + + Table after = Table.builder() + .database("autotest") + .name("abc") + .columns(beforeColumns) + .properties(properties) + .build(); + + request.setBefore(before); + request.setAfter(after); + request.setConfig(TableConfig.builder() + .dialectMeta(DialectMeta.getByNameAndVersion(DialectName.OB_MYSQL.getValue(), IVersion.DEFAULT_VERSION)) + .build()); + DdlGeneratorResult generate = codeGenerator.generate(request); + List dialectNodes = generate.getDialectNodes(); + assertEquals("ALTER TABLE autotest.abc default.replication_num='2'\n", dialectNodes.stream().filter(DialectNode::isExecutable) + .map(DialectNode::getNode) + .collect(Collectors.joining(",\n"))); + + } + + @Test + public void testGeneratorUnSetProperties() { + DdlGeneratorModelRequest request = new DdlGeneratorModelRequest(); + List beforeColumns = Lists.newArrayList(); + + beforeColumns.add(Column.builder() + .dataType("int") + .name("c1") + .nullable(false) + .build()); + + StringProperty stringProperty = new StringProperty(); + stringProperty.setKey("default.replication_num"); + stringProperty.setValueString("2"); + List properties = Lists.newArrayList( + stringProperty + ); + Table before = Table.builder() + .database("autotest") + .name("abc") + .columns(beforeColumns) + .properties(properties) + .build(); + + Table after = Table.builder() + .database("autotest") + .name("abc") + .columns(beforeColumns) + .build(); + + request.setBefore(before); + request.setAfter(after); + request.setConfig(TableConfig.builder() + .dialectMeta(DialectMeta.getByNameAndVersion(DialectName.OB_MYSQL.getValue(), IVersion.DEFAULT_VERSION)) + .build()); + DdlGeneratorResult generate = codeGenerator.generate(request); + List dialectNodes = generate.getDialectNodes(); + assertEquals("ALTER TABLE autotest.abc default.replication_num=''", dialectNodes.stream().filter(DialectNode::isExecutable) + .map(DialectNode::getNode) + .collect(Collectors.joining(",\n"))); + + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/client/OceanBaseGeneratorTest.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/client/OceanBaseGeneratorTest.java new file mode 100644 index 0000000..3cc9e40 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/client/OceanBaseGeneratorTest.java @@ -0,0 +1,375 @@ +package com.aliyun.fastmodel.transform.oceanbase.client; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.BaseStatement; +import com.aliyun.fastmodel.transform.api.client.CodeGenerator; +import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; +import com.aliyun.fastmodel.transform.api.client.dto.property.StringProperty; +import com.aliyun.fastmodel.transform.api.client.dto.request.DdlGeneratorModelRequest; +import com.aliyun.fastmodel.transform.api.client.dto.result.DdlGeneratorResult; +import com.aliyun.fastmodel.transform.api.client.dto.table.Column; +import com.aliyun.fastmodel.transform.api.client.dto.table.Table; +import com.aliyun.fastmodel.transform.api.client.dto.table.TableConfig; +import com.aliyun.fastmodel.transform.api.client.generator.DefaultCodeGenerator; +import com.aliyun.fastmodel.transform.api.dialect.DialectMeta; +import com.aliyun.fastmodel.transform.api.dialect.DialectNode; +import com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey; +import com.aliyun.fastmodel.transform.oceanbase.BaseOceanbaseTest; +import com.aliyun.fastmodel.transform.oceanbase.OceanBaseMysqlTransformer; +import com.aliyun.fastmodel.transform.oceanbase.context.OceanBaseContext; +import com.google.common.collect.Lists; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * oceanbase generator test + * + * @author panguanjing + * @date 2024/2/5 + */ +public class OceanBaseGeneratorTest extends BaseOceanbaseTest { + + private CodeGenerator codeGenerator = new DefaultCodeGenerator(); + + private OceanBaseMysqlTransformer oceanBaseMysqlTransformer = new OceanBaseMysqlTransformer(); + + @Test + public void testGeneratorSimple1() { + assertGenerator("simple1.txt", "CREATE TABLE tbl1 \n" + + "(\n" + + " c1 INT PRIMARY KEY,\n" + + " c2 VARCHAR(50)\n" + + ")"); + } + + @Test + public void testGeneratorSimple2Index() { + assertGenerator("simple2_index.txt", "CREATE TABLE tbl2 \n" + + "(\n" + + " c1 INT PRIMARY KEY,\n" + + " c2 INT,\n" + + " c3 INT,\n" + + " INDEX i1 (c2)\n" + + ")"); + } + + @Test + public void testGeneratorSimple2Index2() { + assertGenerator("simple2_index2.txt", "CREATE TABLE tbl3 \n" + + "(\n" + + " c1 INT,\n" + + " c2 INT,\n" + + " UNIQUE KEY((c1 + c2)),\n" + + " INDEX i1 ((c1 + 1))\n" + + ")"); + } + + @Test + public void testGeneratorSimple3Hash() { + assertGenerator("simple3_hash.txt", "CREATE TABLE tbl4 \n" + + "(\n" + + " c1 INT PRIMARY KEY,\n" + + " c2 INT\n" + + ")\n" + + "PARTITION BY HASH (c1) PARTITIONS 8"); + } + + @Test + public void testGeneratorSimple3Range() { + assertGenerator("simple3_range.txt", "CREATE TABLE tbl5 \n" + + "(\n" + + " c1 INT,\n" + + " c2 INT,\n" + + " c3 INT\n" + + ")\n" + + "PARTITION BY RANGE (c1) SUBPARTITION BY KEY (c2,c3) SUBPARTITIONS 5\n" + + "(PARTITION p0 VALUES LESS THAN (0),\n" + + "PARTITION p1 VALUES LESS THAN (100))"); + } + + @Test + public void testGeneratorSimple1Comment() { + assertGenerator("simple1_comment.txt", "CREATE TABLE tbl1 \n" + + "(\n" + + " c1 INT PRIMARY KEY,\n" + + " c2 VARCHAR(50)\n" + + ")\n" + + "COMMENT 'comment'\n" + + "PARTITION BY KEY (c1) PARTITIONS 8"); + } + + @Test + public void testGeneratorCharset() { + assertGenerator("simple4_charset.txt", "CREATE TABLE tbl6 \n" + + "(\n" + + " c1 VARCHAR(10),\n" + + " c2 VARCHAR(10)\n" + + ")\n" + + "DEFAULT CHARSET utf8\n" + + "COLLATE utf8mb4_general_ci"); + } + + @Test + public void testGeneratorCompress() { + assertGenerator("simple5_compress.txt", "CREATE TABLE tbl7 \n" + + "(\n" + + " c1 INT,\n" + + " c2 INT,\n" + + " c3 VARCHAR(64)\n" + + ")\n" + + "compression 'zstd_1.0'\n" + + "row_format DYNAMIC\n" + + "pctfree 5"); + } + + @Test + public void testGeneratorPr() { + assertGenerator("simple6_pr.txt", "CREATE TABLE tbl8 \n" + + "(\n" + + " c1 INT PRIMARY KEY,\n" + + " c2 INT\n" + + ")\n" + + "parallel 3"); + } + + //@Test + //public void testGeneratorAutoIncrement() { + // assertGenerator("simple7_autoincrement.txt", "CREATE TABLE tbl5 \n" + // + "(\n" + // + " c1 INT,\n" + // + " c2 INT,\n" + // + " c3 INT\n" + // + ")\n" + // + "PARTITION BY RANGE (c1) SUBPARTITION BY KEY (c2,c3) SUBPARTITIONS 5\n" + // + "(PARTITION p0 VALUES LESS THAN (0),\n" + // + "PARTITION p1 VALUES LESS THAN (100))"); + //} + + //@Test + //public void testGeneratorCheck() { + // assertGenerator("simple8_check.txt", "CREATE TABLE tbl5 \n" + // + "(\n" + // + " c1 INT,\n" + // + " c2 INT,\n" + // + " c3 INT\n" + // + ")\n" + // + "PARTITION BY RANGE (c1) SUBPARTITION BY KEY (c2,c3) SUBPARTITIONS 5\n" + // + "(PARTITION p0 VALUES LESS THAN (0),\n" + // + "PARTITION p1 VALUES LESS THAN (100))"); + //} + + //@Test + //public void testGeneratorReference() { + // assertGenerator("simple8_reference.txt", "CREATE TABLE tbl5 \n" + // + "(\n" + // + " c1 INT,\n" + // + " c2 INT,\n" + // + " c3 INT\n" + // + ")\n" + // + "PARTITION BY RANGE (c1) SUBPARTITION BY KEY (c2,c3) SUBPARTITIONS 5\n" + // + "(PARTITION p0 VALUES LESS THAN (0),\n" + // + "PARTITION p1 VALUES LESS THAN (100))"); + //} + + @Test + public void testGeneratorPtCombine1() { + assertGenerator("simple9_pt_combine_1.txt", "CREATE TABLE tb1_m_rcr \n" + + "(\n" + + " col1 INT,\n" + + " col2 INT\n" + + ")\n" + + "PARTITION BY RANGE COLUMNS (col1) \n" + + "SUBPARTITION BY RANGE (col2)\n" + + "SUBPARTITION TEMPLATE (\n" + + "SUBPARTITION mp0 VALUES LESS THAN (3),\n" + + "SUBPARTITION mp1 VALUES LESS THAN (6),\n" + + "SUBPARTITION mp2 VALUES LESS THAN (9)\n" + + ")\n" + + "(PARTITION p0 VALUES LESS THAN (100),\n" + + "PARTITION p1 VALUES LESS THAN (200),\n" + + "PARTITION p2 VALUES LESS THAN (300))"); + } + + @Test + public void testGeneratorPtCombine2() { + assertGenerator("simple9_pt_combine_2.txt", "CREATE TABLE tbl2_f_llc \n" + + "(\n" + + " col1 INT,\n" + + " col2 DATE\n" + + ")\n" + + "PARTITION BY LIST (col1) SUBPARTITION BY LIST COLUMNS (col2)\n" + + "(PARTITION p0 VALUES IN (100)(\n" + + "SUBPARTITION sp0 VALUES IN ('2021/04/01'),\n" + + "SUBPARTITION sp1 VALUES IN ('2021/07/01'),\n" + + "SUBPARTITION sp2 VALUES IN ('2021/10/01'),\n" + + "SUBPARTITION sp3 VALUES IN ('2022/01/01')\n" + + "),\n" + + "PARTITION p1 VALUES IN (200)(\n" + + "SUBPARTITION sp4 VALUES IN ('2021/04/01'),\n" + + "SUBPARTITION sp5 VALUES IN ('2021/07/01'),\n" + + "SUBPARTITION sp6 VALUES IN ('2021/10/01'),\n" + + "SUBPARTITION sp7 VALUES IN ('2022/01/01')\n" + + "))"); + } + + @Test + public void testGeneratorPtCombine3() { + assertGenerator("simple9_pt_combine_3.txt", "CREATE TABLE tbl3_f_hk \n" + + "(\n" + + " col1 INT,\n" + + " col2 VARCHAR(50)\n" + + ")\n" + + "PARTITION BY HASH (col1) SUBPARTITION BY KEY (col2)\n" + + "(PARTITION p1(\n" + + " SUBPARTITION sp0,\n" + + " SUBPARTITION sp1,\n" + + " SUBPARTITION sp2,\n" + + " SUBPARTITION sp3\n" + + "),\n" + + "PARTITION p2(\n" + + " SUBPARTITION sp4,\n" + + " SUBPARTITION sp5,\n" + + " SUBPARTITION sp6,\n" + + " SUBPARTITION sp7\n" + + "))"); + } + + @Test + public void testGeneratorHash() { + assertGenerator("simple9_pt_hash.txt", "CREATE TABLE tbl3_h \n" + + "(\n" + + " col1 INT,\n" + + " col2 VARCHAR(50)\n" + + ")\n" + + "PARTITION BY HASH (col1) PARTITIONS 2"); + } + + @Test + public void testGeneratorList() { + assertGenerator("simple9_pt_list.txt", "CREATE TABLE tbl2_l \n" + + "(\n" + + " col1 INT,\n" + + " col2 DATE\n" + + ")\n" + + "PARTITION BY LIST (col1)\n" + + "(PARTITION p0 VALUES IN (100),\n" + + "PARTITION p1 VALUES IN (200))"); + } + + @Test + public void testGeneratorPtRange() { + assertGenerator("simple9_pt_range.txt", "CREATE TABLE tb1_rc \n" + + "(\n" + + " col1 INT,\n" + + " col2 INT\n" + + ")\n" + + "PARTITION BY RANGE COLUMNS (col1)\n" + + "(PARTITION p0 VALUES LESS THAN (100),\n" + + "PARTITION p1 VALUES LESS THAN (200),\n" + + "PARTITION p2 VALUES LESS THAN (300))"); + } + + @Test + public void testGeneratorPtKey() { + assertGenerator("simple9_pt_key.txt", "CREATE TABLE tb1_rc \n" + + "(\n" + + " col1 INT,\n" + + " col2 INT\n" + + ")\n" + + "PARTITION BY KEY (col1,col2) PARTITIONS 8"); + } + + @Test + public void testGeneratorRangeError() { + assertGenerator("range_error.txt", "CREATE TABLE employees1 \n" + + "(\n" + + " id INT NOT NULL,\n" + + " first_name VARCHAR(30),\n" + + " last_name VARCHAR(30),\n" + + " hired_date DATE NOT NULL,\n" + + " salary INT NOT NULL,\n" + + " PRIMARY KEY(id,hired_date)\n" + + ")\n" + + "PARTITION BY RANGE (YEAR(hired_date))\n" + + "(PARTITION p0 VALUES LESS THAN (1991),\n" + + "PARTITION p1 VALUES LESS THAN (1996),\n" + + "PARTITION p2 VALUES LESS THAN (2001),\n" + + "PARTITION p3 VALUES LESS THAN (2006),\n" + + "PARTITION p4 VALUES LESS THAN (2011),\n" + + "PARTITION p5 VALUES LESS THAN (2016),\n" + + "PARTITION p6 VALUES LESS THAN (2021),\n" + + "PARTITION p7 VALUES LESS THAN MAXVALUE)"); + } + + private void assertGenerator(String file, String expect) { + String text = getText(file); + DialectNode dialectNode = new DialectNode(text); + BaseStatement reverse = oceanBaseMysqlTransformer.reverse(dialectNode); + Table table = oceanBaseMysqlTransformer.transformTable(reverse, OceanBaseContext.builder().build()); + assertText(expect, table); + } + + @Test + public void testGenerator() { + List columns = Lists.newArrayList(); + Column e = Column.builder() + .name("c1") + .dataType("int") + .comment("column_comment") + .nullable(false) + .build(); + columns.add(e); + Table table = Table.builder() + .name("t1") + .comment("comment") + .columns(columns) + .build(); + assertText("CREATE TABLE IF NOT EXISTS t1 \n" + + "(\n" + + " c1 INT NOT NULL COMMENT 'column_comment'\n" + + ")\n" + + "COMMENT 'comment'", table); + } + + @Test + public void testPartitionRaw() { + List columns = Lists.newArrayList(); + Column e = Column.builder() + .name("c1") + .dataType("int") + .comment("column_comment") + .nullable(false) + .build(); + columns.add(e); + List properties = Lists.newArrayList(); + StringProperty e1 = new StringProperty(); + e1.setKey(ExtensionPropertyKey.TABLE_PARTITION_RAW.getValue()); + e1.setValueString("PARTITION BY HASH(c1) PARTITIONS 8"); + properties.add(e1); + Table table = Table.builder() + .name("t1") + .comment("comment") + .columns(columns) + .properties(properties) + .build(); + assertText("CREATE TABLE IF NOT EXISTS t1 \n" + + "(\n" + + " c1 INT NOT NULL COMMENT 'column_comment'\n" + + ")\n" + + "COMMENT 'comment'\n" + + "PARTITION BY HASH(c1) PARTITIONS 8", table); + } + + private void assertText(String expect, Table table) { + DdlGeneratorModelRequest request = DdlGeneratorModelRequest.builder() + .config(TableConfig.builder() + .dialectMeta(DialectMeta.DEFAULT_OB_MYSQL) + .build()) + .after(table) + .build(); + DdlGeneratorResult generate = codeGenerator.generate(request); + assertEquals(expect, generate.getDialectNodes().get(0).getNode()); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/client/OceanBaseGeneratorWithModelTest.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/client/OceanBaseGeneratorWithModelTest.java new file mode 100644 index 0000000..fe37ac3 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/client/OceanBaseGeneratorWithModelTest.java @@ -0,0 +1,80 @@ +package com.aliyun.fastmodel.transform.oceanbase.client; + +import java.util.List; + +import com.aliyun.fastmodel.transform.api.client.CodeGenerator; +import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; +import com.aliyun.fastmodel.transform.api.client.dto.request.DdlGeneratorModelRequest; +import com.aliyun.fastmodel.transform.api.client.dto.result.DdlGeneratorResult; +import com.aliyun.fastmodel.transform.api.client.dto.table.Column; +import com.aliyun.fastmodel.transform.api.client.dto.table.Table; +import com.aliyun.fastmodel.transform.api.client.dto.table.TableConfig; +import com.aliyun.fastmodel.transform.api.client.generator.DefaultCodeGenerator; +import com.aliyun.fastmodel.transform.api.dialect.DialectMeta; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.TablePartitionRaw; +import com.aliyun.fastmodel.transform.oceanbase.BaseOceanbaseTest; +import com.aliyun.fastmodel.transform.oceanbase.OceanBaseMysqlTransformer; +import com.google.common.collect.Lists; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * oceanbase generator test + * + * @author panguanjing + * @date 2024/2/5 + */ +public class OceanBaseGeneratorWithModelTest extends BaseOceanbaseTest { + + private CodeGenerator codeGenerator = new DefaultCodeGenerator(); + + private OceanBaseMysqlTransformer oceanBaseMysqlTransformer = new OceanBaseMysqlTransformer(); + + @Test + public void testGenerator() { + List columns = Lists.newArrayList(); + Column e = Column.builder() + .name("c1") + .dataType("int") + .comment("column_comment") + .nullable(false) + .build(); + columns.add(e); + List properties = Lists.newArrayList(); + TablePartitionRaw tablePartitionRaw = new TablePartitionRaw(); + tablePartitionRaw.setValueString("PARTITION BY RANGE COLUMNS(col1)\n" + + " (PARTITION p0 VALUES LESS THAN(100),\n" + + " PARTITION p1 VALUES LESS THAN(200),\n" + + " PARTITION p2 VALUES LESS THAN(300)\n" + + " );"); + properties.add(tablePartitionRaw); + Table table = Table.builder() + .name("t1") + .comment("comment") + .columns(columns) + .properties(properties) + .build(); + assertText("CREATE TABLE IF NOT EXISTS t1 \n" + + "(\n" + + " c1 INT NOT NULL COMMENT 'column_comment'\n" + + ")\n" + + "COMMENT 'comment'\n" + + "PARTITION BY RANGE COLUMNS(col1)\n" + + " (PARTITION p0 VALUES LESS THAN(100),\n" + + " PARTITION p1 VALUES LESS THAN(200),\n" + + " PARTITION p2 VALUES LESS THAN(300)\n" + + " );", table); + } + + private void assertText(String expect, Table table) { + DdlGeneratorModelRequest request = DdlGeneratorModelRequest.builder() + .config(TableConfig.builder() + .dialectMeta(DialectMeta.DEFAULT_OB_MYSQL) + .build()) + .after(table) + .build(); + DdlGeneratorResult generate = codeGenerator.generate(request); + assertEquals(expect, generate.getDialectNodes().get(0).getNode()); + } +} diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/client/converter/OceanBaseMysqlClientConverterTest.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/client/converter/OceanBaseMysqlClientConverterTest.java new file mode 100644 index 0000000..5b63eb0 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/client/converter/OceanBaseMysqlClientConverterTest.java @@ -0,0 +1,65 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.converter; + +import java.util.List; + +import com.aliyun.fastmodel.core.parser.LanguageParser; +import com.aliyun.fastmodel.core.tree.QualifiedName; +import com.aliyun.fastmodel.core.tree.expr.BaseExpression; +import com.aliyun.fastmodel.core.tree.expr.literal.LongLiteral; +import com.aliyun.fastmodel.core.tree.expr.literal.StringLiteral; +import com.aliyun.fastmodel.transform.api.client.PropertyConverter; +import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.OceanBaseHashPartitionBy; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.OceanBasePartitionBy; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.BaseSubPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.SubHashPartition; +import com.aliyun.fastmodel.transform.oceanbase.parser.tree.partition.desc.element.HashPartitionElement; +import com.google.common.collect.Lists; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * OceanBaseMysqlClientConverterTest + * + * @author panguanjing + * @date 2024/2/5 + */ +public class OceanBaseMysqlClientConverterTest { + + OceanBaseMysqlClientConverter oceanBaseMysqlClientConverter = new OceanBaseMysqlClientConverter(); + + @Test + public void getLanguageParser() { + LanguageParser languageParser = oceanBaseMysqlClientConverter.getLanguageParser(); + assertNotNull(languageParser); + } + + @Test + public void testGetRaw() { + LongLiteral count = new LongLiteral("1"); + BaseExpression expression = new StringLiteral("1"); + BaseExpression e = new StringLiteral("c"); + BaseSubPartition subPartition = new SubHashPartition( + e, null + ); + List hashPartitionElements = Lists.newArrayList(); + HashPartitionElement hashPartitionElement = new HashPartitionElement( + QualifiedName.of("c1"), + new LongLiteral("1"), + null, + null + ); + OceanBasePartitionBy partition = new OceanBaseHashPartitionBy(count, expression, subPartition, hashPartitionElements); + String raw = oceanBaseMysqlClientConverter.getRaw(partition); + assertEquals("PARTITION BY HASH ('1') SUBPARTITION BY HASH ('c') PARTITIONS 1", raw); + } + + @Test + public void testConverter() { + PropertyConverter propertyConverter = oceanBaseMysqlClientConverter.getPropertyConverter(); + BaseClientProperty baseClientProperty = propertyConverter.create("a", "b"); + assertNotNull(baseClientProperty); + } +} \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/client/converter/partition/impl/OceanBasePartitionClientConverterImplTest.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/client/converter/partition/impl/OceanBasePartitionClientConverterImplTest.java new file mode 100644 index 0000000..35e767e --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/client/converter/partition/impl/OceanBasePartitionClientConverterImplTest.java @@ -0,0 +1,20 @@ +package com.aliyun.fastmodel.transform.oceanbase.client.converter.partition.impl; + +import org.junit.Test; + +/** + * OceanBasePartitionClientConverterImplTest + * + * @author panguanjing + * @date 2024/2/28 + */ +public class OceanBasePartitionClientConverterImplTest { + + @Test + public void toSubPartitionClient() { + } + + @Test + public void getSubPartition() { + } +} \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/parser/OceanBaseMysqlLanguageParserTest.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/parser/OceanBaseMysqlLanguageParserTest.java new file mode 100644 index 0000000..35a2cae --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/parser/OceanBaseMysqlLanguageParserTest.java @@ -0,0 +1,79 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser; + +import java.util.List; + +import com.aliyun.fastmodel.core.tree.datatype.BaseDataType; +import com.aliyun.fastmodel.core.tree.statement.constants.ConstraintType; +import com.aliyun.fastmodel.core.tree.statement.table.CreateTable; +import com.aliyun.fastmodel.core.tree.statement.table.PartitionedBy; +import com.aliyun.fastmodel.core.tree.statement.table.constraint.BaseConstraint; +import com.aliyun.fastmodel.core.tree.statement.table.constraint.PrimaryConstraint; +import com.aliyun.fastmodel.transform.api.context.ReverseContext; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * Desc: + * + * @author panguanjing + * @date 2024/2/2 + */ +public class OceanBaseMysqlLanguageParserTest { + + OceanBaseMysqlLanguageParser oceanBaseMysqlParser = new OceanBaseMysqlLanguageParser(); + + @Test + public void parseNode() { + String text = "create table non_partrange_hash_pri (" + + " col1 int," + + " col2 numeric(10,2)," + + " col3 varchar(10)," + + " col4 blob," + + " col5 year," + + " constraint pk_non_partrange_hash_pri primary key(col1,col5)" + + ") partition by range(col2) subpartition by hash(col1) (" + + " partition p1 values less than(0)(" + + " subpartition p1_1," + + " subpartition p1_2" + + " )," + + " partition p2 values less than(10000)(" + + " subpartition p2_1," + + " subpartition p2_2" + + " )," + + " partition p3 values less than(100000)(" + + " subpartition p3_1," + + " subpartition p3_2" + + " )," + + " partition p4 values less than (maxvalue)(" + + " subpartition p4_1" + + " )" + + ");"; + CreateTable createTable = oceanBaseMysqlParser.parseNode(text, ReverseContext.builder().build()); + assertNotNull(createTable); + assertEquals("non_partrange_hash_pri", createTable.getQualifiedName().toString()); + List constraintStatements = createTable.getConstraintStatements(); + assertEquals(1, constraintStatements.size()); + BaseConstraint constraint = constraintStatements.get(0); + assertEquals(ConstraintType.PRIMARY_KEY, constraint.getConstraintType()); + PrimaryConstraint primaryConstraint = (PrimaryConstraint)constraint; + assertEquals(2, primaryConstraint.getColNames().size()); + PartitionedBy partitionedBy = createTable.getPartitionedBy(); + assertNotNull(partitionedBy); + } + + @Test + public void testParsePartition() { + String text = "CREATE TABLE tbl4 (c1 INT PRIMARY KEY, c2 INT) PARTITION BY HASH(c1) PARTITIONS 8;"; + CreateTable createTable = oceanBaseMysqlParser.parseNode(text, ReverseContext.builder().build()); + assertNotNull(createTable); + } + + @Test + public void testParseDataType() { + OceanBaseMysqlLanguageParser mysqlLanguageParser = new OceanBaseMysqlLanguageParser(); + BaseDataType baseDataType = mysqlLanguageParser.parseDataType("varchar(100)", ReverseContext.builder().build()); + assertEquals("VARCHAR", baseDataType.getTypeName().getName()); + } +} \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/OceanBaseMysqlDataTypeNameTest.java b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/OceanBaseMysqlDataTypeNameTest.java new file mode 100644 index 0000000..5dcaabf --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/java/com/aliyun/fastmodel/transform/oceanbase/parser/tree/OceanBaseMysqlDataTypeNameTest.java @@ -0,0 +1,21 @@ +package com.aliyun.fastmodel.transform.oceanbase.parser.tree; + +import com.aliyun.fastmodel.core.tree.datatype.IDataTypeName; +import com.aliyun.fastmodel.core.tree.datatype.IDataTypeName.Dimension; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * Desc: + * + * @author panguanjing + * @date 2024/2/19 + */ +public class OceanBaseMysqlDataTypeNameTest { + @Test + public void testDataTypeName() { + IDataTypeName varchar = OceanBaseMysqlDataTypeName.getByValue("varchar"); + assertEquals(Dimension.ONE, varchar.getDimension()); + } +} \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/range_error.txt b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/range_error.txt new file mode 100644 index 0000000..b31ac07 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/range_error.txt @@ -0,0 +1,18 @@ +CREATE TABLE employees1 ( + id INT NOT NULL, + first_name VARCHAR(30), + last_name VARCHAR(30), + hired_date DATE NOT NULL, + salary INT NOT NULL, + PRIMARY KEY (id, hired_date) +) ENGINE=InnoDB +PARTITION BY RANGE (YEAR(hired_date)) ( + PARTITION p0 VALUES LESS THAN (1991), + PARTITION p1 VALUES LESS THAN (1996), + PARTITION p2 VALUES LESS THAN (2001), + PARTITION p3 VALUES LESS THAN (2006), + PARTITION p4 VALUES LESS THAN (2011), + PARTITION p5 VALUES LESS THAN (2016), + PARTITION p6 VALUES LESS THAN (2021), + PARTITION p7 VALUES LESS THAN MAXVALUE +); \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple1.txt b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple1.txt new file mode 100644 index 0000000..2fa32f4 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple1.txt @@ -0,0 +1 @@ +CREATE TABLE tbl1 (c1 INT PRIMARY KEY, c2 VARCHAR(50)); \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple1_comment.txt b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple1_comment.txt new file mode 100644 index 0000000..80b3a88 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple1_comment.txt @@ -0,0 +1 @@ +CREATE TABLE tbl1 (c1 INT PRIMARY KEY, c2 VARCHAR(50)) COMMENT 'comment' PARTITION BY KEY (c1) PARTITIONS 8; \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple2_index.txt b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple2_index.txt new file mode 100644 index 0000000..829046d --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple2_index.txt @@ -0,0 +1 @@ +CREATE TABLE tbl2 (c1 INT PRIMARY KEY, c2 INT, c3 INT, INDEX i1 (c2)); \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple2_index2.txt b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple2_index2.txt new file mode 100644 index 0000000..7f037f7 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple2_index2.txt @@ -0,0 +1 @@ +CREATE TABLE tbl3 (c1 INT, c2 INT, INDEX i1 ((c1+1)), UNIQUE KEY ((c1+c2))); \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple3_hash.txt b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple3_hash.txt new file mode 100644 index 0000000..0282ad0 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple3_hash.txt @@ -0,0 +1 @@ +CREATE TABLE tbl4 (c1 INT PRIMARY KEY, c2 INT) PARTITION BY HASH(c1) PARTITIONS 8; \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple3_range.txt b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple3_range.txt new file mode 100644 index 0000000..c91b4d3 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple3_range.txt @@ -0,0 +1,3 @@ +CREATE TABLE tbl5 (c1 INT, c2 INT, c3 INT) PARTITION BY RANGE(c1) + SUBPARTITION BY KEY(c2, c3) SUBPARTITIONS 5 + (PARTITION p0 VALUES LESS THAN(0), PARTITION p1 VALUES LESS THAN(100)); \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple4_charset.txt b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple4_charset.txt new file mode 100644 index 0000000..60fd175 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple4_charset.txt @@ -0,0 +1,3 @@ +CREATE TABLE tbl6 (c1 VARCHAR(10), + c2 VARCHAR(10) CHARSET GBK COLLATE gbk_bin) + DEFAULT CHARSET utf8 COLLATE utf8mb4_general_ci; \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple5_compress.txt b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple5_compress.txt new file mode 100644 index 0000000..1465e53 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple5_compress.txt @@ -0,0 +1,4 @@ +CREATE TABLE tbl7 (c1 INT, c2 INT, c3 VARCHAR(64)) + COMPRESSION 'zstd_1.0' + ROW_FORMAT DYNAMIC + PCTFREE 5; \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple6_pr.txt b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple6_pr.txt new file mode 100644 index 0000000..d4c5479 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple6_pr.txt @@ -0,0 +1 @@ +CREATE TABLE tbl8(c1 INT PRIMARY KEY, c2 INT) PARALLEL 3; \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple7_autoincrement.txt b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple7_autoincrement.txt new file mode 100644 index 0000000..a9a6ad5 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple7_autoincrement.txt @@ -0,0 +1,2 @@ +CREATE TABLE tbl9(inv_id BIGINT NOT NULL AUTO_INCREMENT,c1 BIGINT, +PRIMARY KEY (inv_id) ) PARTITION BY HASH(inv_id) PARTITIONS 8; \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple8_check.txt b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple8_check.txt new file mode 100644 index 0000000..6e2975f --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple8_check.txt @@ -0,0 +1 @@ +CREATE TABLE tbl10 (col1 INT, col2 INT, col3 INT, CONSTRAINT equal_check1 CHECK(col1 = col3 * 2)); \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple8_reference.txt b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple8_reference.txt new file mode 100644 index 0000000..3911c99 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple8_reference.txt @@ -0,0 +1 @@ +CREATE TABLE ref_t2(c1 INT PRIMARY KEY, C2 INT,FOREIGN KEY(c2) REFERENCES ref_t1(c1) ON UPDATE SET NULL); \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple9_pt_combine_1.txt b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple9_pt_combine_1.txt new file mode 100644 index 0000000..b3fd954 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple9_pt_combine_1.txt @@ -0,0 +1,12 @@ +CREATE TABLE tb1_m_rcr(col1 INT,col2 INT) + PARTITION BY RANGE COLUMNS(col1) + SUBPARTITION BY RANGE(col2) + SUBPARTITION TEMPLATE + (SUBPARTITION mp0 VALUES LESS THAN(3), + SUBPARTITION mp1 VALUES LESS THAN(6), + SUBPARTITION mp2 VALUES LESS THAN(9) + ) + (PARTITION p0 VALUES LESS THAN(100), + PARTITION p1 VALUES LESS THAN(200), + PARTITION p2 VALUES LESS THAN(300) + ); \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple9_pt_combine_2.txt b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple9_pt_combine_2.txt new file mode 100644 index 0000000..306ec94 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple9_pt_combine_2.txt @@ -0,0 +1,16 @@ +CREATE TABLE tbl2_f_llc(col1 INT,col2 DATE) + PARTITION BY LIST(col1) + SUBPARTITION BY LIST COLUMNS(col2) + (PARTITION p0 VALUES IN(100) + (SUBPARTITION sp0 VALUES IN('2021/04/01'), + SUBPARTITION sp1 VALUES IN('2021/07/01'), + SUBPARTITION sp2 VALUES IN('2021/10/01'), + SUBPARTITION sp3 VALUES IN('2022/01/01') + ), + PARTITION p1 VALUES IN(200) + (SUBPARTITION sp4 VALUES IN('2021/04/01'), + SUBPARTITION sp5 VALUES IN('2021/07/01'), + SUBPARTITION sp6 VALUES IN('2021/10/01'), + SUBPARTITION sp7 VALUES IN('2022/01/01') + ) + ); \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple9_pt_combine_3.txt b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple9_pt_combine_3.txt new file mode 100644 index 0000000..f058b44 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple9_pt_combine_3.txt @@ -0,0 +1,16 @@ +CREATE TABLE tbl3_f_hk (col1 INT,col2 VARCHAR(50)) + PARTITION BY HASH(col1) + SUBPARTITION BY KEY(col2) + (PARTITION p1 + (SUBPARTITION sp0 + ,SUBPARTITION sp1 + ,SUBPARTITION sp2 + ,SUBPARTITION sp3 + ), + PARTITION p2 + (SUBPARTITION sp4 + ,SUBPARTITION sp5 + ,SUBPARTITION sp6 + ,SUBPARTITION sp7 + ) + ); \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple9_pt_hash.txt b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple9_pt_hash.txt new file mode 100644 index 0000000..c8d8747 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple9_pt_hash.txt @@ -0,0 +1,2 @@ +CREATE TABLE tbl3_h(col1 INT,col2 VARCHAR(50)) + PARTITION BY HASH(col1) PARTITIONS 2; \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple9_pt_key.txt b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple9_pt_key.txt new file mode 100644 index 0000000..23abd96 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple9_pt_key.txt @@ -0,0 +1,3 @@ +CREATE TABLE tb1_rc(col1 INT,col2 INT) + PARTITION BY KEY (col1,col2) PARTITIONS 8 + ; \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple9_pt_list.txt b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple9_pt_list.txt new file mode 100644 index 0000000..d6beb09 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple9_pt_list.txt @@ -0,0 +1,5 @@ +CREATE TABLE tbl2_l (col1 INT,col2 DATE) + PARTITION BY LIST(col1) + (PARTITION p0 VALUES IN (100), + PARTITION p1 VALUES IN (200) + ); \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple9_pt_range.txt b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple9_pt_range.txt new file mode 100644 index 0000000..b973bfd --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-oceanbase/src/test/resources/oceanbase/simple9_pt_range.txt @@ -0,0 +1,6 @@ +CREATE TABLE tb1_rc(col1 INT,col2 INT) + PARTITION BY RANGE COLUMNS(col1) + (PARTITION p0 VALUES LESS THAN(100), + PARTITION p1 VALUES LESS THAN(200), + PARTITION p2 VALUES LESS THAN(300) + ); \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/StarRocksTransformer.java b/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/StarRocksTransformer.java index 20dc856..296c48a 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/StarRocksTransformer.java +++ b/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/StarRocksTransformer.java @@ -38,13 +38,13 @@ public class StarRocksTransformer implements Transformer { @Override public DialectNode transform(BaseStatement source, TransformContext context) { DialectMeta dialectMeta = new DialectMeta(DialectName.STARROCKS, IVersion.getDefault()); - StarRocksContext mysqlTransformContext = new StarRocksContext(context); - StatementBuilder builder = BuilderFactory.getInstance().getBuilder(source, dialectMeta, mysqlTransformContext); + StarRocksContext starRocksContext = new StarRocksContext(context); + StatementBuilder builder = BuilderFactory.getInstance().getBuilder(source, dialectMeta, starRocksContext); if (builder == null) { throw new UnsupportedOperationException( "UnSupported statement transform with target Dialect, source: " + source.getClass()); } - return builder.build(source, mysqlTransformContext); + return builder.build(source, starRocksContext); } @Override diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/converter/StarRocksClientConverter.java b/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/converter/StarRocksClientConverter.java index bbe2937..d8f54c6 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/converter/StarRocksClientConverter.java +++ b/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/converter/StarRocksClientConverter.java @@ -1,90 +1,38 @@ package com.aliyun.fastmodel.transform.starrocks.client.converter; import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.LinkedHashMap; import java.util.List; -import java.util.Optional; import java.util.stream.Collectors; -import com.aliyun.fastmodel.common.utils.StripUtils; +import com.aliyun.fastmodel.core.parser.LanguageParser; +import com.aliyun.fastmodel.core.tree.Node; import com.aliyun.fastmodel.core.tree.Property; import com.aliyun.fastmodel.core.tree.QualifiedName; -import com.aliyun.fastmodel.core.tree.datatype.BaseDataType; import com.aliyun.fastmodel.core.tree.datatype.IDataTypeName; -import com.aliyun.fastmodel.core.tree.datatype.IDataTypeName.Dimension; -import com.aliyun.fastmodel.core.tree.expr.BaseExpression; import com.aliyun.fastmodel.core.tree.expr.Identifier; -import com.aliyun.fastmodel.core.tree.expr.atom.FunctionCall; -import com.aliyun.fastmodel.core.tree.expr.enums.DateTimeEnum; -import com.aliyun.fastmodel.core.tree.expr.literal.IntervalLiteral; -import com.aliyun.fastmodel.core.tree.expr.literal.ListStringLiteral; -import com.aliyun.fastmodel.core.tree.expr.literal.LongLiteral; -import com.aliyun.fastmodel.core.tree.expr.literal.StringLiteral; import com.aliyun.fastmodel.core.tree.statement.table.ColumnDefinition; import com.aliyun.fastmodel.core.tree.statement.table.CreateTable; -import com.aliyun.fastmodel.core.tree.statement.table.PartitionedBy; import com.aliyun.fastmodel.core.tree.statement.table.constraint.BaseConstraint; import com.aliyun.fastmodel.core.tree.statement.table.constraint.PrimaryConstraint; -import com.aliyun.fastmodel.core.tree.statement.table.index.IndexColumnName; -import com.aliyun.fastmodel.core.tree.statement.table.index.TableIndex; import com.aliyun.fastmodel.core.tree.util.IdentifierUtil; import com.aliyun.fastmodel.transform.api.client.PropertyConverter; -import com.aliyun.fastmodel.transform.api.client.converter.BaseClientConverter; import com.aliyun.fastmodel.transform.api.client.dto.constraint.Constraint; -import com.aliyun.fastmodel.transform.api.client.dto.constraint.ConstraintType; import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; -import com.aliyun.fastmodel.transform.api.client.dto.property.StringProperty; import com.aliyun.fastmodel.transform.api.client.dto.table.Column; -import com.aliyun.fastmodel.transform.api.client.dto.table.Table; -import com.aliyun.fastmodel.transform.api.context.ReverseContext; -import com.aliyun.fastmodel.transform.api.datatype.simple.ISimpleDataTypeName; -import com.aliyun.fastmodel.transform.api.datatype.simple.SimpleDataTypeName; -import com.aliyun.fastmodel.transform.starrocks.client.constraint.StarRocksConstraintType; -import com.aliyun.fastmodel.transform.starrocks.client.constraint.StarRocksDistributeConstraint; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.ColumnExpressionPartitionProperty; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.ListPartitionProperty; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.MultiRangePartitionProperty; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.SingleRangePartitionProperty; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.TablePartitionRaw; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.TimeExpressionPartitionProperty; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.ArrayClientPartitionKey; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.BaseClientPartitionKey; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.ColumnExpressionClientPartition; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.LessThanClientPartitionKey; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.ListClientPartition; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.MultiRangeClientPartition; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.PartitionClientValue; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.SingleRangeClientPartition; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.TimeExpressionClientPartition; +import com.aliyun.fastmodel.transform.api.extension.client.constraint.ClientConstraintType; +import com.aliyun.fastmodel.transform.api.extension.client.constraint.DistributeClientConstraint; +import com.aliyun.fastmodel.transform.api.extension.client.converter.ExtensionClientConverter; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.AggregateKeyConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.DuplicateKeyConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.DistributeConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.OrderByConstraint; import com.aliyun.fastmodel.transform.starrocks.context.StarRocksContext; import com.aliyun.fastmodel.transform.starrocks.format.StarRocksOutVisitor; -import com.aliyun.fastmodel.transform.starrocks.format.StarRocksProperty; import com.aliyun.fastmodel.transform.starrocks.parser.StarRocksLanguageParser; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.AggregateKeyConstraint; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.DuplicateKeyConstraint; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.desc.DistributeConstraint; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.desc.OrderByConstraint; import com.aliyun.fastmodel.transform.starrocks.parser.tree.datatype.StarRocksDataTypeName; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.ArrayPartitionKey; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.ExpressionPartitionBy; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.LessThanPartitionKey; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.ListPartitionValue; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.ListPartitionedBy; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.MultiItemListPartition; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.MultiRangePartition; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.PartitionDesc; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.PartitionKey; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.PartitionValue; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.RangePartitionedBy; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.SingleItemListPartition; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.SingleRangePartition; import com.google.common.collect.Lists; -import com.google.common.collect.Maps; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.BooleanUtils; -import org.apache.commons.lang3.StringUtils; /** * StarRocksClientConverter @@ -92,11 +40,7 @@ * @author panguanjing * @date 2023/9/16 */ -public class StarRocksClientConverter extends BaseClientConverter { - - public static final String UUID = "uuid"; - public static final String UUID_NUMERIC = "uuid_numeric"; - public static final String SUFFIX = "()"; +public class StarRocksClientConverter extends ExtensionClientConverter { private final StarRocksLanguageParser starRocksLanguageParser = new StarRocksLanguageParser(); @@ -110,7 +54,7 @@ public PropertyConverter getPropertyConverter() { @Override protected List toOutlineConstraint(CreateTable createTable) { List outlineConstraint = super.toOutlineConstraint(createTable); - if (createTable.isConstraintEmpty() && createTable.isIndexEmpty()) { + if (createTable.isConstraintEmpty()) { return outlineConstraint; } List constraintStatements = createTable.getConstraintStatements(); @@ -122,37 +66,13 @@ protected List toOutlineConstraint(CreateTable createTable) { convertConstraint(baseConstraint, outlineConstraint); } } - if (!createTable.isIndexEmpty()) { - for (TableIndex index : createTable.getTableIndexList()) { - List indexColumnNames = index.getIndexColumnNames(); - List collect = indexColumnNames.stream().map(i -> { - return i.getColumnName().toString(); - }).collect(Collectors.toList()); - List es = Lists.newArrayList(); - List properties = index.getProperties(); - if (properties != null) { - for (Property p : properties) { - BaseClientProperty baseClientProperty = getPropertyConverter().create(p.getName(), p.getValue()); - es.add(baseClientProperty); - } - } - Constraint constraint = Constraint.builder() - .name(index.getName().getValue()) - .columns(collect) - .type(StarRocksConstraintType.INDEX) - .properties(es) - .build(); - outlineConstraint.add(constraint); - } - } return outlineConstraint; - } private void convertConstraint(BaseConstraint baseConstraint, List outlineConstraint) { if (baseConstraint instanceof DistributeConstraint) { DistributeConstraint distributeConstraint = (DistributeConstraint)baseConstraint; - StarRocksDistributeConstraint starRocksDistributeConstraint = toStarRocksDistributeConstraint(distributeConstraint); + DistributeClientConstraint starRocksDistributeConstraint = toStarRocksDistributeConstraint(distributeConstraint); outlineConstraint.add(starRocksDistributeConstraint); return; } @@ -180,14 +100,14 @@ private Constraint toDuplicateClientConstraint(DuplicateKeyConstraint aggregateK List collect = aggregateKeyConstraint.getColumns().stream().map(Identifier::getValue).collect(Collectors.toList()); return Constraint.builder().name(aggregateKeyConstraint.getName().getValue()) .columns(collect) - .type(StarRocksConstraintType.DUPLICATE_KEY) + .type(ClientConstraintType.DUPLICATE_KEY) .build(); } private Constraint toAggregateClientConstraint(AggregateKeyConstraint aggregateKeyConstraint) { List collect = aggregateKeyConstraint.getColumns().stream().map(Identifier::getValue).collect(Collectors.toList()); return Constraint.builder().name(aggregateKeyConstraint.getName().getValue()) - .columns(collect).type(StarRocksConstraintType.AGGREGATE_KEY) + .columns(collect).type(ClientConstraintType.AGGREGATE_KEY) .build(); } @@ -195,12 +115,12 @@ private Constraint toOrderClientConstraint(OrderByConstraint orderByConstraint) List collect = orderByConstraint.getColumns().stream().map(Identifier::getValue).collect(Collectors.toList()); return Constraint.builder().name(orderByConstraint.getName().getValue()) .columns(collect) - .type(StarRocksConstraintType.ORDER_BY) + .type(ClientConstraintType.ORDER_BY) .build(); } - private StarRocksDistributeConstraint toStarRocksDistributeConstraint(DistributeConstraint distributeConstraint) { - StarRocksDistributeConstraint starRocksDistributeConstraint = new StarRocksDistributeConstraint(); + private DistributeClientConstraint toStarRocksDistributeConstraint(DistributeConstraint distributeConstraint) { + DistributeClientConstraint starRocksDistributeConstraint = new DistributeClientConstraint(); starRocksDistributeConstraint.setBucket(distributeConstraint.getBucket()); if (CollectionUtils.isNotEmpty(distributeConstraint.getColumns())) { starRocksDistributeConstraint.setColumns( @@ -210,85 +130,6 @@ private StarRocksDistributeConstraint toStarRocksDistributeConstraint(Distribute return starRocksDistributeConstraint; } - @Override - protected List toConstraint(List columns, List constraints) { - List baseConstraints = super.toConstraint(columns, constraints); - if (constraints == null) { - return baseConstraints; - } - for (Constraint constraint : constraints) { - ConstraintType type = constraint.getType(); - if (type == StarRocksConstraintType.DISTRIBUTE) { - DistributeConstraint distributeConstraint = toDistributeConstraint(constraint); - if (distributeConstraint == null) { - continue; - } - baseConstraints.add(distributeConstraint); - } - if (type == StarRocksConstraintType.ORDER_BY) { - OrderByConstraint orderByConstraint = toOrderByConstraint(constraint); - baseConstraints.add(orderByConstraint); - } - - if (type == StarRocksConstraintType.DUPLICATE_KEY) { - DuplicateKeyConstraint duplicateKeyConstraint = toDuplicateKeyConstraint(constraint); - baseConstraints.add(duplicateKeyConstraint); - } - - if (type == StarRocksConstraintType.AGGREGATE_KEY) { - AggregateKeyConstraint aggregateKeyConstraint = toAggregateKeyConstraint(constraint); - baseConstraints.add(aggregateKeyConstraint); - } - } - return baseConstraints; - } - - private AggregateKeyConstraint toAggregateKeyConstraint(Constraint constraint) { - return new AggregateKeyConstraint( - IdentifierUtil.sysIdentifier(), - constraint.getColumns().stream().map(Identifier::new).collect(Collectors.toList()) - ); - } - - private DuplicateKeyConstraint toDuplicateKeyConstraint(Constraint constraint) { - return new DuplicateKeyConstraint( - IdentifierUtil.sysIdentifier(), - constraint.getColumns().stream().map(Identifier::new).collect(Collectors.toList()), - true - ); - } - - private OrderByConstraint toOrderByConstraint(Constraint constraint) { - String name = constraint.getName(); - Identifier nameIdentifier = null; - if (StringUtils.isBlank(name)) { - nameIdentifier = IdentifierUtil.sysIdentifier(); - } else { - nameIdentifier = new Identifier(name); - } - List collect = constraint.getColumns().stream().map(Identifier::new).collect(Collectors.toList()); - return new OrderByConstraint(nameIdentifier, collect); - } - - private DistributeConstraint toDistributeConstraint(Constraint constraint) { - if (constraint instanceof StarRocksDistributeConstraint) { - StarRocksDistributeConstraint starRocksDistributeConstraint = (StarRocksDistributeConstraint)constraint; - List list = null; - if (CollectionUtils.isNotEmpty(constraint.getColumns())) { - list = constraint.getColumns().stream().map(Identifier::new).collect(Collectors.toList()); - return new DistributeConstraint(list, starRocksDistributeConstraint.getBucket()); - } else { - return new DistributeConstraint(starRocksDistributeConstraint.getRandom(), starRocksDistributeConstraint.getBucket()); - } - } - List list = null; - if (CollectionUtils.isNotEmpty(constraint.getColumns())) { - list = constraint.getColumns().stream().map(Identifier::new).collect(Collectors.toList()); - return new DistributeConstraint(list, null); - } - return null; - } - @Override protected Column getColumn(ColumnDefinition c, boolean partitionKey, Integer partitionKeyIndex) { Column column = super.getColumn(c, partitionKey, partitionKeyIndex); @@ -306,107 +147,20 @@ protected Column getColumn(ColumnDefinition c, boolean partitionKey, Integer par } @Override - protected BaseDataType getDataType(Column column) { - String dataTypeName = column.getDataType(); - if (StringUtils.isBlank(dataTypeName)) { - throw new IllegalArgumentException("dataType name can't be null:" + column.getName()); - } - IDataTypeName byValue = StarRocksDataTypeName.getByValue(dataTypeName); - Dimension dimension = byValue.getDimension(); - ReverseContext context = ReverseContext.builder().build(); - if (dimension == null || dimension == Dimension.ZERO) { - return starRocksLanguageParser.parseDataType(dataTypeName, context); - } - if (dimension == Dimension.ONE) { - boolean isValidLength = column.getLength() != null && column.getLength() > 0; - if (isValidLength) { - String dt = String.format(ONE_DIMENSION, dataTypeName, column.getLength()); - return starRocksLanguageParser.parseDataType(dt, context); - } - } - if (dimension == Dimension.TWO) { - if (column.getPrecision() != null) { - if (column.getScale() == null) { - return starRocksLanguageParser.parseDataType(String.format(ONE_DIMENSION, dataTypeName, column.getPrecision()), context); - } - return starRocksLanguageParser.parseDataType(String.format(TWO_DIMENSION, dataTypeName, column.getPrecision(), column.getScale()), - context); - } - } - return starRocksLanguageParser.parseDataType(dataTypeName, context); - } - - @Override - protected PartitionedBy toPartitionedBy(Table table, List columns) { - //convert to starRockPartitionBy - List properties = table.getProperties(); - List list = columns.stream() - .filter(Column::isPartitionKey) - .sorted(Comparator.comparing(Column::getPartitionKeyIndex)) - .map(x -> { - List clientProperties = x.getProperties(); - return ColumnDefinition.builder().colName(new Identifier(x.getName())) - .properties(toProperty(table, clientProperties)) - .build(); - }) - .collect(Collectors.toList()); - return toPartition(list, properties); + public IDataTypeName getDataTypeName(String dataTypeName) { + return StarRocksDataTypeName.getByValue(dataTypeName); } @Override - protected List toTableIndex(Table table, List columns) { - if (table == null || CollectionUtils.isEmpty(table.getConstraints())) { - return Collections.emptyList(); - } - List indexConstraints = table.getConstraints().stream() - .filter(constraint -> StarRocksConstraintType.INDEX == constraint.getType()) - .collect(Collectors.toList()); - if (CollectionUtils.isEmpty(indexConstraints)) { - return Collections.emptyList(); - } - return indexConstraints.stream().map(indexConstraint -> { - Identifier indexName = new Identifier(indexConstraint.getName()); - List indexColumnNames = indexConstraint.getColumns().stream() - .map(column -> new IndexColumnName(new Identifier(column), null, null)).collect(Collectors.toList()); - - List properties = null; - if (CollectionUtils.isNotEmpty(indexConstraint.getProperties())) { - properties = indexConstraint.getProperties().stream().map(property -> { - return new Property(property.getKey(), (String)property.getValue()); - }).collect(Collectors.toList()); - } - return new TableIndex(indexName, indexColumnNames, properties); - }).collect(Collectors.toList()); + public LanguageParser getLanguageParser() { + return this.starRocksLanguageParser; } @Override - protected List toBaseClientProperty(CreateTable createTable) { - List propertyList = Lists.newArrayList(); - if (!createTable.isPropertyEmpty()) { - List properties = createTable.getProperties(); - for (Property property : properties) { - BaseClientProperty baseClientProperty = getPropertyConverter().create(property.getName(), property.getValue()); - propertyList.add(baseClientProperty); - } - } - - PartitionedBy partitionedBy = createTable.getPartitionedBy(); - if (createTable.isPartitionEmpty()) { - return propertyList; - } - if (partitionedBy instanceof RangePartitionedBy) { - processRangePartition((RangePartitionedBy)partitionedBy, propertyList); - } - - if (partitionedBy instanceof ListPartitionedBy) { - processListPartition((ListPartitionedBy)partitionedBy, propertyList); - } - - if (partitionedBy instanceof ExpressionPartitionBy) { - processExpressionPartition((ExpressionPartitionBy)partitionedBy, propertyList); - } - - return propertyList; + public String getRaw(Node node) { + StarRocksOutVisitor starRocksOutVisitor = new StarRocksOutVisitor(StarRocksContext.builder().build()); + node.accept(starRocksOutVisitor, 0); + return starRocksOutVisitor.getBuilder().toString(); } /** @@ -454,379 +208,6 @@ protected String toDatabase(CreateTable createTable, String database) { return database; } - private void processRangePartition(RangePartitionedBy rangePartitionedBy, List propertyList) { - List rangePartitions = rangePartitionedBy.getRangePartitions(); - //结构化的返回 - List list = Lists.newArrayList(); - for (PartitionDesc partitionDesc : rangePartitions) { - BaseClientProperty baseClientProperty = parseRangePartition(partitionDesc); - if (baseClientProperty != null) { - list.add(baseClientProperty); - } - } - //如果解析不了,那么使用visitor的方式进行解析 - if (list.isEmpty()) { - StarRocksOutVisitor starRocksOutVisitor = new StarRocksOutVisitor(StarRocksContext.builder().build()); - starRocksOutVisitor.visitRangePartitionedBy(rangePartitionedBy, 0); - TablePartitionRaw baseClientProperty = new TablePartitionRaw(); - baseClientProperty.setKey(StarRocksProperty.TABLE_PARTITION_RAW.getValue()); - baseClientProperty.setValueString(starRocksOutVisitor.getBuilder().toString()); - propertyList.add(baseClientProperty); - } else { - propertyList.addAll(list); - } - } - - private void processListPartition(ListPartitionedBy listPartitionedBy, List propertyList) { - List listPartitions = listPartitionedBy.getListPartitions(); - //结构化的返回 - List list = Lists.newArrayList(); - for (PartitionDesc partitionDesc : listPartitions) { - BaseClientProperty baseClientProperty = parseListPartition(partitionDesc); - if (baseClientProperty != null) { - list.add(baseClientProperty); - } - } - - //如果解析不了,那么使用visitor的方式进行解析 - if (list.isEmpty()) { - StarRocksOutVisitor starRocksOutVisitor = new StarRocksOutVisitor(StarRocksContext.builder().build()); - starRocksOutVisitor.visitListPartitionedBy(listPartitionedBy, 0); - StringProperty baseClientProperty = new StringProperty(); - baseClientProperty.setKey(StarRocksProperty.TABLE_PARTITION_RAW.getValue()); - baseClientProperty.setValueString(starRocksOutVisitor.getBuilder().toString()); - propertyList.add(baseClientProperty); - } else { - propertyList.addAll(list); - } - } - - private void processExpressionPartition(ExpressionPartitionBy expressionPartitionBy, - List propertyList) { - FunctionCall functionCall = expressionPartitionBy.getFunctionCall(); - if (functionCall == null) { - // 列表达式 - ColumnExpressionClientPartition partition = new ColumnExpressionClientPartition(); - List columnNameList = expressionPartitionBy.getColumnDefinitions().stream() - .map(columnDefinition -> columnDefinition.getColName().getValue()) - .collect(Collectors.toList()); - partition.setColumnNameList(columnNameList); - - ColumnExpressionPartitionProperty columnExpressionPartitionProperty = new ColumnExpressionPartitionProperty(); - columnExpressionPartitionProperty.setValue(partition); - propertyList.add(columnExpressionPartitionProperty); - } else { - // 时间函数表达式 - TimeExpressionClientPartition timeExpressionClientPartition = new TimeExpressionClientPartition(); - timeExpressionClientPartition.setFuncName(functionCall.getFuncName().getFirst()); - if (expressionPartitionBy.getTimeUnitArg() != null) { - timeExpressionClientPartition.setTimeUnit(StripUtils.strip(expressionPartitionBy.getTimeUnitArg().getOrigin())); - } - if (expressionPartitionBy.getIntervalLiteralArg() != null) { - timeExpressionClientPartition.setInterval(expressionPartitionBy.getIntervalLiteralArg()); - } - - //property - TimeExpressionPartitionProperty timeExpressionPartitionProperty = new TimeExpressionPartitionProperty(); - timeExpressionPartitionProperty.setValue(timeExpressionClientPartition); - propertyList.add(timeExpressionPartitionProperty); - } - } - - /** - * 将partition desc转为 baseClientProperty - * - * @param partitionDesc - */ - private BaseClientProperty parseRangePartition(PartitionDesc partitionDesc) { - if (partitionDesc instanceof SingleRangePartition) { - SingleRangePartition singleRangePartition = (SingleRangePartition)partitionDesc; - SingleRangeClientPartition rangePartitionValue = new SingleRangeClientPartition(); - rangePartitionValue.setName(singleRangePartition.getName().getValue()); - rangePartitionValue.setIfNotExists(singleRangePartition.isIfNotExists()); - List propertyList = singleRangePartition.getPropertyList(); - if (propertyList != null && !propertyList.isEmpty()) { - LinkedHashMap linkedHashMap = Maps.newLinkedHashMap(); - for (Property p : propertyList) { - linkedHashMap.put(p.getName(), p.getValue()); - } - rangePartitionValue.setProperties(linkedHashMap); - } - BaseClientPartitionKey partitionKey = toClientPartitionKey(singleRangePartition.getPartitionKey()); - rangePartitionValue.setPartitionKey(partitionKey); - - //property - SingleRangePartitionProperty singleRangePartitionProperty = new SingleRangePartitionProperty(); - singleRangePartitionProperty.setValue(rangePartitionValue); - return singleRangePartitionProperty; - - } else if (partitionDesc instanceof MultiRangePartition) { - MultiRangePartition multiRangePartition = (MultiRangePartition)partitionDesc; - MultiRangeClientPartition multiRangePartitionValue = new MultiRangeClientPartition(); - multiRangePartitionValue.setStart(multiRangePartition.getStart().getValue()); - multiRangePartitionValue.setEnd(multiRangePartition.getEnd().getValue()); - if (multiRangePartition.getLongLiteral() != null) { - LongLiteral longLiteral = multiRangePartition.getLongLiteral(); - multiRangePartitionValue.setInterval(longLiteral.getValue()); - } - IntervalLiteral intervalLiteral = multiRangePartition.getIntervalLiteral(); - if (intervalLiteral != null) { - DateTimeEnum fromDateTime = intervalLiteral.getFromDateTime(); - multiRangePartitionValue.setDateTimeEnum(fromDateTime); - LongLiteral value = (LongLiteral)intervalLiteral.getValue(); - multiRangePartitionValue.setInterval(value.getValue()); - } - //property - MultiRangePartitionProperty multiRangePartitionProperty = new MultiRangePartitionProperty(); - multiRangePartitionProperty.setValue(multiRangePartitionValue); - return multiRangePartitionProperty; - } - return null; - } - - private BaseClientProperty parseListPartition(PartitionDesc partitionDesc) { - if (partitionDesc instanceof SingleItemListPartition) { - SingleItemListPartition singleListPartition = (SingleItemListPartition)partitionDesc; - ListClientPartition listPartitionValue = new ListClientPartition(); - listPartitionValue.setName(singleListPartition.getName().getOrigin()); - List> partitionValue = singleListPartition.getListStringLiteral() - .getStringLiteralList().stream() - .map(stringLiteral -> { - PartitionClientValue partitionClientValue = PartitionClientValue.builder() - .value(StripUtils.strip(stringLiteral.getValue())).build(); - return Lists.newArrayList(partitionClientValue); - }).collect(Collectors.toList()); - ArrayClientPartitionKey arrayClientPartitionKey = ArrayClientPartitionKey.builder() - .partitionValue(partitionValue).build(); - listPartitionValue.setPartitionKey(arrayClientPartitionKey); - - //property - ListPartitionProperty listPartitionProperty = new ListPartitionProperty(); - listPartitionProperty.setValue(listPartitionValue); - return listPartitionProperty; - } else if (partitionDesc instanceof MultiItemListPartition) { - MultiItemListPartition multiItemListPartition = (MultiItemListPartition)partitionDesc; - ListClientPartition listPartitionValue = new ListClientPartition(); - listPartitionValue.setName(multiItemListPartition.getName().getOrigin()); - List> partitionValue = multiItemListPartition.getListStringLiterals().stream() - .map(listStringLiteral -> listStringLiteral.getStringLiteralList().stream() - .map(stringLiteral -> PartitionClientValue.builder() - .value(StripUtils.strip(stringLiteral.getValue())).build()) - .collect(Collectors.toList())).collect(Collectors.toList()); - ArrayClientPartitionKey arrayClientPartitionKey = ArrayClientPartitionKey.builder() - .partitionValue(partitionValue).build(); - listPartitionValue.setPartitionKey(arrayClientPartitionKey); - - //property - ListPartitionProperty listPartitionProperty = new ListPartitionProperty(); - listPartitionProperty.setValue(listPartitionValue); - return listPartitionProperty; - } - return null; - } - - private BaseClientPartitionKey toClientPartitionKey(PartitionKey partitionKey) { - if (partitionKey instanceof ArrayPartitionKey) { - ArrayPartitionKey arrayPartitionKey = (ArrayPartitionKey)partitionKey; - List partitionValues1 = arrayPartitionKey.getPartitionValues(); - ArrayClientPartitionKey arrayClientPartitionKey = new ArrayClientPartitionKey(); - List> partitionValues = partitionValues1.stream().map(x -> { - List partitionValueList = x.getPartitionValueList(); - return partitionValueList.stream().map(p -> { - PartitionClientValue partitionClientValue = new PartitionClientValue(); - partitionClientValue.setMaxValue(p.isMaxValue()); - if (p.getStringLiteral() != null) { - partitionClientValue.setValue(p.getStringLiteral().getValue()); - } - return partitionClientValue; - }).collect(Collectors.toList()); - }).collect(Collectors.toList()); - arrayClientPartitionKey.setPartitionValue(partitionValues); - return arrayClientPartitionKey; - } else if (partitionKey instanceof LessThanPartitionKey) { - LessThanPartitionKey lessThanPartitionKey = (LessThanPartitionKey)partitionKey; - LessThanClientPartitionKey lessThanClientPartitionKey = new LessThanClientPartitionKey(); - lessThanClientPartitionKey.setMaxValue(lessThanPartitionKey.isMaxValue()); - List list = lessThanPartitionKey.getPartitionValues().getPartitionValueList().stream().map( - x -> { - PartitionClientValue partitionClientValue = new PartitionClientValue(); - partitionClientValue.setMaxValue(x.isMaxValue()); - if (x.getStringLiteral() != null) { - partitionClientValue.setValue(x.getStringLiteral().getValue()); - } - return partitionClientValue; - } - ).collect(Collectors.toList()); - lessThanClientPartitionKey.setPartitionValueList(list); - return lessThanClientPartitionKey; - } - return null; - } - - private PartitionedBy toPartition(List columnDefinitionList, List properties) { - if (properties == null || properties.isEmpty()) { - return null; - } - - // range partition - List rangePartitionProperties = properties.stream().filter(property -> - StringUtils.equalsIgnoreCase(property.getKey(), StarRocksProperty.TABLE_RANGE_PARTITION.getValue())) - .collect(Collectors.toList()); - if (CollectionUtils.isNotEmpty(rangePartitionProperties)) { - List list = Lists.newArrayList(); - rangePartitionProperties.forEach(property -> toRangePartition(list, property)); - return new RangePartitionedBy(columnDefinitionList, list); - } - - // list partition - List listPartitionProperties = properties.stream().filter(property -> - StringUtils.equalsIgnoreCase(property.getKey(), StarRocksProperty.TABLE_LIST_PARTITION.getValue())) - .collect(Collectors.toList()); - if (CollectionUtils.isNotEmpty(listPartitionProperties)) { - List list = Lists.newArrayList(); - listPartitionProperties.forEach(property -> toListPartition(list, columnDefinitionList, property)); - return new ListPartitionedBy(columnDefinitionList, list); - } - - // expression partition - List expressionPartitionProperties = properties.stream().filter(property -> - StringUtils.equalsIgnoreCase(property.getKey(), StarRocksProperty.TABLE_EXPRESSION_PARTITION.getValue())) - .collect(Collectors.toList()); - if (CollectionUtils.isNotEmpty(expressionPartitionProperties)) { - FunctionCall functionCall = buildFunctionCall(expressionPartitionProperties.get(0)); - return new ExpressionPartitionBy(columnDefinitionList, functionCall, null); - } - - return null; - } - - private void toRangePartition(List list, BaseClientProperty baseClientProperty) { - if (baseClientProperty instanceof SingleRangePartitionProperty) { - SingleRangePartitionProperty value = (SingleRangePartitionProperty)baseClientProperty; - SingleRangeClientPartition rangePartitionValue = value.getValue(); - BaseClientPartitionKey partitionKeyValue = rangePartitionValue.getPartitionKey(); - PartitionKey partitionKey = null; - if (partitionKeyValue instanceof LessThanClientPartitionKey) { - LessThanClientPartitionKey lessThanClientPartitionKey = (LessThanClientPartitionKey)partitionKeyValue; - List partitionValueList = Optional.ofNullable(lessThanClientPartitionKey.getPartitionValueList()).orElse( - Lists.newArrayList()); - List collect = partitionValueList - .stream().map(x -> { - if (x.getValue() != null) { - PartitionValue partitionValue = new PartitionValue(x.isMaxValue(), new StringLiteral(x.getValue())); - return partitionValue; - } else { - PartitionValue partitionValue = new PartitionValue(x.isMaxValue(), null); - return partitionValue; - } - }) - .collect(Collectors.toList()); - partitionKey = new LessThanPartitionKey( - lessThanClientPartitionKey.isMaxValue(), - new ListPartitionValue(collect) - ); - } else if (partitionKeyValue instanceof ArrayClientPartitionKey) { - ArrayClientPartitionKey arrayClientPartitionKey = (ArrayClientPartitionKey)partitionKeyValue; - List collect = arrayClientPartitionKey.getPartitionValue().stream().map( - x -> { - List partitionValueList = Lists.newArrayList(); - for (PartitionClientValue partitionClientValue : x) { - PartitionValue partitionValue = new PartitionValue(partitionClientValue.isMaxValue(), - new StringLiteral(partitionClientValue.getValue())); - partitionValueList.add(partitionValue); - } - return new ListPartitionValue(partitionValueList); - } - ).collect(Collectors.toList()); - partitionKey = new ArrayPartitionKey(collect); - } - PartitionDesc rangePartition = new SingleRangePartition( - new Identifier(rangePartitionValue.getName()), - rangePartitionValue.isIfNotExists(), - partitionKey, - null - ); - list.add(rangePartition); - } else if (baseClientProperty instanceof MultiRangePartitionProperty) { - MultiRangePartitionProperty multiRangePartitionProperty = (MultiRangePartitionProperty)baseClientProperty; - MultiRangeClientPartition value = multiRangePartitionProperty.getValue(); - LongLiteral longLiteral = new LongLiteral(String.valueOf(value.getInterval())); - PartitionDesc rangePartition = new MultiRangePartition( - new StringLiteral(value.getStart()), - new StringLiteral(value.getEnd()), - value.getDateTimeEnum() != null ? new IntervalLiteral(longLiteral, value.getDateTimeEnum()) : null, - value.getDateTimeEnum() == null ? longLiteral : null - ); - list.add(rangePartition); - } - } - - private void toListPartition(List list, List columnDefinitionList, - BaseClientProperty baseClientProperty) { - if (!(baseClientProperty instanceof ListPartitionProperty)) { - return; - } - boolean multiPartition = columnDefinitionList.size() > 1; - ListPartitionProperty listPartitionProperty = (ListPartitionProperty)baseClientProperty; - ListClientPartition listClientPartition = listPartitionProperty.getValue(); - BaseClientPartitionKey partitionKeyValue = listClientPartition.getPartitionKey(); - if (!(partitionKeyValue instanceof ArrayClientPartitionKey)) { - return; - } - ArrayClientPartitionKey arrayClientPartitionKey = (ArrayClientPartitionKey)partitionKeyValue; - if (multiPartition) { - List collect = arrayClientPartitionKey.getPartitionValue().stream().map( - x -> { - List partitionValueList = Lists.newArrayList(); - for (PartitionClientValue partitionClientValue : x) { - partitionValueList.add(new StringLiteral(partitionClientValue.getValue())); - } - return new ListStringLiteral(partitionValueList); - } - ).collect(Collectors.toList()); - MultiItemListPartition listPartition = new MultiItemListPartition( - new Identifier(listClientPartition.getName()), - false, - collect, - null - ); - list.add(listPartition); - } else { - List collect = arrayClientPartitionKey.getPartitionValue().stream().map( - x -> { - PartitionClientValue partitionClientValue = x.get(0); - return new StringLiteral(partitionClientValue.getValue()); - } - ).collect(Collectors.toList()); - ListStringLiteral partitionKey = new ListStringLiteral(collect); - SingleItemListPartition listPartition = new SingleItemListPartition( - new Identifier(listClientPartition.getName()), - false, - partitionKey, - null - ); - list.add(listPartition); - } - } - - private FunctionCall buildFunctionCall(BaseClientProperty baseClientProperty) { - if (!(baseClientProperty instanceof TimeExpressionPartitionProperty)) { - return null; - } - TimeExpressionPartitionProperty timeExpressionPartitionProperty = (TimeExpressionPartitionProperty)baseClientProperty; - TimeExpressionClientPartition timeExpressionClientPartition = timeExpressionPartitionProperty.getValue(); - List arguments = new ArrayList<>(); - if (StringUtils.isNotBlank(timeExpressionClientPartition.getTimeUnit())) { - arguments.add(new StringLiteral(timeExpressionClientPartition.getTimeUnit())); - } - if (timeExpressionClientPartition.getInterval() != null) { - arguments.add(timeExpressionClientPartition.getInterval()); - } - return new FunctionCall(QualifiedName.of(timeExpressionClientPartition.getFuncName()), - false, arguments); - - } - protected BaseConstraint setPrimaryConstraintColumns(List columns) { if (CollectionUtils.isEmpty(columns)) { return null; @@ -847,24 +228,4 @@ protected BaseConstraint setPrimaryConstraintColumns(List columns) { return baseConstraint; } - protected BaseExpression toDefaultValueExpression(BaseDataType baseDataType, String defaultValue) { - if (defaultValue == null) { - return null; - } - IDataTypeName typeName = baseDataType.getTypeName(); - if (StringUtils.equalsIgnoreCase(defaultValue, UUID + SUFFIX)) { - return new FunctionCall(QualifiedName.of(UUID), false, Lists.newArrayList()); - } - if (StringUtils.equalsIgnoreCase(defaultValue, UUID_NUMERIC + SUFFIX)) { - return new FunctionCall(QualifiedName.of(UUID_NUMERIC), false, Lists.newArrayList()); - } - if (typeName instanceof ISimpleDataTypeName) { - //starRocks 数字也是用字符标识 - ISimpleDataTypeName simpleDataTypeName = (ISimpleDataTypeName)typeName; - if (simpleDataTypeName.getSimpleDataTypeName() == SimpleDataTypeName.NUMBER) { - return new StringLiteral(defaultValue); - } - } - return super.toDefaultValueExpression(baseDataType, defaultValue); - } } diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/converter/StarRocksPropertyConverter.java b/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/converter/StarRocksPropertyConverter.java index 4186dde..4693e2e 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/converter/StarRocksPropertyConverter.java +++ b/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/converter/StarRocksPropertyConverter.java @@ -5,16 +5,23 @@ import com.aliyun.fastmodel.transform.api.client.converter.BasePropertyConverter; import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; -import com.aliyun.fastmodel.transform.starrocks.client.property.column.AggrColumnProperty; -import com.aliyun.fastmodel.transform.starrocks.client.property.index.IndexCommentProperty; -import com.aliyun.fastmodel.transform.starrocks.client.property.index.IndexTypeProperty; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.DistributeBucketsNum; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.DistributeHash; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.PartitionLiveNumberProperty; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.ReplicationNum; -import com.aliyun.fastmodel.transform.starrocks.format.StarRocksProperty; +import com.aliyun.fastmodel.transform.api.extension.client.property.column.AggrColumnProperty; +import com.aliyun.fastmodel.transform.api.extension.client.property.index.IndexCommentProperty; +import com.aliyun.fastmodel.transform.api.extension.client.property.index.IndexTypeProperty; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.DistributeBucketsNum; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.DistributeHash; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.PartitionLiveNumberProperty; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.ReplicationNum; import com.google.common.collect.Maps; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.COLUMN_AGG_DESC; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.PARTITION_LIVE_NUMBER; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_DISTRIBUTED_BUCKETS; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_DISTRIBUTED_HASH; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_INDEX_COMMENT; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_INDEX_TYPE; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_REPLICATION_NUM; + /** * StarRocksPropertyConverter * @@ -23,50 +30,50 @@ */ public class StarRocksPropertyConverter extends BasePropertyConverter { - private Map> functionMap = Maps.newHashMap(); + private static Map> functionMap = Maps.newHashMap(); public StarRocksPropertyConverter() { init(); } private void init() { - functionMap.put(StarRocksProperty.TABLE_DISTRIBUTED_BUCKETS.getValue(), + functionMap.put(TABLE_DISTRIBUTED_BUCKETS.getValue(), (k) -> { DistributeBucketsNum distributeBucketsNum = new DistributeBucketsNum(); distributeBucketsNum.setValueString(k); return distributeBucketsNum; }); - functionMap.put(StarRocksProperty.TABLE_DISTRIBUTED_HASH.getValue(), (k) -> { + functionMap.put(TABLE_DISTRIBUTED_HASH.getValue(), (k) -> { DistributeHash distributeHash = new DistributeHash(); distributeHash.setValueString(k); return distributeHash; }); - functionMap.put(StarRocksProperty.TABLE_REPLICATION_NUM.getValue(), (k) -> { + functionMap.put(TABLE_REPLICATION_NUM.getValue(), (k) -> { ReplicationNum distributeHash = new ReplicationNum(); distributeHash.setValueString(k); return distributeHash; }); - functionMap.put(StarRocksProperty.PARTITION_LIVE_NUMBER.getValue(), (k) -> { + functionMap.put(PARTITION_LIVE_NUMBER.getValue(), (k) -> { PartitionLiveNumberProperty partitionLiveNumberProperty = new PartitionLiveNumberProperty(); partitionLiveNumberProperty.setValueString(k); return partitionLiveNumberProperty; }); - functionMap.put(StarRocksProperty.TABLE_INDEX_COMMENT.getValue(), (k) -> { + functionMap.put(TABLE_INDEX_COMMENT.getValue(), (k) -> { IndexCommentProperty indexCommentProperty = new IndexCommentProperty(); indexCommentProperty.setValueString(k); return indexCommentProperty; }); - functionMap.put(StarRocksProperty.TABLE_INDEX_TYPE.getValue(), (k) -> { + functionMap.put(TABLE_INDEX_TYPE.getValue(), (k) -> { IndexTypeProperty indexTypeProperty = new IndexTypeProperty(); indexTypeProperty.setValueString(k); return indexTypeProperty; }); - functionMap.put(StarRocksProperty.COLUMN_AGG_DESC.getValue(), (k) -> { + functionMap.put(COLUMN_AGG_DESC.getValue(), (k) -> { AggrColumnProperty aggrColumnProperty = new AggrColumnProperty(); aggrColumnProperty.setValueString(k); return aggrColumnProperty; diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/column/AggrColumnProperty.java b/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/column/AggrColumnProperty.java deleted file mode 100644 index bbc2d9a..0000000 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/column/AggrColumnProperty.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.aliyun.fastmodel.transform.starrocks.client.property.column; - -import java.util.Locale; - -import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; -import com.aliyun.fastmodel.transform.starrocks.format.StarRocksProperty; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.AggDesc; - -/** - * aggr column property - * - * @author panguanjing - * @date 2023/9/17 - */ -public class AggrColumnProperty extends BaseClientProperty { - - public AggrColumnProperty() { - this.setKey(StarRocksProperty.COLUMN_AGG_DESC.getValue()); - } - - @Override - public String valueString() { - return value.name(); - } - - @Override - public void setValueString(String value) { - this.value = AggDesc.valueOf(value.toUpperCase(Locale.ROOT)); - } -} diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/ListPartitionProperty.java b/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/ListPartitionProperty.java deleted file mode 100644 index ea7091d..0000000 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/client/property/table/ListPartitionProperty.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.aliyun.fastmodel.transform.starrocks.client.property.table; - -import com.alibaba.fastjson.JSON; -import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.ListClientPartition; -import com.aliyun.fastmodel.transform.starrocks.format.StarRocksProperty; -import org.apache.commons.lang3.StringUtils; - -/** - * @author 子梁 - * @date 2023/12/25 - */ -public class ListPartitionProperty extends BaseClientProperty { - - public ListPartitionProperty() { - this.setKey(StarRocksProperty.TABLE_LIST_PARTITION.getValue()); - } - - @Override - public String valueString() { - return JSON.toJSONString(value); - } - - @Override - public void setValueString(String value) { - if (StringUtils.isBlank(value)) { - return; - } - this.setValue(JSON.parseObject(value, ListClientPartition.class)); - } -} diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/format/StarRocksExpressionVisitor.java b/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/format/StarRocksExpressionVisitor.java index 162207c..6a521e6 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/format/StarRocksExpressionVisitor.java +++ b/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/format/StarRocksExpressionVisitor.java @@ -10,7 +10,6 @@ import com.aliyun.fastmodel.common.utils.StripUtils; import com.aliyun.fastmodel.core.tree.expr.Identifier; -import com.aliyun.fastmodel.core.tree.expr.literal.NullLiteral; import com.aliyun.fastmodel.transform.api.format.DefaultExpressionVisitor; import com.aliyun.fastmodel.transform.starrocks.context.StarRocksContext; import com.aliyun.fastmodel.transform.starrocks.parser.tree.datatype.StarRocksGenericDataType; @@ -54,11 +53,6 @@ public String visitIdentifier(Identifier node, Void context) { } } - @Override - public String visitNullLiteral(NullLiteral node, Void context) { - return "NULL"; - } - @Override public String formatStringLiteral(String s) { if (s == null) { diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/format/StarRocksOutVisitor.java b/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/format/StarRocksOutVisitor.java index d42e997..cdd7d26 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/format/StarRocksOutVisitor.java +++ b/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/format/StarRocksOutVisitor.java @@ -1,5 +1,10 @@ package com.aliyun.fastmodel.transform.starrocks.format; +import java.util.Iterator; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + import com.aliyun.fastmodel.core.formatter.FastModelVisitor; import com.aliyun.fastmodel.core.tree.Property; import com.aliyun.fastmodel.core.tree.datatype.BaseDataType; @@ -13,6 +18,7 @@ import com.aliyun.fastmodel.core.tree.statement.table.ColumnDefinition; import com.aliyun.fastmodel.core.tree.statement.table.CreateTable; import com.aliyun.fastmodel.core.tree.statement.table.DropCol; +import com.aliyun.fastmodel.core.tree.statement.table.PartitionedBy; import com.aliyun.fastmodel.core.tree.statement.table.RenameCol; import com.aliyun.fastmodel.core.tree.statement.table.RenameTable; import com.aliyun.fastmodel.core.tree.statement.table.SetTableProperties; @@ -22,36 +28,40 @@ import com.aliyun.fastmodel.core.tree.statement.table.constraint.UniqueConstraint; import com.aliyun.fastmodel.core.tree.statement.table.index.TableIndex; import com.aliyun.fastmodel.core.tree.util.PropertyUtil; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.AggregateKeyConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.DuplicateKeyConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.DistributeConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.NonKeyConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.OrderByConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.RollupConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.RollupItem; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.ExpressionPartitionBy; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.ListPartitionedBy; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.RangePartitionedBy; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.MultiItemListPartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.MultiRangePartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.PartitionDesc; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.SingleItemListPartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.SingleRangePartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.ArrayPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.LessThanPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.ListPartitionValue; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.PartitionValue; +import com.aliyun.fastmodel.transform.api.format.PropertyKey; import com.aliyun.fastmodel.transform.starrocks.context.StarRocksContext; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.AggregateKeyConstraint; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.DuplicateKeyConstraint; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.desc.DistributeConstraint; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.desc.NonKeyConstraint; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.desc.OrderByConstraint; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.desc.RollupConstraint; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.desc.RollupItem; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.ArrayPartitionKey; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.ExpressionPartitionBy; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.LessThanPartitionKey; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.ListPartitionValue; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.ListPartitionedBy; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.MultiItemListPartition; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.MultiRangePartition; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.PartitionDesc; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.PartitionValue; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.RangePartitionedBy; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.SingleItemListPartition; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.SingleRangePartition; import com.aliyun.fastmodel.transform.starrocks.parser.visitor.StarRocksAstVisitor; import com.google.common.base.Objects; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; -import java.util.Iterator; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.COLUMN_AGG_DESC; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.COLUMN_AUTO_INCREMENT; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.COLUMN_KEY; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_ENGINE; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_INDEX_COMMENT; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_INDEX_TYPE; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_PARTITION_RAW; /** * StarRocksVisitor @@ -97,7 +107,7 @@ public Boolean visitCreateTable(CreateTable node, Integer indent) { //format engine if (node.getProperties() != null) { Optional first = node.getProperties().stream().filter( - p -> StringUtils.equalsIgnoreCase(p.getName(), StarRocksProperty.TABLE_ENGINE.getValue())).findFirst(); + p -> StringUtils.equalsIgnoreCase(p.getName(), TABLE_ENGINE.getValue())).findFirst(); first.ifPresent(property -> builder.append("\nENGINE=").append(property.getValue())); } @@ -117,7 +127,7 @@ public Boolean visitCreateTable(CreateTable node, Integer indent) { builder.append("\n"); process(node.getPartitionedBy(), indent); } else { - String propertyValue = PropertyUtil.getPropertyValue(node.getProperties(), StarRocksProperty.TABLE_PARTITION_RAW.getValue()); + String propertyValue = PropertyUtil.getPropertyValue(node.getProperties(), TABLE_PARTITION_RAW.getValue()); if (StringUtils.isNotBlank(propertyValue)) { builder.append("\n"); builder.append(propertyValue); @@ -148,8 +158,8 @@ public Boolean visitCreateTable(CreateTable node, Integer indent) { protected String formatProperty(List properties) { List collect = properties.stream().filter( p -> { - StarRocksProperty byValue = StarRocksProperty.getByValue(p.getName()); - return byValue == null || byValue.isSupportPrint(); + PropertyKey propertyKey = StarRocksPropertyKey.getByValue(p.getName()); + return propertyKey == null || propertyKey.isSupportPrint(); } ).collect(Collectors.toList()); return super.formatProperty(collect); @@ -165,17 +175,17 @@ protected String formatColumnDefinition(ColumnDefinition column, Integer max) { } List columnProperties = column.getColumnProperties(); //charset - String charSet = PropertyUtil.getPropertyValue(columnProperties, StarRocksProperty.COLUMN_CHAR_SET.getValue()); + String charSet = PropertyUtil.getPropertyValue(columnProperties, StarRocksPropertyKey.COLUMN_CHAR_SET.getValue()); if (StringUtils.isNotBlank(charSet)) { sb.append(" ").append("CHARSET ").append(charSet); } //key - String key = PropertyUtil.getPropertyValue(columnProperties, StarRocksProperty.COLUMN_KEY.getValue()); + String key = PropertyUtil.getPropertyValue(columnProperties, COLUMN_KEY.getValue()); if (StringUtils.isNotBlank(key)) { sb.append(" ").append("KEY"); } //aggDesc - String propertyValue = PropertyUtil.getPropertyValue(columnProperties, StarRocksProperty.COLUMN_AGG_DESC.getValue()); + String propertyValue = PropertyUtil.getPropertyValue(columnProperties, COLUMN_AGG_DESC.getValue()); if (StringUtils.isNotBlank(propertyValue)) { sb.append(" ").append(propertyValue); } @@ -194,7 +204,7 @@ protected String formatColumnDefinition(ColumnDefinition column, Integer max) { } } //auto increment - String autoIncrement = PropertyUtil.getPropertyValue(columnProperties, StarRocksProperty.COLUMN_AUTO_INCREMENT.getValue()); + String autoIncrement = PropertyUtil.getPropertyValue(columnProperties, COLUMN_AUTO_INCREMENT.getValue()); if (StringUtils.equalsIgnoreCase(BooleanLiteral.TRUE, autoIncrement)) { sb.append(" ").append("AUTO_INCREMENT"); } @@ -383,19 +393,31 @@ public Boolean visitTableIndex(TableIndex tableIndex, Integer ident) { return true; } Optional first = properties.stream().filter(p -> { - StarRocksProperty tableIndexType = StarRocksProperty.TABLE_INDEX_TYPE; - return StringUtils.equalsIgnoreCase(p.getName(), tableIndexType.getValue()); + return StringUtils.equalsIgnoreCase(p.getName(), TABLE_INDEX_TYPE.getValue()); }).findFirst(); first.ifPresent(property -> builder.append(" USING ").append(property.getValue())); Optional comment = properties.stream().filter(p -> { - StarRocksProperty tableIndexType = StarRocksProperty.TABLE_INDEX_COMMENT; - return StringUtils.equalsIgnoreCase(p.getName(), tableIndexType.getValue()); + return StringUtils.equalsIgnoreCase(p.getName(), TABLE_INDEX_COMMENT.getValue()); }).findFirst(); comment.ifPresent(property -> builder.append(" COMMENT ").append(formatStringLiteral(property.getValue()))); return true; } + @Override + public Boolean visitPartitionedBy(PartitionedBy partitionedBy, Integer context) { + if (partitionedBy instanceof RangePartitionedBy) { + return visitRangePartitionedBy((RangePartitionedBy)partitionedBy, context); + } + if (partitionedBy instanceof ListPartitionedBy) { + return visitListPartitionedBy((ListPartitionedBy)partitionedBy, context); + } + if (partitionedBy instanceof ExpressionPartitionBy) { + return visitExpressionPartitionedBy((ExpressionPartitionBy)partitionedBy, context); + } + return super.visitPartitionedBy(partitionedBy, context); + } + @Override public Boolean visitRangePartitionedBy(RangePartitionedBy starRocksPartitionedBy, Integer indent) { builder.append("PARTITION BY RANGE ("); @@ -453,7 +475,7 @@ public Boolean visitExpressionPartitionedBy(ExpressionPartitionBy expressionPart builder.append("PARTITION BY "); List partitioned = expressionPartitionedBy.getColumnDefinitions(); String col = partitioned.stream().map( - x -> formatExpression(x.getColName()) + x -> formatExpression(x.getColName()) ).collect(Collectors.joining(",")); if (expressionPartitionedBy.getFunctionCall() == null) { // 列表达式 @@ -519,6 +541,14 @@ private String formatPartitionValue(PartitionValue partitionValue) { return formatExpression(partitionValue.getStringLiteral()); } + private String formatListPartitionValue(ListPartitionValue listPartitionValue) { + return listPartitionValue.getPartitionValueList().stream().map( + p -> { + return formatPartitionValue(p); + } + ).collect(Collectors.joining(",")); + } + @Override public Boolean visitMultiItemListPartition(MultiItemListPartition multiItemListPartition, Integer context) { builder.append("PARTITION "); @@ -556,7 +586,7 @@ public Boolean visitDistributeKeyConstraint(DistributeConstraint distributeKeyCo } if (CollectionUtils.isNotEmpty(distributeKeyConstraint.getColumns())) { List colNames = distributeKeyConstraint.getColumns(); - builder.append(" ("); + builder.append("("); builder.append(colNames.stream().map(this::formatExpression).collect(Collectors.joining(","))); builder.append(")"); } @@ -616,12 +646,12 @@ public Boolean visitArrayPartitionKey(ArrayPartitionKey arrayPartitionKey, Integ public Boolean visitMultiRangePartition(MultiRangePartition multiRangePartition, Integer context) { String s = indentString(context); builder.append(s).append("START"); - builder.append("(").append(formatExpression(multiRangePartition.getStart())); + builder.append("(").append(formatListPartitionValue(multiRangePartition.getStart())); builder.append(")"); builder.append(" "); builder.append("END"); builder.append("("); - builder.append(formatExpression(multiRangePartition.getEnd())); + builder.append(formatListPartitionValue(multiRangePartition.getEnd())); builder.append(")"); builder.append(" EVERY ("); if (multiRangePartition.getIntervalLiteral() != null) { @@ -632,4 +662,10 @@ public Boolean visitMultiRangePartition(MultiRangePartition multiRangePartition, builder.append(")"); return true; } + + @Override + public Boolean visitListPartitionValue(ListPartitionValue listPartitionValue, Integer context) { + builder.append(formatListPartitionValue(listPartitionValue)); + return true; + } } diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/format/StarRocksProperty.java b/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/format/StarRocksProperty.java index af71507..65070ba 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/format/StarRocksProperty.java +++ b/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/format/StarRocksProperty.java @@ -1,5 +1,6 @@ package com.aliyun.fastmodel.transform.starrocks.format; +import com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey; import com.aliyun.fastmodel.transform.api.format.PropertyKey; import org.apache.commons.lang3.StringUtils; @@ -11,84 +12,16 @@ * @date 2023/9/14 */ public enum StarRocksProperty implements PropertyKey { - /** - * engine - */ - TABLE_ENGINE("engine"), - - /** - * distribute hash - */ - TABLE_DISTRIBUTED_HASH("distributed_hash"), - - /** - * distribute buckets - */ - TABLE_DISTRIBUTED_BUCKETS("distributed_buckets"), - - /** - * index type - */ - TABLE_INDEX_TYPE("index_type"), - /** - * index comment - */ - TABLE_INDEX_COMMENT("index_comment"), /** * rollup */ TABLE_ROLLUP("rollup"), - /** - * range partition - */ - TABLE_RANGE_PARTITION("range_partition"), - - /** - * table range partition raw - */ - TABLE_PARTITION_RAW("range_partition_raw"), - - /** - * list partition - */ - TABLE_LIST_PARTITION("list_partition"), - - /** - * expression partition - */ - TABLE_EXPRESSION_PARTITION("expression_partition"), - /** * char set */ - COLUMN_CHAR_SET("char_set"), - - /** - * column key - */ - COLUMN_KEY("column_key"), - - /** - * 自增列信息 - */ - COLUMN_AUTO_INCREMENT("column_auto_increment"), - - /** - * column agg desc - */ - COLUMN_AGG_DESC("column_agg_desc"), - - /** - * REPLICATION_NUM - */ - TABLE_REPLICATION_NUM("replication_num", true), - - /** - * 保留最近多少数量的分区 - */ - PARTITION_LIVE_NUMBER("partition_live_number", true); + COLUMN_CHAR_SET("char_set"); private final String value; @@ -103,13 +36,18 @@ public enum StarRocksProperty implements PropertyKey { this.supportPrint = supportPrint; } - public static StarRocksProperty getByValue(String value) { + public static PropertyKey getByValue(String value) { StarRocksProperty[] starRocksProperties = StarRocksProperty.values(); for (StarRocksProperty starRocksProperty : starRocksProperties) { if (StringUtils.equalsIgnoreCase(starRocksProperty.getValue(), value)) { return starRocksProperty; } } + for (ExtensionPropertyKey extensionPropertyKey : ExtensionPropertyKey.values()) { + if (StringUtils.equalsIgnoreCase(extensionPropertyKey.getValue(), value)) { + return extensionPropertyKey; + } + } return null; } diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/format/StarRocksPropertyKey.java b/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/format/StarRocksPropertyKey.java new file mode 100644 index 0000000..3044989 --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/format/StarRocksPropertyKey.java @@ -0,0 +1,63 @@ +package com.aliyun.fastmodel.transform.starrocks.format; + +import com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey; +import com.aliyun.fastmodel.transform.api.format.PropertyKey; +import org.apache.commons.lang3.StringUtils; + +/** + * StarRocksProperty + * $$是代表系统属性,不会进行输出 + * + * @author panguanjing + * @date 2023/9/14 + */ +public enum StarRocksPropertyKey implements PropertyKey { + + /** + * rollup + */ + TABLE_ROLLUP("rollup"), + + /** + * char set + */ + COLUMN_CHAR_SET("char_set"); + + private final String value; + + private final boolean supportPrint; + + StarRocksPropertyKey(String value) { + this(value, false); + } + + StarRocksPropertyKey(String value, boolean supportPrint) { + this.value = value; + this.supportPrint = supportPrint; + } + + public static PropertyKey getByValue(String value) { + StarRocksPropertyKey[] starRocksProperties = StarRocksPropertyKey.values(); + for (StarRocksPropertyKey starRocksProperty : starRocksProperties) { + if (StringUtils.equalsIgnoreCase(starRocksProperty.getValue(), value)) { + return starRocksProperty; + } + } + for (ExtensionPropertyKey extensionPropertyKey : ExtensionPropertyKey.values()) { + if (StringUtils.equalsIgnoreCase(extensionPropertyKey.getValue(), value)) { + return extensionPropertyKey; + } + } + return null; + } + + @Override + public String getValue() { + return value; + } + + @Override + public boolean isSupportPrint() { + return supportPrint; + } +} diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/StarRocksLanguageParser.java b/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/StarRocksLanguageParser.java index ed0af9e..782c006 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/StarRocksLanguageParser.java +++ b/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/StarRocksLanguageParser.java @@ -2,9 +2,7 @@ import java.util.function.Function; -import com.aliyun.fastmodel.common.parser.ThrowingErrorListener; -import com.aliyun.fastmodel.common.parser.lexer.CaseChangingCharStream; -import com.aliyun.fastmodel.common.utils.StripUtils; +import com.aliyun.fastmodel.common.parser.ParserHelper; import com.aliyun.fastmodel.core.exception.ParseException; import com.aliyun.fastmodel.core.parser.LanguageParser; import com.aliyun.fastmodel.core.tree.Node; @@ -12,11 +10,7 @@ import com.aliyun.fastmodel.transform.api.context.ReverseContext; import com.aliyun.fastmodel.transform.starrocks.parser.visitor.StarRocksAstBuilder; import com.google.auto.service.AutoService; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CodePointCharStream; -import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.ParserRuleContext; -import org.antlr.v4.runtime.atn.PredictionMode; /** * StarRocksLanguageParser @@ -27,33 +21,21 @@ @AutoService(LanguageParser.class) public class StarRocksLanguageParser implements LanguageParser { - public static final ThrowingErrorListener LISTENER = new ThrowingErrorListener(); - @Override public Node parseNode(String text, ReverseContext context) throws ParseException { return getNode(text, context, StarRocksParser::sqlStatements); } private Node getNode(String text, ReverseContext context, Function functionalInterface) { - String code = StripUtils.appendSemicolon(text); - CodePointCharStream charStream = CharStreams.fromString(code); - CaseChangingCharStream caseChangingCharStream = new CaseChangingCharStream(charStream, true); - StarRocksLexer lexer = new StarRocksLexer(caseChangingCharStream); - lexer.removeErrorListeners(); - lexer.addErrorListener(LISTENER); - CommonTokenStream commonTokenStream = new CommonTokenStream(lexer); - StarRocksParser sparkParser = new StarRocksParser(commonTokenStream); - sparkParser.removeErrorListeners(); - sparkParser.addErrorListener(LISTENER); - ParserRuleContext tree; - try { - sparkParser.getInterpreter().setPredictionMode(PredictionMode.SLL); - tree = functionalInterface.apply(sparkParser); - } catch (Throwable e) { - commonTokenStream.seek(0); - sparkParser.getInterpreter().setPredictionMode(PredictionMode.LL); - tree = functionalInterface.apply(sparkParser); - } + ParserRuleContext tree = ParserHelper.getNode( + text, + charStream -> new StarRocksLexer(charStream), + tokenStream -> new StarRocksParser(tokenStream), + parser -> { + StarRocksParser starRocksParser = (StarRocksParser)parser; + return functionalInterface.apply(starRocksParser); + } + ); return tree.accept(new StarRocksAstBuilder(context)); } diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/datatype/StarRocksGenericDataType.java b/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/datatype/StarRocksGenericDataType.java index 44b9480..18fdf96 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/datatype/StarRocksGenericDataType.java +++ b/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/tree/datatype/StarRocksGenericDataType.java @@ -21,7 +21,7 @@ import lombok.Getter; /** - * HologresGenericDataType + * StarRocksGenericDataType * * @author panguanjing * @date 2022/6/9 diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/visitor/StarRocksAstBuilder.java b/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/visitor/StarRocksAstBuilder.java index 2de7a81..6f7d3ff 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/visitor/StarRocksAstBuilder.java +++ b/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/visitor/StarRocksAstBuilder.java @@ -1,5 +1,10 @@ package com.aliyun.fastmodel.transform.starrocks.parser.visitor; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + import com.aliyun.fastmodel.common.parser.ParserHelper; import com.aliyun.fastmodel.common.utils.StripUtils; import com.aliyun.fastmodel.core.exception.ParseException; @@ -39,7 +44,26 @@ import com.aliyun.fastmodel.core.tree.statement.table.index.TableIndex; import com.aliyun.fastmodel.core.tree.util.IdentifierUtil; import com.aliyun.fastmodel.transform.api.context.ReverseContext; -import com.aliyun.fastmodel.transform.starrocks.format.StarRocksProperty; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.AggregateKeyConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.DuplicateKeyConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.DistributeConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.OrderByConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.RollupConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.RollupItem; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.ExpressionPartitionBy; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.ListPartitionedBy; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.RangePartitionedBy; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.MultiItemListPartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.MultiRangePartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.PartitionDesc; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.SingleItemListPartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.SingleRangePartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.ArrayPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.LessThanPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.ListPartitionValue; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.PartitionKey; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.PartitionValue; +import com.aliyun.fastmodel.transform.starrocks.format.StarRocksPropertyKey; import com.aliyun.fastmodel.transform.starrocks.format.TimeFunctionType; import com.aliyun.fastmodel.transform.starrocks.parser.StarRocksBaseVisitor; import com.aliyun.fastmodel.transform.starrocks.parser.StarRocksParser; @@ -93,39 +117,21 @@ import com.aliyun.fastmodel.transform.starrocks.parser.StarRocksParser.TypeListContext; import com.aliyun.fastmodel.transform.starrocks.parser.StarRocksParser.TypeParameterContext; import com.aliyun.fastmodel.transform.starrocks.parser.StarRocksParser.UnquotedIdentifierContext; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.AggregateKeyConstraint; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.DuplicateKeyConstraint; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.desc.DistributeConstraint; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.desc.OrderByConstraint; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.desc.RollupConstraint; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.desc.RollupItem; import com.aliyun.fastmodel.transform.starrocks.parser.tree.datatype.StarRocksDataTypeName; import com.aliyun.fastmodel.transform.starrocks.parser.tree.datatype.StarRocksGenericDataType; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.ArrayPartitionKey; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.ExpressionPartitionBy; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.LessThanPartitionKey; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.ListPartitionValue; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.ListPartitionedBy; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.MultiItemListPartition; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.MultiRangePartition; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.PartitionDesc; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.PartitionKey; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.PartitionValue; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.RangePartitionedBy; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.SingleItemListPartition; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.SingleRangePartition; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import org.antlr.v4.runtime.Token; import org.apache.commons.lang3.BooleanUtils; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; -import java.util.stream.Stream; - import static com.aliyun.fastmodel.common.parser.ParserHelper.getLocation; import static com.aliyun.fastmodel.common.parser.ParserHelper.getOrigin; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.COLUMN_AGG_DESC; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.COLUMN_AUTO_INCREMENT; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.COLUMN_KEY; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_ENGINE; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_INDEX_COMMENT; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_INDEX_TYPE; /** * StarRocksAstBuilder @@ -186,7 +192,7 @@ public Node visitCreateTableStatement(CreateTableStatementContext ctx) { List constraints = Lists.newArrayList(); list.ifPresent(constraints::add); - //distrbiute key constraint + //distribute key constraint if (ctx.distributionDesc() != null) { DistributeConstraint distributeKeyConstraint = (DistributeConstraint)visit(ctx.distributionDesc()); constraints.add(distributeKeyConstraint); @@ -239,12 +245,12 @@ public Node visitIndexDesc(IndexDescContext ctx) { List properties = Lists.newArrayList(); IndexTypeContext indexTypeContext = ctx.indexType(); if (indexTypeContext != null) { - Property property = new Property(StarRocksProperty.TABLE_INDEX_TYPE.getValue(), "BITMAP"); + Property property = new Property(TABLE_INDEX_TYPE.getValue(), "BITMAP"); properties.add(property); } if (ctx.comment() != null) { Comment comment = (Comment)visit(ctx.comment()); - Property property = new Property(StarRocksProperty.TABLE_INDEX_COMMENT.getValue(), comment.getComment()); + Property property = new Property(TABLE_INDEX_COMMENT.getValue(), comment.getComment()); properties.add(property); } return new TableIndex( @@ -308,8 +314,8 @@ public Node visitSimpleFunctionCall(StarRocksParser.SimpleFunctionCallContext ct } ColumnDefinition columnDefinition = ColumnDefinition.builder() - .colName(columnName) - .build(); + .colName(columnName) + .build(); return new ExpressionPartitionBy(Lists.newArrayList(columnDefinition), functionCall, null); } @@ -319,8 +325,8 @@ public Node visitPartitionListIdentiifer(StarRocksParser.PartitionListIdentiifer IdentifierListContext identifierListContext = ctx.identifierList(); List list = ParserHelper.visit(this, identifierListContext.identifier(), Identifier.class); List columnDefinitions = list.stream().map(identifier -> ColumnDefinition.builder() - .colName(identifier) - .build()).collect(Collectors.toList()); + .colName(identifier) + .build()).collect(Collectors.toList()); return new ExpressionPartitionBy(columnDefinitions, null, null); } @@ -338,9 +344,9 @@ public Node visitSingleItemListPartitionDesc(SingleItemListPartitionDescContext @Override public Node visitStringList(StarRocksParser.StringListContext ctx) { List stringLiteralList = ctx.string().stream() - .map(value -> new StringLiteral(value.getText())).collect(Collectors.toList()); + .map(value -> new StringLiteral(value.getText())).collect(Collectors.toList()); return new ListStringLiteral(getLocation(ctx), - getOrigin(ctx), stringLiteralList); + getOrigin(ctx), stringLiteralList); } @Override @@ -376,7 +382,9 @@ public Node visitMultiRangePartition(MultiRangePartitionContext ctx) { } else { intervalLiteral = (IntervalLiteral)visit(ctx.interval()); } - return new MultiRangePartition(start, end, intervalLiteral, longLiteral); + ListPartitionValue fromValue = new ListPartitionValue(Lists.newArrayList(new PartitionValue(start))); + ListPartitionValue endValue = new ListPartitionValue(Lists.newArrayList(new PartitionValue(end))); + return new MultiRangePartition(fromValue, endValue, intervalLiteral, longLiteral); } @Override @@ -487,7 +495,7 @@ public Node visitFromRollup(FromRollupContext ctx) { @Override public Node visitEngineDesc(EngineDescContext ctx) { Identifier identifier = (Identifier)visit(ctx.identifier()); - return new Property(StarRocksProperty.TABLE_ENGINE.getValue(), identifier.getValue()); + return new Property(TABLE_ENGINE.getValue(), identifier.getValue()); } @Override @@ -545,22 +553,22 @@ public Node visitColumnDesc(ColumnDescContext ctx) { AggDescContext aggDescContext = ctx.aggDesc(); List properties = Lists.newArrayList(); if (aggDescContext != null) { - Property property = new Property(StarRocksProperty.COLUMN_AGG_DESC.getValue(), aggDescContext.getText()); + Property property = new Property(COLUMN_AGG_DESC.getValue(), aggDescContext.getText()); properties.add(property); } if (ctx.charsetName() != null) { Identifier value = (Identifier)visit(ctx.charsetName().identifier()); - Property property = new Property(StarRocksProperty.COLUMN_CHAR_SET.getValue(), value.getValue()); + Property property = new Property(StarRocksPropertyKey.COLUMN_CHAR_SET.getValue(), value.getValue()); properties.add(property); } if (ctx.KEY() != null) { - Property property = new Property(StarRocksProperty.COLUMN_KEY.getValue(), "KEY"); + Property property = new Property(COLUMN_KEY.getValue(), "KEY"); properties.add(property); } if (ctx.AUTO_INCREMENT() != null) { - Property property = new Property(StarRocksProperty.COLUMN_AUTO_INCREMENT.getValue(), BooleanUtils.toStringTrueFalse(true)); + Property property = new Property(COLUMN_AUTO_INCREMENT.getValue(), BooleanUtils.toStringTrueFalse(true)); properties.add(property); } return ColumnDefinition.builder() @@ -605,7 +613,13 @@ public Node visitProperty(PropertyContext ctx) { @Override public Node visitMapType(MapTypeContext ctx) { - return super.visitMapType(ctx); + Node keyVisit = visit(ctx.type(0)); + Node valueVisit = visit(ctx.type(1)); + return new StarRocksGenericDataType( + getLocation(ctx), + getOrigin(ctx), + ctx.getText(), + ImmutableList.of(new TypeParameter((BaseDataType)keyVisit), new TypeParameter((BaseDataType)valueVisit))); } @Override diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/visitor/StarRocksAstVisitor.java b/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/visitor/StarRocksAstVisitor.java index 2b37ca0..dd996b0 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/visitor/StarRocksAstVisitor.java +++ b/fastmodel-transform/fastmodel-transform-starrocks/src/main/java/com/aliyun/fastmodel/transform/starrocks/parser/visitor/StarRocksAstVisitor.java @@ -1,26 +1,7 @@ package com.aliyun.fastmodel.transform.starrocks.parser.visitor; -import com.aliyun.fastmodel.core.tree.IAstVisitor; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.AggregateKeyConstraint; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.DuplicateKeyConstraint; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.desc.DistributeConstraint; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.desc.OrderByConstraint; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.desc.RollupConstraint; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.desc.RollupItem; +import com.aliyun.fastmodel.transform.api.extension.visitor.ExtensionAstVisitor; import com.aliyun.fastmodel.transform.starrocks.parser.tree.datatype.StarRocksGenericDataType; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.ArrayPartitionKey; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.ExpressionPartitionBy; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.LessThanPartitionKey; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.ListPartitionValue; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.ListPartitionedBy; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.MultiItemListPartition; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.MultiRangePartition; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.PartitionDesc; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.PartitionKey; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.PartitionValue; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.RangePartitionedBy; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.SingleItemListPartition; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.SingleRangePartition; /** * star rocks visitor @@ -28,7 +9,7 @@ * @author panguanjing * @date 2023/9/12 */ -public interface StarRocksAstVisitor extends IAstVisitor { +public interface StarRocksAstVisitor extends ExtensionAstVisitor { /** * visit starRocks GenericDataType @@ -41,184 +22,4 @@ default R visitStarRocksGenericDataType(StarRocksGenericDataType starRocksGeneri return visitGenericDataType(starRocksGenericDataType, context); } - /** - * visit starRocks partitioned by - * - * @param starRocksPartitionedBy - * @param context - * @return - */ - default R visitRangePartitionedBy(RangePartitionedBy starRocksPartitionedBy, C context) { - return visitNode(starRocksPartitionedBy, context); - } - - /** - * visitAggregateConstraint - * - * @param aggregateConstraint - * @param context - * @return - */ - default R visitAggregateConstraint(AggregateKeyConstraint aggregateConstraint, C context) { - return visitNode(aggregateConstraint, context); - } - - /** - * visit duplicate constraint - * - * @param duplicateConstraint - * @param context - * @return - */ - default R visitDuplicateConstraint(DuplicateKeyConstraint duplicateConstraint, C context) { - return visitNode(duplicateConstraint, context); - } - - /** - * visitListPartitionedBy - * - * @param listPartitionedBy - * @param context - * @return - */ - default R visitListPartitionedBy(ListPartitionedBy listPartitionedBy, C context) { - return visitNode(listPartitionedBy, context); - } - - /** - * visitExpressionPartitionBy - * - * @param expressionPartitionedBy - * @param context - * @return - */ - default R visitExpressionPartitionedBy(ExpressionPartitionBy expressionPartitionedBy, C context) { - return visitNode(expressionPartitionedBy, context); - } - - /** - * single range partition - * - * @param singleRangePartition - * @param context - * @return - */ - default R visitSingleRangePartition(SingleRangePartition singleRangePartition, C context) { - return visitNode(singleRangePartition, context); - } - - /** - * multi range partition - * - * @param multiRangePartition - * @param context - * @return - */ - default R visitMultiRangePartition(MultiRangePartition multiRangePartition, C context) { - return visitNode(multiRangePartition, context); - } - - /** - * visit partition key - * - * @param partitionKey - * @param context - * @return - */ - default R visitPartitionKey(PartitionKey partitionKey, C context) { - return visitNode(partitionKey, context); - } - - /** - * visit array partition key - * - * @param arrayPartitionKey arrayPartitionKey - * @param context context - * @return - */ - default R visitArrayPartitionKey(ArrayPartitionKey arrayPartitionKey, C context) { - return visitPartitionKey(arrayPartitionKey, context); - } - - /** - * visit less than partition key - * - * @param lessThanPartitionKey - * @param context - * @return - */ - default R visitLessThanPartitionKey(LessThanPartitionKey lessThanPartitionKey, C context) { - return visitPartitionKey(lessThanPartitionKey, context); - } - - /** - * visit single item partition - * - * @param singleItemListPartition - * @param context - * @return - */ - default R visitSingleItemListPartition(SingleItemListPartition singleItemListPartition, C context) { - return visitPartitionDesc(singleItemListPartition, context); - } - - /** - * visit partition desc - * - * @param partitionDesc - * @param context - * @return - */ - default R visitPartitionDesc(PartitionDesc partitionDesc, C context) { - return visitNode(partitionDesc, context); - } - - /** - * visit multiItemListPartition - * - * @param multiItemListPartition - * @param context - * @return - */ - default R visitMultiItemListPartition(MultiItemListPartition multiItemListPartition, C context) { - return visitPartitionDesc(multiItemListPartition, context); - } - - /** - * visit list partition value - * - * @param listPartitionValue - * @param context - * @return - */ - default R visitListPartitionValue(ListPartitionValue listPartitionValue, C context) { - return visitNode(listPartitionValue, context); - } - - /** - * visit partition value - * - * @param partitionValue - * @param context - * @return - */ - default R visitPartitionValue(PartitionValue partitionValue, C context) { - return visitNode(partitionValue, context); - } - - default R visitOrderByConstraint(OrderByConstraint orderByConstraint, C context) { - return visitNode(orderByConstraint, context); - } - - default R visitDistributeKeyConstraint(DistributeConstraint distributeKeyConstraint, C context) { - return visitNode(distributeKeyConstraint, context); - } - - default R visitRollupItem(RollupItem rollupItem, C context) { - return visitNode(rollupItem, context); - } - - default R visitRollupConstraint(RollupConstraint rollupConstraint, C context) { - return visitNode(rollupConstraint, context); - } } diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/StarRocksTransformerTest.java b/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/StarRocksTransformerTest.java index 84b012c..49add2d 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/StarRocksTransformerTest.java +++ b/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/StarRocksTransformerTest.java @@ -1,5 +1,8 @@ package com.aliyun.fastmodel.transform.starrocks; +import java.util.List; +import java.util.Optional; + import com.aliyun.fastmodel.core.tree.BaseStatement; import com.aliyun.fastmodel.core.tree.Node; import com.aliyun.fastmodel.core.tree.QualifiedName; @@ -15,25 +18,22 @@ import com.aliyun.fastmodel.transform.api.context.TransformContext; import com.aliyun.fastmodel.transform.api.dialect.DialectMeta; import com.aliyun.fastmodel.transform.api.dialect.DialectNode; -import com.aliyun.fastmodel.transform.starrocks.client.constraint.StarRocksDistributeConstraint; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.ColumnExpressionPartitionProperty; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.TimeExpressionPartitionProperty; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.ListPartitionProperty; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.TablePartitionRaw; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.ArrayClientPartitionKey; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.ColumnExpressionClientPartition; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.TimeExpressionClientPartition; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.ListClientPartition; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.PartitionClientValue; -import com.aliyun.fastmodel.transform.starrocks.format.StarRocksProperty; +import com.aliyun.fastmodel.transform.api.extension.client.constraint.DistributeClientConstraint; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.ColumnExpressionPartitionProperty; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.ListPartitionProperty; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.TablePartitionRaw; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.TimeExpressionPartitionProperty; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.ArrayClientPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.ColumnExpressionClientPartition; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.ListClientPartition; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.PartitionClientValue; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.TimeExpressionClientPartition; import com.aliyun.fastmodel.transform.starrocks.parser.StarRocksLanguageParser; import org.apache.commons.lang3.StringUtils; import org.junit.Test; -import java.util.List; -import java.util.Optional; - import static com.aliyun.fastmodel.core.formatter.ExpressionFormatter.formatExpression; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_ENGINE; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -104,25 +104,25 @@ public void testTransformTable() { List properties = table.getProperties(); assertEquals(6, properties.size()); Optional first = properties.stream().filter( - c -> StringUtils.equalsIgnoreCase(c.getKey(), StarRocksProperty.TABLE_ENGINE.getValue())).findFirst(); - assertEquals(StarRocksProperty.TABLE_ENGINE.getValue(), first.get().getKey()); + c -> StringUtils.equalsIgnoreCase(c.getKey(), TABLE_ENGINE.getValue())).findFirst(); + assertEquals(TABLE_ENGINE.getValue(), first.get().getKey()); } @Test public void testTransformTableDistributedKey() { DialectNode dialectNode = new DialectNode( - "CREATE TABLE example_db.table_hash\n" + - "(\n" + - " k1 TINYINT AUTO_INCREMENT,\n" + - " k2 DECIMAL(10, 2) DEFAULT \"10.5\"\n" + - ")\n" + - "DISTRIBUTED BY RANDOM BUCKETS 56;" + "CREATE TABLE example_db.table_hash\n" + + "(\n" + + " k1 TINYINT AUTO_INCREMENT,\n" + + " k2 DECIMAL(10, 2) DEFAULT \"10.5\"\n" + + ")\n" + + "DISTRIBUTED BY RANDOM BUCKETS 56;" ); Node node = starRocksTransformer.reverse(dialectNode); Table table = starRocksTransformer.transformTable(node, TransformContext.builder().build()); assertNotNull(table.getConstraints()); assertEquals(1, table.getConstraints().size()); - StarRocksDistributeConstraint distributedKey = (StarRocksDistributeConstraint)table.getConstraints().get(0); + DistributeClientConstraint distributedKey = (DistributeClientConstraint)table.getConstraints().get(0); assertTrue(distributedKey.getRandom()); assertEquals(56, distributedKey.getBucket().intValue()); } @@ -161,9 +161,9 @@ public void testTransformTableArray() { List properties = table.getProperties(); assertEquals(6, properties.size()); Optional first = properties.stream().filter(c -> { - return StringUtils.equalsIgnoreCase(c.getKey(), StarRocksProperty.TABLE_ENGINE.getValue()); + return StringUtils.equalsIgnoreCase(c.getKey(), TABLE_ENGINE.getValue()); }).findFirst(); - assertEquals(StarRocksProperty.TABLE_ENGINE.getValue(), first.get().getKey()); + assertEquals(TABLE_ENGINE.getValue(), first.get().getKey()); } @Test @@ -267,7 +267,7 @@ public void testTransformUniqueKeyConstraint() { + " total_price BIGINT COMMENT \"price of an order\"\n" + ")\n" + "UNIQUE KEY (create_time,order_id)\n" - + "DISTRIBUTED BY HASH (order_id)\n" + + "DISTRIBUTED BY HASH(order_id)\n" + "PROPERTIES (\"replication_num\"=\"3\");", transform.getNode()); } @@ -314,7 +314,7 @@ public void testTransformAggregateConstraint() { + " property3 TINYINT NOT NULL\n" + ")\n" + "PRIMARY KEY (`user_id`)\n" - + "DISTRIBUTED BY HASH (`user_id`)\n" + + "DISTRIBUTED BY HASH(`user_id`)\n" + "ORDER BY (`address`,`last_active`)\n" + "PROPERTIES (\"replication_num\"=\"3\",\"enable_persistent_index\"=\"true\");", transform.getNode()); } @@ -345,7 +345,7 @@ public void testTransformDuplicateConstraint() { + " channel INT COMMENT \"\"\n" + ")\n" + "DUPLICATE KEY (event_time,event_type)\n" - + "DISTRIBUTED BY HASH (user_id)\n" + + "DISTRIBUTED BY HASH(user_id)\n" + "PROPERTIES (\"replication_num\"=\"3\");", transform.getNode()); } @@ -389,7 +389,7 @@ public void testTransformOrderby() { + " property3 TINYINT NOT NULL\n" + ")\n" + "PRIMARY KEY (`user_id`)\n" - + "DISTRIBUTED BY HASH (`user_id`)\n" + + "DISTRIBUTED BY HASH(`user_id`)\n" + "ORDER BY (`address`,`last_active`)\n" + "PROPERTIES (\"replication_num\"=\"3\",\"enable_persistent_index\"=\"true\");", transform.getNode()); } @@ -422,7 +422,7 @@ public void testTransformIndex() { + "ENGINE=olap\n" + "AGGREGATE KEY (k1,k2)\n" + "COMMENT \"my first starrocks table\"\n" - + "DISTRIBUTED BY HASH (k1) BUCKETS 10\n" + + "DISTRIBUTED BY HASH(k1) BUCKETS 10\n" + "PROPERTIES (\"storage_type\"=\"column\");", transform.getNode()); } @@ -455,7 +455,7 @@ public void testTransformRollup() { + "ENGINE=olap\n" + "AGGREGATE KEY (k1,k2)\n" + "COMMENT \"my first starrocks table\"\n" - + "DISTRIBUTED BY HASH (k1) BUCKETS 10\n" + + "DISTRIBUTED BY HASH(k1) BUCKETS 10\n" + "ROLLUP (a (a,b) DUPLICATE KEY (b,c) FROM c PROPERTIES (\"a\"=\"d\"))\n" + "PROPERTIES (\"storage_type\"=\"column\");", transform.getNode()); } @@ -487,15 +487,15 @@ public void testTransformTable_Npe() { public void testTransformListPartition() { { DialectNode dialectNode = new DialectNode( - "CREATE TABLE t_recharge_detail2 (\n" + - " id bigint,\n" + - " city varchar(20) not null,\n" + - " dt varchar(20) not null\n" + - ")\n" + - "PARTITION BY LIST (city) (\n" + - " PARTITION pCalifornia VALUES IN (\"Los Angeles\",\"San Francisco\",\"San Diego\"),\n" + - " PARTITION pTexas VALUES IN (\"Houston\",\"Dallas\",\"Austin\")\n" + - ");" + "CREATE TABLE t_recharge_detail2 (\n" + + " id bigint,\n" + + " city varchar(20) not null,\n" + + " dt varchar(20) not null\n" + + ")\n" + + "PARTITION BY LIST (city) (\n" + + " PARTITION pCalifornia VALUES IN (\"Los Angeles\",\"San Francisco\",\"San Diego\"),\n" + + " PARTITION pTexas VALUES IN (\"Houston\",\"Dallas\",\"Austin\")\n" + + ");" ); Node node = starRocksTransformer.reverse(dialectNode); Table table = starRocksTransformer.transformTable(node, TransformContext.builder().build()); @@ -511,36 +511,36 @@ public void testTransformListPartition() { ListClientPartition listClientPartition = property.getValue(); assertEquals("pCalifornia", listClientPartition.getName()); List> partitionValue = - ((ArrayClientPartitionKey) listClientPartition.getPartitionKey()).getPartitionValue(); + ((ArrayClientPartitionKey)listClientPartition.getPartitionKey()).getPartitionValue(); assertEquals("[[PartitionClientValue(maxValue=false, value=Los Angeles)], " + - "[PartitionClientValue(maxValue=false, value=San Francisco)], " + - "[PartitionClientValue(maxValue=false, value=San Diego)]]", partitionValue.toString()); + "[PartitionClientValue(maxValue=false, value=San Francisco)], " + + "[PartitionClientValue(maxValue=false, value=San Diego)]]", partitionValue.toString()); } { DialectNode dialectNode = new DialectNode( - "CREATE TABLE t_recharge_detail4 (\n" + - " id bigint,\n" + - " user_id bigint,\n" + - " recharge_money decimal(32,2), \n" + - " city varchar(20) not null,\n" + - " dt varchar(20) not null\n" + - ")\n" + - "PARTITION BY LIST (dt,city) (\n" + - " PARTITION p202204_California VALUES IN (\n" + - " (\"2022-04-01\", \"Los Angeles\"),\n" + - " (\"2022-04-01\", \"San Francisco\"),\n" + - " (\"2022-04-02\", \"Los Angeles\"),\n" + - " (\"2022-04-02\", \"San Francisco\")\n" + - " ),\n" + - " PARTITION p202204_Texas VALUES IN (\n" + - " (\"2022-04-01\", \"Houston\"),\n" + - " (\"2022-04-01\", \"Dallas\"),\n" + - " (\"2022-04-02\", \"Houston\"),\n" + - " (\"2022-04-02\", \"Dallas\")\n" + - " )\n" + - ");" + "CREATE TABLE t_recharge_detail4 (\n" + + " id bigint,\n" + + " user_id bigint,\n" + + " recharge_money decimal(32,2), \n" + + " city varchar(20) not null,\n" + + " dt varchar(20) not null\n" + + ")\n" + + "PARTITION BY LIST (dt,city) (\n" + + " PARTITION p202204_California VALUES IN (\n" + + " (\"2022-04-01\", \"Los Angeles\"),\n" + + " (\"2022-04-01\", \"San Francisco\"),\n" + + " (\"2022-04-02\", \"Los Angeles\"),\n" + + " (\"2022-04-02\", \"San Francisco\")\n" + + " ),\n" + + " PARTITION p202204_Texas VALUES IN (\n" + + " (\"2022-04-01\", \"Houston\"),\n" + + " (\"2022-04-01\", \"Dallas\"),\n" + + " (\"2022-04-02\", \"Houston\"),\n" + + " (\"2022-04-02\", \"Dallas\")\n" + + " )\n" + + ");" ); Node node = starRocksTransformer.reverse(dialectNode); Table table = starRocksTransformer.transformTable(node, TransformContext.builder().build()); @@ -554,16 +554,16 @@ public void testTransformListPartition() { ListClientPartition listClientPartition = property.getValue(); assertEquals("p202204_California", listClientPartition.getName()); List> partitionValue = - ((ArrayClientPartitionKey) listClientPartition.getPartitionKey()).getPartitionValue(); + ((ArrayClientPartitionKey)listClientPartition.getPartitionKey()).getPartitionValue(); assertEquals("[[PartitionClientValue(maxValue=false, value=2022-04-01), " + - "PartitionClientValue(maxValue=false, value=Los Angeles)], " + - "[PartitionClientValue(maxValue=false, value=2022-04-01), " + - "PartitionClientValue(maxValue=false, value=San Francisco)], " + - "[PartitionClientValue(maxValue=false, value=2022-04-02), " + - "PartitionClientValue(maxValue=false, value=Los Angeles)], " + - "[PartitionClientValue(maxValue=false, value=2022-04-02), " + - "PartitionClientValue(maxValue=false, value=San Francisco)]]", partitionValue.toString()); + "PartitionClientValue(maxValue=false, value=Los Angeles)], " + + "[PartitionClientValue(maxValue=false, value=2022-04-01), " + + "PartitionClientValue(maxValue=false, value=San Francisco)], " + + "[PartitionClientValue(maxValue=false, value=2022-04-02), " + + "PartitionClientValue(maxValue=false, value=Los Angeles)], " + + "[PartitionClientValue(maxValue=false, value=2022-04-02), " + + "PartitionClientValue(maxValue=false, value=San Francisco)]]", partitionValue.toString()); } } @@ -571,90 +571,94 @@ public void testTransformListPartition() { public void testReverseListPartition() { { DialectNode dialectNode = new DialectNode( - "CREATE TABLE t_recharge_detail2 (\n" + - " id bigint,\n" + - " city varchar(20) not null,\n" + - " dt varchar(20) not null\n" + - ")\n" + - "PARTITION BY LIST (city) (\n" + - " PARTITION pCalifornia VALUES IN (\"Los Angeles\",\"San Francisco\",\"San Diego\"),\n" + - " PARTITION pTexas VALUES IN (\"Houston\",\"Dallas\",\"Austin\")\n" + - ");" + "CREATE TABLE t_recharge_detail2 (\n" + + " id bigint,\n" + + " city varchar(20) not null,\n" + + " dt varchar(20) not null\n" + + ")\n" + + "PARTITION BY LIST (city) (\n" + + " PARTITION pCalifornia VALUES IN (\"Los Angeles\",\"San Francisco\",\"San Diego\"),\n" + + " PARTITION pTexas VALUES IN (\"Houston\",\"Dallas\",\"Austin\")\n" + + ");" ); Node node = starRocksTransformer.reverse(dialectNode); Table table = starRocksTransformer.transformTable(node, TransformContext.builder().build()); DdlGeneratorModelRequest request = DdlGeneratorModelRequest.builder() - .after(table) - .config(TableConfig.builder() - .dialectMeta(DialectMeta.DEFAULT_STARROCKS) - .build()) - .build(); + .after(table) + .config(TableConfig.builder() + .dialectMeta(DialectMeta.DEFAULT_STARROCKS) + .build()) + .build(); CodeGenerator codeGenerator = new DefaultCodeGenerator(); DdlGeneratorResult generate = codeGenerator.generate(request); List dialectNodes = generate.getDialectNodes(); assertEquals("CREATE TABLE t_recharge_detail2\n" + - "(\n" + - " id BIGINT NULL,\n" + - " city VARCHAR(20) NOT NULL,\n" + - " dt VARCHAR(20) NOT NULL\n" + - ")\n" + - "PARTITION BY LIST (city)\n" + - "(\n" + - "PARTITION pCalifornia VALUES IN (\"Los Angeles\",\"San Francisco\",\"San Diego\"),\n" + - "PARTITION pTexas VALUES IN (\"Houston\",\"Dallas\",\"Austin\")\n" + - ");", dialectNodes.get(0).getNode()); + "(\n" + + " id BIGINT NULL,\n" + + " city VARCHAR(20) NOT NULL,\n" + + " dt VARCHAR(20) NOT NULL\n" + + ")\n" + + "PARTITION BY LIST (city)\n" + + "(\n" + + "PARTITION pCalifornia VALUES IN (\"Los Angeles\",\"San Francisco\",\"San Diego\"),\n" + + "PARTITION pTexas VALUES IN (\"Houston\",\"Dallas\",\"Austin\")\n" + + ");", dialectNodes.get(0).getNode()); } { DialectNode dialectNode = new DialectNode( - "CREATE TABLE t_recharge_detail4 (\n" + - " id bigint,\n" + - " user_id bigint,\n" + - " recharge_money decimal(32,2), \n" + - " city varchar(20) not null,\n" + - " dt varchar(20) not null\n" + - ")\n" + - "PARTITION BY LIST (dt,city) (\n" + - " PARTITION p202204_California VALUES IN (\n" + - " (\"2022-04-01\", \"Los Angeles\"),\n" + - " (\"2022-04-01\", \"San Francisco\"),\n" + - " (\"2022-04-02\", \"Los Angeles\"),\n" + - " (\"2022-04-02\", \"San Francisco\")\n" + - " ),\n" + - " PARTITION p202204_Texas VALUES IN (\n" + - " (\"2022-04-01\", \"Houston\"),\n" + - " (\"2022-04-01\", \"Dallas\"),\n" + - " (\"2022-04-02\", \"Houston\"),\n" + - " (\"2022-04-02\", \"Dallas\")\n" + - " )\n" + - ");" + "CREATE TABLE t_recharge_detail4 (\n" + + " id bigint,\n" + + " user_id bigint,\n" + + " recharge_money decimal(32,2), \n" + + " city varchar(20) not null,\n" + + " dt varchar(20) not null\n" + + ")\n" + + "PARTITION BY LIST (dt,city) (\n" + + " PARTITION p202204_California VALUES IN (\n" + + " (\"2022-04-01\", \"Los Angeles\"),\n" + + " (\"2022-04-01\", \"San Francisco\"),\n" + + " (\"2022-04-02\", \"Los Angeles\"),\n" + + " (\"2022-04-02\", \"San Francisco\")\n" + + " ),\n" + + " PARTITION p202204_Texas VALUES IN (\n" + + " (\"2022-04-01\", \"Houston\"),\n" + + " (\"2022-04-01\", \"Dallas\"),\n" + + " (\"2022-04-02\", \"Houston\"),\n" + + " (\"2022-04-02\", \"Dallas\")\n" + + " )\n" + + ");" ); Node node = starRocksTransformer.reverse(dialectNode); Table table = starRocksTransformer.transformTable(node, TransformContext.builder().build()); DdlGeneratorModelRequest request = DdlGeneratorModelRequest.builder() - .after(table) - .config(TableConfig.builder() - .dialectMeta(DialectMeta.DEFAULT_STARROCKS) - .build()) - .build(); + .after(table) + .config(TableConfig.builder() + .dialectMeta(DialectMeta.DEFAULT_STARROCKS) + .build()) + .build(); CodeGenerator codeGenerator = new DefaultCodeGenerator(); DdlGeneratorResult generate = codeGenerator.generate(request); List dialectNodes = generate.getDialectNodes(); assertEquals("CREATE TABLE t_recharge_detail4\n" + - "(\n" + - " id BIGINT NULL,\n" + - " user_id BIGINT NULL,\n" + - " recharge_money DECIMAL(32,2) NULL,\n" + - " city VARCHAR(20) NOT NULL,\n" + - " dt VARCHAR(20) NOT NULL\n" + - ")\n" + - "PARTITION BY LIST (dt,city)\n" + - "(\n" + - "PARTITION p202204_California VALUES IN ((\"2022-04-01\",\"Los Angeles\"),(\"2022-04-01\",\"San Francisco\"),(\"2022-04-02\",\"Los Angeles\"),(\"2022-04-02\",\"San Francisco\")),\n" + - "PARTITION p202204_Texas VALUES IN ((\"2022-04-01\",\"Houston\"),(\"2022-04-01\",\"Dallas\"),(\"2022-04-02\",\"Houston\"),(\"2022-04-02\",\"Dallas\"))\n" + - ");", dialectNodes.get(0).getNode()); + "(\n" + + " id BIGINT NULL,\n" + + " user_id BIGINT NULL,\n" + + " recharge_money DECIMAL(32,2) NULL,\n" + + " city VARCHAR(20) NOT NULL,\n" + + " dt VARCHAR(20) NOT NULL\n" + + ")\n" + + "PARTITION BY LIST (dt,city)\n" + + "(\n" + + "PARTITION p202204_California VALUES IN ((\"2022-04-01\",\"Los Angeles\"),(\"2022-04-01\",\"San Francisco\"),(\"2022-04-02\",\"Los " + + "Angeles\"),(\"2022-04-02\",\"San Francisco\")),\n" + + + "PARTITION p202204_Texas VALUES IN ((\"2022-04-01\",\"Houston\"),(\"2022-04-01\",\"Dallas\"),(\"2022-04-02\",\"Houston\")," + + "(\"2022-04-02\",\"Dallas\"))\n" + + + ");", dialectNodes.get(0).getNode()); } } @@ -662,14 +666,14 @@ public void testReverseListPartition() { public void testTransformExpressionPartition() { { DialectNode dialectNode = new DialectNode( - "CREATE TABLE site_access1 (\n" + - " event_day DATETIME NOT NULL,\n" + - " site_id INT DEFAULT '10',\n" + - " city_code VARCHAR(100),\n" + - " user_name VARCHAR(32) DEFAULT '',\n" + - " pv BIGINT DEFAULT '0'\n" + - ")\n" + - "PARTITION BY date_trunc('day', event_day);" + "CREATE TABLE site_access1 (\n" + + " event_day DATETIME NOT NULL,\n" + + " site_id INT DEFAULT '10',\n" + + " city_code VARCHAR(100),\n" + + " user_name VARCHAR(32) DEFAULT '',\n" + + " pv BIGINT DEFAULT '0'\n" + + ")\n" + + "PARTITION BY date_trunc('day', event_day);" ); Node node = starRocksTransformer.reverse(dialectNode); Table table = starRocksTransformer.transformTable(node, TransformContext.builder().build()); @@ -689,14 +693,14 @@ public void testTransformExpressionPartition() { { DialectNode dialectNode = new DialectNode( - "CREATE TABLE site_access3 (\n" + - " event_day DATETIME NOT NULL,\n" + - " site_id INT DEFAULT '10',\n" + - " city_code VARCHAR(100),\n" + - " user_name VARCHAR(32) DEFAULT '',\n" + - " pv BIGINT DEFAULT '0'\n" + - ")\n" + - "PARTITION BY time_slice(event_day, INTERVAL 7 day);" + "CREATE TABLE site_access3 (\n" + + " event_day DATETIME NOT NULL,\n" + + " site_id INT DEFAULT '10',\n" + + " city_code VARCHAR(100),\n" + + " user_name VARCHAR(32) DEFAULT '',\n" + + " pv BIGINT DEFAULT '0'\n" + + ")\n" + + "PARTITION BY time_slice(event_day, INTERVAL 7 day);" ); Node node = starRocksTransformer.reverse(dialectNode); Table table = starRocksTransformer.transformTable(node, TransformContext.builder().build()); @@ -716,14 +720,14 @@ public void testTransformExpressionPartition() { { DialectNode dialectNode = new DialectNode( - "CREATE TABLE t_recharge_detail1 (\n" + - " id bigint,\n" + - " user_id bigint,\n" + - " recharge_money decimal(32,2), \n" + - " city varchar(20) not null,\n" + - " dt varchar(20) not null\n" + - ")\n" + - "PARTITION BY (dt,city);" + "CREATE TABLE t_recharge_detail1 (\n" + + " id bigint,\n" + + " user_id bigint,\n" + + " recharge_money decimal(32,2), \n" + + " city varchar(20) not null,\n" + + " dt varchar(20) not null\n" + + ")\n" + + "PARTITION BY (dt,city);" ); Node node = starRocksTransformer.reverse(dialectNode); Table table = starRocksTransformer.transformTable(node, TransformContext.builder().build()); @@ -745,104 +749,104 @@ public void testTransformExpressionPartition() { public void testReverseExpressionPartition() { { DialectNode dialectNode = new DialectNode( - "CREATE TABLE site_access1 (\n" + - " event_day DATETIME NOT NULL,\n" + - " site_id INT DEFAULT '10',\n" + - " city_code VARCHAR(100),\n" + - " user_name VARCHAR(32) DEFAULT '',\n" + - " pv BIGINT DEFAULT '0'\n" + - ")\n" + - "PARTITION BY date_trunc('day', event_day);" + "CREATE TABLE site_access1 (\n" + + " event_day DATETIME NOT NULL,\n" + + " site_id INT DEFAULT '10',\n" + + " city_code VARCHAR(100),\n" + + " user_name VARCHAR(32) DEFAULT '',\n" + + " pv BIGINT DEFAULT '0'\n" + + ")\n" + + "PARTITION BY date_trunc('day', event_day);" ); Node node = starRocksTransformer.reverse(dialectNode); Table table = starRocksTransformer.transformTable(node, TransformContext.builder().build()); DdlGeneratorModelRequest request = DdlGeneratorModelRequest.builder() - .after(table) - .config(TableConfig.builder() - .dialectMeta(DialectMeta.DEFAULT_STARROCKS) - .build()) - .build(); + .after(table) + .config(TableConfig.builder() + .dialectMeta(DialectMeta.DEFAULT_STARROCKS) + .build()) + .build(); CodeGenerator codeGenerator = new DefaultCodeGenerator(); DdlGeneratorResult generate = codeGenerator.generate(request); List dialectNodes = generate.getDialectNodes(); assertEquals("CREATE TABLE site_access1\n" + - "(\n" + - " event_day DATETIME NOT NULL,\n" + - " site_id INT NULL DEFAULT \"10\",\n" + - " city_code VARCHAR(100) NULL,\n" + - " user_name VARCHAR(32) NULL DEFAULT \"\",\n" + - " pv BIGINT NULL DEFAULT \"0\"\n" + - ")\n" + - "PARTITION BY date_trunc('day', event_day);", dialectNodes.get(0).getNode()); + "(\n" + + " event_day DATETIME NOT NULL,\n" + + " site_id INT NULL DEFAULT \"10\",\n" + + " city_code VARCHAR(100) NULL,\n" + + " user_name VARCHAR(32) NULL DEFAULT \"\",\n" + + " pv BIGINT NULL DEFAULT \"0\"\n" + + ")\n" + + "PARTITION BY date_trunc('day', event_day);", dialectNodes.get(0).getNode()); } { DialectNode dialectNode = new DialectNode( - "CREATE TABLE site_access3 (\n" + - " event_day DATETIME NOT NULL,\n" + - " site_id INT DEFAULT '10',\n" + - " city_code VARCHAR(100),\n" + - " user_name VARCHAR(32) DEFAULT '',\n" + - " pv BIGINT DEFAULT '0'\n" + - ")\n" + - "PARTITION BY time_slice(event_day, INTERVAL 7 day);" + "CREATE TABLE site_access3 (\n" + + " event_day DATETIME NOT NULL,\n" + + " site_id INT DEFAULT '10',\n" + + " city_code VARCHAR(100),\n" + + " user_name VARCHAR(32) DEFAULT '',\n" + + " pv BIGINT DEFAULT '0'\n" + + ")\n" + + "PARTITION BY time_slice(event_day, INTERVAL 7 day);" ); Node node = starRocksTransformer.reverse(dialectNode); Table table = starRocksTransformer.transformTable(node, TransformContext.builder().build()); DdlGeneratorModelRequest request = DdlGeneratorModelRequest.builder() - .after(table) - .config(TableConfig.builder() - .dialectMeta(DialectMeta.DEFAULT_STARROCKS) - .build()) - .build(); + .after(table) + .config(TableConfig.builder() + .dialectMeta(DialectMeta.DEFAULT_STARROCKS) + .build()) + .build(); CodeGenerator codeGenerator = new DefaultCodeGenerator(); DdlGeneratorResult generate = codeGenerator.generate(request); List dialectNodes = generate.getDialectNodes(); assertEquals("CREATE TABLE site_access3\n" + - "(\n" + - " event_day DATETIME NOT NULL,\n" + - " site_id INT NULL DEFAULT \"10\",\n" + - " city_code VARCHAR(100) NULL,\n" + - " user_name VARCHAR(32) NULL DEFAULT \"\",\n" + - " pv BIGINT NULL DEFAULT \"0\"\n" + - ")\n" + - "PARTITION BY time_slice(event_day, INTERVAL 7 DAY);", dialectNodes.get(0).getNode()); + "(\n" + + " event_day DATETIME NOT NULL,\n" + + " site_id INT NULL DEFAULT \"10\",\n" + + " city_code VARCHAR(100) NULL,\n" + + " user_name VARCHAR(32) NULL DEFAULT \"\",\n" + + " pv BIGINT NULL DEFAULT \"0\"\n" + + ")\n" + + "PARTITION BY time_slice(event_day, INTERVAL 7 DAY);", dialectNodes.get(0).getNode()); } { DialectNode dialectNode = new DialectNode( - "CREATE TABLE t_recharge_detail1 (\n" + - " id bigint,\n" + - " user_id bigint,\n" + - " recharge_money decimal(32,2), \n" + - " city varchar(20) not null,\n" + - " dt varchar(20) not null\n" + - ")\n" + - "PARTITION BY (dt,city);" + "CREATE TABLE t_recharge_detail1 (\n" + + " id bigint,\n" + + " user_id bigint,\n" + + " recharge_money decimal(32,2), \n" + + " city varchar(20) not null,\n" + + " dt varchar(20) not null\n" + + ")\n" + + "PARTITION BY (dt,city);" ); Node node = starRocksTransformer.reverse(dialectNode); Table table = starRocksTransformer.transformTable(node, TransformContext.builder().build()); DdlGeneratorModelRequest request = DdlGeneratorModelRequest.builder() - .after(table) - .config(TableConfig.builder() - .dialectMeta(DialectMeta.DEFAULT_STARROCKS) - .build()) - .build(); + .after(table) + .config(TableConfig.builder() + .dialectMeta(DialectMeta.DEFAULT_STARROCKS) + .build()) + .build(); CodeGenerator codeGenerator = new DefaultCodeGenerator(); DdlGeneratorResult generate = codeGenerator.generate(request); List dialectNodes = generate.getDialectNodes(); assertEquals("CREATE TABLE t_recharge_detail1\n" + - "(\n" + - " id BIGINT NULL,\n" + - " user_id BIGINT NULL,\n" + - " recharge_money DECIMAL(32,2) NULL,\n" + - " city VARCHAR(20) NOT NULL,\n" + - " dt VARCHAR(20) NOT NULL\n" + - ")\n" + - "PARTITION BY (dt,city);", dialectNodes.get(0).getNode()); + "(\n" + + " id BIGINT NULL,\n" + + " user_id BIGINT NULL,\n" + + " recharge_money DECIMAL(32,2) NULL,\n" + + " city VARCHAR(20) NOT NULL,\n" + + " dt VARCHAR(20) NOT NULL\n" + + ")\n" + + "PARTITION BY (dt,city);", dialectNodes.get(0).getNode()); } } diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/client/constraint/ClientConstraintTypeTest.java b/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/client/constraint/ClientConstraintTypeTest.java new file mode 100644 index 0000000..f5cf33e --- /dev/null +++ b/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/client/constraint/ClientConstraintTypeTest.java @@ -0,0 +1,24 @@ +package com.aliyun.fastmodel.transform.starrocks.client.constraint; + +import com.aliyun.fastmodel.transform.api.extension.client.constraint.ClientConstraintType; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * Desc: + * + * @author panguanjing + * @date 2023/12/13 + */ +public class ClientConstraintTypeTest { + + @Test + public void testGetByValue() { + ClientConstraintType primaryKey = ClientConstraintType.getByValue("primary"); + assertEquals(primaryKey, ClientConstraintType.PRIMARY_KEY); + + ClientConstraintType unique = ClientConstraintType.getByValue("unique"); + assertEquals(unique, ClientConstraintType.UNIQUE_KEY); + } +} \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/client/constraint/StarRocksConstraintTypeTest.java b/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/client/constraint/StarRocksConstraintTypeTest.java deleted file mode 100644 index 26e6a11..0000000 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/client/constraint/StarRocksConstraintTypeTest.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.aliyun.fastmodel.transform.starrocks.client.constraint; - -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - -/** - * Desc: - * - * @author panguanjing - * @date 2023/12/13 - */ -public class StarRocksConstraintTypeTest { - - @Test - public void testGetByValue() { - StarRocksConstraintType primaryKey = StarRocksConstraintType.getByValue("primary"); - assertEquals(primaryKey, StarRocksConstraintType.PRIMARY_KEY); - - StarRocksConstraintType unique = StarRocksConstraintType.getByValue("unique"); - assertEquals(unique, StarRocksConstraintType.UNIQUE_KEY); - } -} \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/client/converter/StarRocksClientConverterTest.java b/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/client/converter/StarRocksClientConverterTest.java index 20381cf..8c5d68d 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/client/converter/StarRocksClientConverterTest.java +++ b/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/client/converter/StarRocksClientConverterTest.java @@ -17,37 +17,37 @@ import com.aliyun.fastmodel.core.tree.statement.table.CreateTable; import com.aliyun.fastmodel.transform.api.client.PropertyConverter; import com.aliyun.fastmodel.transform.api.client.dto.constraint.Constraint; -import com.aliyun.fastmodel.transform.api.client.dto.constraint.OutlineConstraintType; +import com.aliyun.fastmodel.transform.api.client.dto.index.Index; import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; import com.aliyun.fastmodel.transform.api.client.dto.table.Column; import com.aliyun.fastmodel.transform.api.client.dto.table.Table; import com.aliyun.fastmodel.transform.api.client.dto.table.TableConfig; import com.aliyun.fastmodel.transform.api.dialect.DialectMeta; import com.aliyun.fastmodel.transform.api.dialect.DialectNode; +import com.aliyun.fastmodel.transform.api.extension.client.property.column.AggrColumnProperty; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.SingleRangePartitionProperty; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.ArrayClientPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.BaseClientPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.LessThanClientPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.MultiRangeClientPartition; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.PartitionClientValue; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.SingleRangeClientPartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.RangePartitionedBy; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.MultiRangePartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.PartitionDesc; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.SingleRangePartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.ArrayPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.LessThanPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.ListPartitionValue; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.PartitionValue; import com.aliyun.fastmodel.transform.starrocks.StarRocksTransformer; -import com.aliyun.fastmodel.transform.starrocks.client.property.column.AggrColumnProperty; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.SingleRangePartitionProperty; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.ArrayClientPartitionKey; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.BaseClientPartitionKey; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.LessThanClientPartitionKey; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.MultiRangeClientPartition; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.PartitionClientValue; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.SingleRangeClientPartition; import com.aliyun.fastmodel.transform.starrocks.context.StarRocksContext; -import com.aliyun.fastmodel.transform.starrocks.format.StarRocksProperty; import com.aliyun.fastmodel.transform.starrocks.parser.StarRocksLanguageParser; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.ArrayPartitionKey; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.LessThanPartitionKey; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.ListPartitionValue; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.MultiRangePartition; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.PartitionDesc; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.PartitionValue; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.RangePartitionedBy; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.SingleRangePartition; import com.google.common.collect.Lists; import org.apache.commons.lang3.StringUtils; import org.junit.Test; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_RANGE_PARTITION; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -93,7 +93,7 @@ public void testToBaseClientProperty() { List baseClientProperties = starRocksClientConverter.toBaseClientProperty(table); assertEquals(1, baseClientProperties.size()); BaseClientProperty baseClientProperty = baseClientProperties.get(0); - assertEquals(StarRocksProperty.TABLE_RANGE_PARTITION.getValue(), baseClientProperty.getKey()); + assertEquals(TABLE_RANGE_PARTITION.getValue(), baseClientProperty.getKey()); SingleRangePartitionProperty singleRangePartitionProperty = (SingleRangePartitionProperty)baseClientProperty; SingleRangeClientPartition value1 = singleRangePartitionProperty.getValue(); @@ -128,7 +128,7 @@ public void testToBaseClientPropertyLessThan() { List baseClientProperties = starRocksClientConverter.toBaseClientProperty(table); assertEquals(1, baseClientProperties.size()); BaseClientProperty baseClientProperty = baseClientProperties.get(0); - assertEquals(StarRocksProperty.TABLE_RANGE_PARTITION.getValue(), baseClientProperty.getKey()); + assertEquals(TABLE_RANGE_PARTITION.getValue(), baseClientProperty.getKey()); SingleRangeClientPartition value1 = (SingleRangeClientPartition)baseClientProperty.getValue(); assertEquals("abc", value1.getName()); assertFalse(value1.isIfNotExists()); @@ -159,7 +159,7 @@ public void testToBaseClientPropertyMultiRange() { List baseClientProperties = starRocksClientConverter.toBaseClientProperty(table); assertEquals(1, baseClientProperties.size()); BaseClientProperty baseClientProperty = baseClientProperties.get(0); - assertEquals(StarRocksProperty.TABLE_RANGE_PARTITION.getValue(), baseClientProperty.getKey()); + assertEquals(TABLE_RANGE_PARTITION.getValue(), baseClientProperty.getKey()); MultiRangeClientPartition value1 = (MultiRangeClientPartition)baseClientProperty.getValue(); String start = value1.getStart(); assertEquals("2021-01-01", start); @@ -189,7 +189,7 @@ public void testToBaseClientPropertyMultiRangeInterval() { List baseClientProperties = starRocksClientConverter.toBaseClientProperty(table); assertEquals(1, baseClientProperties.size()); BaseClientProperty baseClientProperty = baseClientProperties.get(0); - assertEquals(StarRocksProperty.TABLE_RANGE_PARTITION.getValue(), baseClientProperty.getKey()); + assertEquals(TABLE_RANGE_PARTITION.getValue(), baseClientProperty.getKey()); MultiRangeClientPartition value1 = (MultiRangeClientPartition)baseClientProperty.getValue(); String start = value1.getStart(); assertEquals("2021-01-01", start); @@ -198,14 +198,6 @@ public void testToBaseClientPropertyMultiRangeInterval() { assertTrue(value1.getInterval() == Long.parseLong("10")); } - @Test - public void getDataType() { - Column column = Column.builder() - .dataType("int") - .build(); - starRocksClientConverter.getDataType(column); - } - @Test public void testConvertIndexToTable() { StarRocksLanguageParser starRocksLanguageParser = new StarRocksLanguageParser(); @@ -224,13 +216,9 @@ public void testConvertIndexToTable() { + "PROPERTIES (\"storage_type\"=\"column\");"); Table table = starRocksClientConverter.convertToTable(node1, StarRocksContext.builder().build()); List constraints = table.getConstraints(); - assertEquals(3, constraints.size()); - Constraint constraint = constraints.stream().filter(c -> { - return StringUtils.equalsIgnoreCase(c.getType().getCode(), OutlineConstraintType.INDEX.getCode()); - }).findFirst().get(); - assertEquals("k1_idx", constraint.getName()); - List properties = constraint.getProperties(); - assertEquals(2, properties.size()); + assertEquals(2, constraints.size()); + List indices = table.getIndices(); + assertEquals("k1_idx", indices.get(0).getName()); } @Test @@ -306,6 +294,25 @@ public void testToFmlTable() { + "(\n" + " c1 BIGINT REPLACE NOT NULL\n" + ");", transform.getNode()); + } + + @Test + public void testMapTypeToFmlTable() { + List columns = Lists.newArrayList(); + List properties = Lists.newArrayList(); + AggrColumnProperty e = new AggrColumnProperty(); + e.setValueString("REPLACE"); + properties.add(e); + columns.add(Column.builder().name("c1").dataType("MAP").properties(properties).build()); + Table table = Table.builder().name("t1").columns(columns).build(); + BaseStatement node = (BaseStatement)starRocksClientConverter.covertToNode(table, + TableConfig.builder().dialectMeta(DialectMeta.DEFAULT_STARROCKS).build()); + StarRocksTransformer starRocksTransformer = new StarRocksTransformer(); + DialectNode transform = starRocksTransformer.transform(node); + assertEquals("CREATE TABLE IF NOT EXISTS t1\n" + + "(\n" + + " c1 MAP REPLACE NOT NULL\n" + + ");", transform.getNode()); } } \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/client/converter/StarRocksPropertyConverterTest.java b/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/client/converter/StarRocksPropertyKeyConverterTest.java similarity index 64% rename from fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/client/converter/StarRocksPropertyConverterTest.java rename to fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/client/converter/StarRocksPropertyKeyConverterTest.java index d3a533a..1c4454e 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/client/converter/StarRocksPropertyConverterTest.java +++ b/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/client/converter/StarRocksPropertyKeyConverterTest.java @@ -4,9 +4,10 @@ import java.util.function.Function; import com.aliyun.fastmodel.transform.api.client.dto.property.BaseClientProperty; -import com.aliyun.fastmodel.transform.starrocks.format.StarRocksProperty; import org.junit.Test; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_INDEX_COMMENT; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_INDEX_TYPE; import static org.junit.Assert.assertNotNull; /** @@ -15,16 +16,16 @@ * @author panguanjing * @date 2023/9/16 */ -public class StarRocksPropertyConverterTest { +public class StarRocksPropertyKeyConverterTest { StarRocksPropertyConverter starRocksPropertyConverter = new StarRocksPropertyConverter(); @Test public void getFunctionMap() { Map> functionMap = starRocksPropertyConverter.getFunctionMap(); - Function stringBaseClientPropertyFunction = functionMap.get(StarRocksProperty.TABLE_INDEX_COMMENT.getValue()); + Function stringBaseClientPropertyFunction = functionMap.get(TABLE_INDEX_COMMENT.getValue()); assertNotNull(stringBaseClientPropertyFunction); - stringBaseClientPropertyFunction = functionMap.get(StarRocksProperty.TABLE_INDEX_TYPE.getValue()); + stringBaseClientPropertyFunction = functionMap.get(TABLE_INDEX_TYPE.getValue()); assertNotNull(stringBaseClientPropertyFunction); } } \ No newline at end of file diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/client/generator/StarRocksGeneratorTest.java b/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/client/generator/StarRocksGeneratorTest.java index f7f1c87..82e875b 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/client/generator/StarRocksGeneratorTest.java +++ b/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/client/generator/StarRocksGeneratorTest.java @@ -20,20 +20,20 @@ import com.aliyun.fastmodel.transform.api.dialect.DialectName; import com.aliyun.fastmodel.transform.api.dialect.DialectNode; import com.aliyun.fastmodel.transform.api.dialect.IVersion; -import com.aliyun.fastmodel.transform.starrocks.client.constraint.StarRocksConstraintType; -import com.aliyun.fastmodel.transform.starrocks.client.constraint.StarRocksDistributeConstraint; -import com.aliyun.fastmodel.transform.starrocks.client.property.column.AggrColumnProperty; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.MultiRangePartitionProperty; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.ReplicationNum; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.SingleRangePartitionProperty; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.TablePartitionRaw; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.ArrayClientPartitionKey; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.LessThanClientPartitionKey; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.MultiRangeClientPartition; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.PartitionClientValue; -import com.aliyun.fastmodel.transform.starrocks.client.property.table.partition.SingleRangeClientPartition; +import com.aliyun.fastmodel.transform.api.extension.client.constraint.ClientConstraintType; +import com.aliyun.fastmodel.transform.api.extension.client.constraint.DistributeClientConstraint; +import com.aliyun.fastmodel.transform.api.extension.client.property.column.AggrColumnProperty; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.MultiRangePartitionProperty; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.ReplicationNum; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.SingleRangePartitionProperty; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.TablePartitionRaw; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.ArrayClientPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.LessThanClientPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.MultiRangeClientPartition; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.PartitionClientValue; +import com.aliyun.fastmodel.transform.api.extension.client.property.table.partition.SingleRangeClientPartition; +import com.aliyun.fastmodel.transform.api.extension.tree.column.AggregateDesc; import com.aliyun.fastmodel.transform.starrocks.parser.StarRocksLanguageParser; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.AggDesc; import com.aliyun.fastmodel.transform.starrocks.parser.tree.datatype.StarRocksDataTypeName; import com.google.common.collect.Lists; import org.junit.Test; @@ -205,7 +205,7 @@ public void testGeneratorSupportPartitionRaw() { + ")"); properties.add(e); - StarRocksDistributeConstraint starRocksDistributeConstraint = new StarRocksDistributeConstraint(); + DistributeClientConstraint starRocksDistributeConstraint = new DistributeClientConstraint(); starRocksDistributeConstraint.setColumns(Lists.newArrayList("c1")); List list = Lists.newArrayList(starRocksDistributeConstraint); @@ -231,7 +231,7 @@ public void testGeneratorSupportPartitionRaw() { + " PARTITION p2 VALUES LESS THAN (\"20210103\"),\n" + " PARTITION p3 VALUES LESS THAN MAXVALUE\n" + ")\n" - + "DISTRIBUTED BY HASH (c1);", dialectNodes.stream().map(DialectNode::getNode).collect(Collectors.joining("\n"))); + + "DISTRIBUTED BY HASH(c1);", dialectNodes.stream().map(DialectNode::getNode).collect(Collectors.joining("\n"))); } @Test @@ -244,7 +244,7 @@ public void testGeneratorSupportDistribute() { .nullable(true) .build()); - StarRocksDistributeConstraint starRocksDistributeConstraint = new StarRocksDistributeConstraint(); + DistributeClientConstraint starRocksDistributeConstraint = new DistributeClientConstraint(); starRocksDistributeConstraint.setColumns(Lists.newArrayList("c1")); starRocksDistributeConstraint.setBucket(1); List list = Lists.newArrayList(starRocksDistributeConstraint); @@ -265,7 +265,7 @@ public void testGeneratorSupportDistribute() { + " c1 INT NULL\n" + ")\n" + "COMMENT \"comment\"\n" - + "DISTRIBUTED BY HASH (c1) BUCKETS 1;", dialectNodes.stream().map(DialectNode::getNode).collect(Collectors.joining("\n"))); + + "DISTRIBUTED BY HASH(c1) BUCKETS 1;", dialectNodes.stream().map(DialectNode::getNode).collect(Collectors.joining("\n"))); } @Test @@ -421,7 +421,7 @@ public void testGeneratorMultiRange() { List columns = Lists.newArrayList(); List columnProp = Lists.newArrayList(); AggrColumnProperty aggrColumnProperty = new AggrColumnProperty(); - aggrColumnProperty.setValueString(AggDesc.MIN.name()); + aggrColumnProperty.setValueString(AggregateDesc.MIN.name()); columnProp.add(aggrColumnProperty); columns.add(Column.builder() @@ -478,7 +478,7 @@ public void testGeneratorMultiRangeInterval() { List columns = Lists.newArrayList(); List columnProp = Lists.newArrayList(); AggrColumnProperty aggrColumnProperty = new AggrColumnProperty(); - aggrColumnProperty.setValueString(AggDesc.MIN.name()); + aggrColumnProperty.setValueString(AggregateDesc.MIN.name()); columnProp.add(aggrColumnProperty); columns.add(Column.builder() @@ -614,7 +614,7 @@ public void testGeneratorDistribute() { ArrayList add = Lists.newArrayList("add"); Constraint distributeConstraint = Constraint.builder().name(null) .columns(add) - .type(StarRocksConstraintType.DISTRIBUTE) + .type(ClientConstraintType.DISTRIBUTE) .build(); constraints.add(distributeConstraint); Table after = Table.builder() @@ -634,7 +634,7 @@ public void testGeneratorDistribute() { + ")\n" + "PRIMARY KEY (`add`)\n" + "COMMENT \"comment\"\n" - + "DISTRIBUTED BY HASH (`add`);", dialectNodes.stream().map(DialectNode::getNode).collect(Collectors.joining("\n"))); + + "DISTRIBUTED BY HASH(`add`);", dialectNodes.stream().map(DialectNode::getNode).collect(Collectors.joining("\n"))); } @Test @@ -722,7 +722,7 @@ public void testDuplicateKey() { ArrayList es = Lists.newArrayList("c1"); Constraint constraint = Constraint.builder().name(null) .columns(es) - .type(StarRocksConstraintType.DUPLICATE_KEY) + .type(ClientConstraintType.DUPLICATE_KEY) .build(); constraints.add(constraint); Table after = Table.builder() @@ -765,7 +765,7 @@ public void testAggregateKey() { ArrayList strings = Lists.newArrayList("c1", "c2"); Constraint constraint = Constraint.builder(). columns(strings) - .type(StarRocksConstraintType.AGGREGATE_KEY) + .type(ClientConstraintType.AGGREGATE_KEY) .build(); constraints.add(constraint); Table after = Table.builder() @@ -807,7 +807,7 @@ public void testUniqueKey() { List constraints = Lists.newArrayList(); ArrayList strings = Lists.newArrayList("c1", "c2"); Constraint constraint = Constraint.builder().columns(strings) - .type(StarRocksConstraintType.UNIQUE_KEY) + .type(ClientConstraintType.UNIQUE_KEY) .build(); constraints.add(constraint); Table after = Table.builder() @@ -896,7 +896,7 @@ public void testDefaultValue() { List constraints = Lists.newArrayList(); Constraint constraint = Constraint.builder() .columns(Lists.newArrayList("c1", "c2")) - .type(StarRocksConstraintType.UNIQUE_KEY) + .type(ClientConstraintType.UNIQUE_KEY) .build(); constraints.add(constraint); Table after = Table.builder() diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/format/StarRocksOutVisitorTest.java b/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/format/StarRocksOutVisitorTest.java index 2b2162c..86a1c8c 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/format/StarRocksOutVisitorTest.java +++ b/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/format/StarRocksOutVisitorTest.java @@ -24,25 +24,28 @@ import com.aliyun.fastmodel.core.tree.statement.table.constraint.PrimaryConstraint; import com.aliyun.fastmodel.core.tree.util.DataTypeUtil; import com.aliyun.fastmodel.core.tree.util.IdentifierUtil; +import com.aliyun.fastmodel.transform.api.extension.tree.column.AggregateDesc; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.AggregateKeyConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.DuplicateKeyConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.DistributeConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.ListPartitionedBy; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.RangePartitionedBy; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.MultiItemListPartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.MultiRangePartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.PartitionDesc; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.SingleItemListPartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.SingleRangePartition; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.LessThanPartitionKey; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.ListPartitionValue; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.keyvalue.PartitionValue; import com.aliyun.fastmodel.transform.starrocks.context.StarRocksContext; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.AggDesc; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.AggregateKeyConstraint; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.DuplicateKeyConstraint; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.desc.DistributeConstraint; import com.aliyun.fastmodel.transform.starrocks.parser.tree.datatype.StarRocksGenericDataType; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.LessThanPartitionKey; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.ListPartitionValue; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.ListPartitionedBy; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.MultiItemListPartition; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.MultiRangePartition; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.PartitionDesc; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.PartitionValue; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.RangePartitionedBy; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.SingleItemListPartition; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.SingleRangePartition; import com.google.common.collect.Lists; import org.junit.Test; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.COLUMN_AGG_DESC; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_ENGINE; +import static com.aliyun.fastmodel.transform.api.extension.client.property.ExtensionPropertyKey.TABLE_PARTITION_RAW; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -171,13 +174,13 @@ public void testDistributeBy() { + "(\n" + " c1\n" + ")\n" - + "DISTRIBUTED BY HASH (c1) BUCKETS 4;", starRocksVisitor.getBuilder().toString()); + + "DISTRIBUTED BY HASH(c1) BUCKETS 4;", starRocksVisitor.getBuilder().toString()); } @Test public void testPartitionValueRaw() { List properties = Lists.newArrayList(); - properties.add(new Property(StarRocksProperty.TABLE_PARTITION_RAW.getValue(), "PARTITION BY RANGE (pay_dt) (\n" + properties.add(new Property(TABLE_PARTITION_RAW.getValue(), "PARTITION BY RANGE (pay_dt) (\n" + " PARTITION p1 VALUES LESS THAN (\"20210102\"),\n" + " PARTITION p2 VALUES LESS THAN (\"20210103\"),\n" + " PARTITION p3 VALUES LESS THAN MAXVALUE\n" @@ -257,13 +260,13 @@ public void testVisitListPartition() { private List toColumnProperties() { List properties = Lists.newArrayList(); - properties.add(new Property(StarRocksProperty.COLUMN_AGG_DESC.getValue(), AggDesc.SUM.name())); + properties.add(new Property(COLUMN_AGG_DESC.getValue(), AggregateDesc.SUM.name())); return properties; } private List toProperty() { List list = Lists.newArrayList(); - list.add(new Property(StarRocksProperty.TABLE_ENGINE.getValue(), "mysql")); + list.add(new Property(TABLE_ENGINE.getValue(), "mysql")); return list; } diff --git a/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/parser/StarRocksLanguageParserTest.java b/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/parser/StarRocksLanguageParserTest.java index 415618e..9c57aa1 100644 --- a/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/parser/StarRocksLanguageParserTest.java +++ b/fastmodel-transform/fastmodel-transform-starrocks/src/test/java/com/aliyun/fastmodel/transform/starrocks/parser/StarRocksLanguageParserTest.java @@ -18,13 +18,13 @@ import com.aliyun.fastmodel.core.tree.statement.table.constraint.UniqueConstraint; import com.aliyun.fastmodel.core.tree.statement.table.index.TableIndex; import com.aliyun.fastmodel.transform.api.context.ReverseContext; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.AggregateKeyConstraint; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.DuplicateKeyConstraint; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.desc.DistributeConstraint; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.constraint.desc.OrderByConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.AggregateKeyConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.DuplicateKeyConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.DistributeConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.constraint.desc.OrderByConstraint; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.RangePartitionedBy; +import com.aliyun.fastmodel.transform.api.extension.tree.partition.desc.PartitionDesc; import com.aliyun.fastmodel.transform.starrocks.parser.tree.datatype.StarRocksDataTypeName; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.PartitionDesc; -import com.aliyun.fastmodel.transform.starrocks.parser.tree.partition.RangePartitionedBy; import org.apache.commons.lang3.StringUtils; import org.junit.Test; diff --git a/fastmodel-transform/pom.xml b/fastmodel-transform/pom.xml index 7c3fa12..b200d9c 100644 --- a/fastmodel-transform/pom.xml +++ b/fastmodel-transform/pom.xml @@ -46,6 +46,8 @@ fastmodel-transform-adbmysql fastmodel-transform-sqlite fastmodel-transform-starrocks + fastmodel-transform-doris + fastmodel-transform-oceanbase diff --git a/pom.xml b/pom.xml index b061080..d740492 100644 --- a/pom.xml +++ b/pom.xml @@ -59,7 +59,7 @@ 11 UTF-8 0.8.5 - 0.5.10 + 0.5.11 1.4.1 4.13.1 @@ -148,7 +148,7 @@ jdk11 - 0.5.10 + 0.5.11 true @@ -189,7 +189,7 @@ jdk8 - 0.5.10-jdk8 + 0.5.11-jdk8