[Enhancement][Refactor](Nereids) generate pattern by operator and refactor Plan and NODE_TYPE generic type (#10019)
This pr support
1. remove the generic type from operator, remove some NODE_TYPE from plan and expression
2. refactor Plan and NODE_TYPE generic type
3. support child class matching by TypePattern
4. analyze the code of operator and generate pattern makes it easy to create rules.
e.g.
```java
class LogicalJoin extends LogicalBinaryOperator;
class PhysicalFilter extends PhysicalUnaryOperator;
```
will generate the code
```java
interface GeneratedPatterns extends Patterns {
default PatternDescriptor<LogicalBinaryPlan<LogicalJoin, Plan, Plan>, Plan> logicalJoin() {
return new PatternDescriptor<LogicalBinaryPlan<LogicalJoin, Plan, Plan>, Plan>(
new TypePattern(LogicalJoin.class, Pattern.FIXED, Pattern.FIXED),
defaultPromise()
);
}
default <C1 extends Plan, C2 extends Plan>
PatternDescriptor<LogicalBinaryPlan<LogicalJoin, C1, C2>, Plan>
logicalJoin(PatternDescriptor<C1, Plan> child1, PatternDescriptor<C2, Plan> child2) {
return new PatternDescriptor<LogicalBinaryPlan<LogicalJoin, C1, C2>, Plan>(
new TypePattern(LogicalJoin.class, child1.pattern, child2.pattern),
defaultPromise()
);
}
default PatternDescriptor<PhysicalUnaryPlan<PhysicalFilter, Plan>, Plan> physicalFilter() {
return new PatternDescriptor<PhysicalUnaryPlan<PhysicalFilter, Plan>, Plan>(
new TypePattern(PhysicalFilter.class, Pattern.FIXED),
defaultPromise()
);
}
default <C1 extends Plan>
PatternDescriptor<PhysicalUnaryPlan<PhysicalFilter, C1>, Plan>
physicalFilter(PatternDescriptor<C1, Plan> child1) {
return new PatternDescriptor<PhysicalUnaryPlan<PhysicalFilter, C1>, Plan>(
new TypePattern(PhysicalFilter.class, child1.pattern),
defaultPromise()
);
}
}
```
and then we don't have to add pattern for new operators.
this function utilizing jsr269 to do something in compile time, and utilizing antlr4 to analyze the code of `Operator`, then we can generate corresponding pattern.
pattern generate steps:
1. maven-compiler-plugin in the pom.xml will compile fe-core three terms. first term will compile `PatternDescribable.java` and `PatternDescribableProcessor.java`
2. second compile term will compile `PatternDescribableProcessPoint.java`, and enable annotation process `PatternDescribableProcessor`, PatternDescribableProcessor will receive the event and know that `PatternDescribableProcessPoint` class contains the `PatternDescribable` annotation.
3. `PatternDescribableProcessor` will not process `PatternDescribableProcessPoint`, but find all java file exists in `operatorPath` that specify in pom.xml, and then parse to Java AST(abstract syntax tree).
5. PatternDescribableProcessor collect java AST and use `PatternGeneratorAnalyzer` to analyze AST, find the child class file for `PlanOperator` then generate `GeneratedPatterns.java` by the AST.
6. third compile term will compile `GeneratedPatterns.java` and other java file.
This commit is contained in:
241
fe/fe-core/src/main/antlr4/org/apache/doris/nereids/JavaLexer.g4
Normal file
241
fe/fe-core/src/main/antlr4/org/apache/doris/nereids/JavaLexer.g4
Normal file
@ -0,0 +1,241 @@
|
||||
/*
|
||||
[The "BSD licence"]
|
||||
Copyright (c) 2013 Terence Parr, Sam Harwell
|
||||
Copyright (c) 2017 Ivan Kochurkin (upgrade to Java 8)
|
||||
Copyright (c) 2021 Michał Lorek (upgrade to Java 11)
|
||||
Copyright (c) 2022 Michał Lorek (upgrade to Java 17)
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
lexer grammar JavaLexer;
|
||||
|
||||
// Keywords
|
||||
|
||||
ABSTRACT: 'abstract';
|
||||
ASSERT: 'assert';
|
||||
BOOLEAN: 'boolean';
|
||||
BREAK: 'break';
|
||||
BYTE: 'byte';
|
||||
CASE: 'case';
|
||||
CATCH: 'catch';
|
||||
CHAR: 'char';
|
||||
CLASS: 'class';
|
||||
CONST: 'const';
|
||||
CONTINUE: 'continue';
|
||||
DEFAULT: 'default';
|
||||
DO: 'do';
|
||||
DOUBLE: 'double';
|
||||
ELSE: 'else';
|
||||
ENUM: 'enum';
|
||||
EXTENDS: 'extends';
|
||||
FINAL: 'final';
|
||||
FINALLY: 'finally';
|
||||
FLOAT: 'float';
|
||||
FOR: 'for';
|
||||
IF: 'if';
|
||||
GOTO: 'goto';
|
||||
IMPLEMENTS: 'implements';
|
||||
IMPORT: 'import';
|
||||
INSTANCEOF: 'instanceof';
|
||||
INT: 'int';
|
||||
INTERFACE: 'interface';
|
||||
LONG: 'long';
|
||||
NATIVE: 'native';
|
||||
NEW: 'new';
|
||||
PACKAGE: 'package';
|
||||
PRIVATE: 'private';
|
||||
PROTECTED: 'protected';
|
||||
PUBLIC: 'public';
|
||||
RETURN: 'return';
|
||||
SHORT: 'short';
|
||||
STATIC: 'static';
|
||||
STRICTFP: 'strictfp';
|
||||
SUPER: 'super';
|
||||
SWITCH: 'switch';
|
||||
SYNCHRONIZED: 'synchronized';
|
||||
THIS: 'this';
|
||||
THROW: 'throw';
|
||||
THROWS: 'throws';
|
||||
TRANSIENT: 'transient';
|
||||
TRY: 'try';
|
||||
VOID: 'void';
|
||||
VOLATILE: 'volatile';
|
||||
WHILE: 'while';
|
||||
|
||||
// Module related keywords
|
||||
MODULE: 'module';
|
||||
OPEN: 'open';
|
||||
REQUIRES: 'requires';
|
||||
EXPORTS: 'exports';
|
||||
OPENS: 'opens';
|
||||
TO: 'to';
|
||||
USES: 'uses';
|
||||
PROVIDES: 'provides';
|
||||
WITH: 'with';
|
||||
TRANSITIVE: 'transitive';
|
||||
|
||||
// Local Variable Type Inference
|
||||
VAR: 'var'; // reserved type name
|
||||
|
||||
// Switch Expressions
|
||||
YIELD: 'yield';
|
||||
|
||||
// Records
|
||||
RECORD: 'record';
|
||||
|
||||
// Sealed Classes
|
||||
SEALED: 'sealed';
|
||||
PERMITS: 'permits';
|
||||
NON_SEALED: 'non-sealed';
|
||||
|
||||
// Literals
|
||||
|
||||
DECIMAL_LITERAL: ('0' | [1-9] (Digits? | '_'+ Digits)) [lL]?;
|
||||
HEX_LITERAL: '0' [xX] [0-9a-fA-F] ([0-9a-fA-F_]* [0-9a-fA-F])? [lL]?;
|
||||
OCT_LITERAL: '0' '_'* [0-7] ([0-7_]* [0-7])? [lL]?;
|
||||
BINARY_LITERAL: '0' [bB] [01] ([01_]* [01])? [lL]?;
|
||||
|
||||
FLOAT_LITERAL: (Digits '.' Digits? | '.' Digits) ExponentPart? [fFdD]?
|
||||
| Digits (ExponentPart [fFdD]? | [fFdD])
|
||||
;
|
||||
|
||||
HEX_FLOAT_LITERAL: '0' [xX] (HexDigits '.'? | HexDigits? '.' HexDigits) [pP] [+-]? Digits [fFdD]?;
|
||||
|
||||
BOOL_LITERAL: 'true'
|
||||
| 'false'
|
||||
;
|
||||
|
||||
CHAR_LITERAL: '\'' (~['\\\r\n] | EscapeSequence) '\'';
|
||||
|
||||
STRING_LITERAL: '"' (~["\\\r\n] | EscapeSequence)* '"';
|
||||
|
||||
TEXT_BLOCK: '"""' [ \t]* [\r\n] (. | EscapeSequence)*? '"""';
|
||||
|
||||
NULL_LITERAL: 'null';
|
||||
|
||||
// Separators
|
||||
|
||||
LPAREN: '(';
|
||||
RPAREN: ')';
|
||||
LBRACE: '{';
|
||||
RBRACE: '}';
|
||||
LBRACK: '[';
|
||||
RBRACK: ']';
|
||||
SEMI: ';';
|
||||
COMMA: ',';
|
||||
DOT: '.';
|
||||
|
||||
// Operators
|
||||
|
||||
ASSIGN: '=';
|
||||
GT: '>';
|
||||
LT: '<';
|
||||
BANG: '!';
|
||||
TILDE: '~';
|
||||
QUESTION: '?';
|
||||
COLON: ':';
|
||||
EQUAL: '==';
|
||||
LE: '<=';
|
||||
GE: '>=';
|
||||
NOTEQUAL: '!=';
|
||||
AND: '&&';
|
||||
OR: '||';
|
||||
INC: '++';
|
||||
DEC: '--';
|
||||
ADD: '+';
|
||||
SUB: '-';
|
||||
MUL: '*';
|
||||
DIV: '/';
|
||||
BITAND: '&';
|
||||
BITOR: '|';
|
||||
CARET: '^';
|
||||
MOD: '%';
|
||||
|
||||
ADD_ASSIGN: '+=';
|
||||
SUB_ASSIGN: '-=';
|
||||
MUL_ASSIGN: '*=';
|
||||
DIV_ASSIGN: '/=';
|
||||
AND_ASSIGN: '&=';
|
||||
OR_ASSIGN: '|=';
|
||||
XOR_ASSIGN: '^=';
|
||||
MOD_ASSIGN: '%=';
|
||||
LSHIFT_ASSIGN: '<<=';
|
||||
RSHIFT_ASSIGN: '>>=';
|
||||
URSHIFT_ASSIGN: '>>>=';
|
||||
|
||||
// Java 8 tokens
|
||||
|
||||
ARROW: '->';
|
||||
COLONCOLON: '::';
|
||||
|
||||
// Additional symbols not defined in the lexical specification
|
||||
|
||||
AT: '@';
|
||||
ELLIPSIS: '...';
|
||||
|
||||
// Whitespace and comments
|
||||
|
||||
WS: [ \t\r\n\u000C]+ -> channel(HIDDEN);
|
||||
COMMENT: '/*' .*? '*/' -> channel(HIDDEN);
|
||||
LINE_COMMENT: '//' ~[\r\n]* -> channel(HIDDEN);
|
||||
|
||||
// Identifiers
|
||||
|
||||
IDENTIFIER: Letter LetterOrDigit*;
|
||||
|
||||
// Fragment rules
|
||||
|
||||
fragment ExponentPart
|
||||
: [eE] [+-]? Digits
|
||||
;
|
||||
|
||||
fragment EscapeSequence
|
||||
: '\\' [btnfr"'\\]
|
||||
| '\\' ([0-3]? [0-7])? [0-7]
|
||||
| '\\' 'u'+ HexDigit HexDigit HexDigit HexDigit
|
||||
;
|
||||
|
||||
fragment HexDigits
|
||||
: HexDigit ((HexDigit | '_')* HexDigit)?
|
||||
;
|
||||
|
||||
fragment HexDigit
|
||||
: [0-9a-fA-F]
|
||||
;
|
||||
|
||||
fragment Digits
|
||||
: [0-9] ([0-9_]* [0-9])?
|
||||
;
|
||||
|
||||
fragment LetterOrDigit
|
||||
: Letter
|
||||
| [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
|
||||
;
|
||||
@ -0,0 +1,762 @@
|
||||
/*
|
||||
[The "BSD licence"]
|
||||
Copyright (c) 2013 Terence Parr, Sam Harwell
|
||||
Copyright (c) 2017 Ivan Kochurkin (upgrade to Java 8)
|
||||
Copyright (c) 2021 Michał Lorek (upgrade to Java 11)
|
||||
Copyright (c) 2022 Michał Lorek (upgrade to Java 17)
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
parser grammar JavaParser;
|
||||
|
||||
options { tokenVocab=JavaLexer; }
|
||||
|
||||
compilationUnit
|
||||
: packageDeclaration? importDeclaration* typeDeclaration*
|
||||
| moduleDeclaration EOF
|
||||
;
|
||||
|
||||
packageDeclaration
|
||||
: annotation* PACKAGE qualifiedName ';'
|
||||
;
|
||||
|
||||
importDeclaration
|
||||
: IMPORT STATIC? qualifiedName importStar? ';'
|
||||
;
|
||||
|
||||
importStar
|
||||
: '.' '*'
|
||||
;
|
||||
|
||||
typeDeclaration
|
||||
: classOrInterfaceModifier*
|
||||
(classDeclaration | enumDeclaration | interfaceDeclaration | annotationTypeDeclaration | recordDeclaration)
|
||||
| ';'
|
||||
;
|
||||
|
||||
modifier
|
||||
: classOrInterfaceModifier
|
||||
| NATIVE
|
||||
| SYNCHRONIZED
|
||||
| TRANSIENT
|
||||
| VOLATILE
|
||||
;
|
||||
|
||||
classOrInterfaceModifier
|
||||
: annotation
|
||||
| PUBLIC
|
||||
| PROTECTED
|
||||
| PRIVATE
|
||||
| STATIC
|
||||
| ABSTRACT
|
||||
| FINAL // FINAL for class only -- does not apply to interfaces
|
||||
| STRICTFP
|
||||
| SEALED // Java17
|
||||
| NON_SEALED // Java17
|
||||
;
|
||||
|
||||
variableModifier
|
||||
: FINAL
|
||||
| annotation
|
||||
;
|
||||
|
||||
classDeclaration
|
||||
: CLASS identifier typeParameters?
|
||||
(EXTENDS typeType)?
|
||||
(IMPLEMENTS typeList)?
|
||||
(PERMITS typeList)? // Java17
|
||||
classBody
|
||||
;
|
||||
|
||||
typeParameters
|
||||
: '<' typeParameter (',' typeParameter)* '>'
|
||||
;
|
||||
|
||||
typeParameter
|
||||
: annotation* identifier (EXTENDS annotation* typeBound)?
|
||||
;
|
||||
|
||||
typeBound
|
||||
: typeType ('&' typeType)*
|
||||
;
|
||||
|
||||
enumDeclaration
|
||||
: ENUM identifier (IMPLEMENTS typeList)? '{' enumConstants? ','? enumBodyDeclarations? '}'
|
||||
;
|
||||
|
||||
enumConstants
|
||||
: enumConstant (',' enumConstant)*
|
||||
;
|
||||
|
||||
enumConstant
|
||||
: annotation* identifier arguments? classBody?
|
||||
;
|
||||
|
||||
enumBodyDeclarations
|
||||
: ';' classBodyDeclaration*
|
||||
;
|
||||
|
||||
interfaceDeclaration
|
||||
: INTERFACE identifier typeParameters? (EXTENDS typeList)? (PERMITS typeList)? interfaceBody
|
||||
;
|
||||
|
||||
classBody
|
||||
: '{' classBodyDeclaration* '}'
|
||||
;
|
||||
|
||||
interfaceBody
|
||||
: '{' interfaceBodyDeclaration* '}'
|
||||
;
|
||||
|
||||
classBodyDeclaration
|
||||
: ';'
|
||||
| STATIC? block
|
||||
| modifier* memberDeclaration
|
||||
;
|
||||
|
||||
memberDeclaration
|
||||
: methodDeclaration
|
||||
| genericMethodDeclaration
|
||||
| fieldDeclaration
|
||||
| constructorDeclaration
|
||||
| genericConstructorDeclaration
|
||||
| interfaceDeclaration
|
||||
| annotationTypeDeclaration
|
||||
| classDeclaration
|
||||
| enumDeclaration
|
||||
| recordDeclaration //Java17
|
||||
;
|
||||
|
||||
/* We use rule this even for void methods which cannot have [] after parameters.
|
||||
This simplifies grammar and we can consider void to be a type, which
|
||||
renders the [] matching as a context-sensitive issue or a semantic check
|
||||
for invalid return type after parsing.
|
||||
*/
|
||||
methodDeclaration
|
||||
: typeTypeOrVoid identifier formalParameters ('[' ']')*
|
||||
(THROWS qualifiedNameList)?
|
||||
methodBody
|
||||
;
|
||||
|
||||
methodBody
|
||||
: block
|
||||
| ';'
|
||||
;
|
||||
|
||||
typeTypeOrVoid
|
||||
: typeType
|
||||
| VOID
|
||||
;
|
||||
|
||||
genericMethodDeclaration
|
||||
: typeParameters methodDeclaration
|
||||
;
|
||||
|
||||
genericConstructorDeclaration
|
||||
: typeParameters constructorDeclaration
|
||||
;
|
||||
|
||||
constructorDeclaration
|
||||
: identifier formalParameters (THROWS qualifiedNameList)? constructorBody=block
|
||||
;
|
||||
|
||||
fieldDeclaration
|
||||
: typeType variableDeclarators ';'
|
||||
;
|
||||
|
||||
interfaceBodyDeclaration
|
||||
: modifier* interfaceMemberDeclaration
|
||||
| ';'
|
||||
;
|
||||
|
||||
interfaceMemberDeclaration
|
||||
: constDeclaration
|
||||
| interfaceMethodDeclaration
|
||||
| genericInterfaceMethodDeclaration
|
||||
| interfaceDeclaration
|
||||
| annotationTypeDeclaration
|
||||
| classDeclaration
|
||||
| enumDeclaration
|
||||
| recordDeclaration // Java17
|
||||
;
|
||||
|
||||
constDeclaration
|
||||
: typeType constantDeclarator (',' constantDeclarator)* ';'
|
||||
;
|
||||
|
||||
constantDeclarator
|
||||
: identifier ('[' ']')* '=' variableInitializer
|
||||
;
|
||||
|
||||
// Early versions of Java allows brackets after the method name, eg.
|
||||
// public int[] return2DArray() [] { ... }
|
||||
// is the same as
|
||||
// public int[][] return2DArray() { ... }
|
||||
interfaceMethodDeclaration
|
||||
: interfaceMethodModifier* interfaceCommonBodyDeclaration
|
||||
;
|
||||
|
||||
// Java8
|
||||
interfaceMethodModifier
|
||||
: annotation
|
||||
| PUBLIC
|
||||
| ABSTRACT
|
||||
| DEFAULT
|
||||
| STATIC
|
||||
| STRICTFP
|
||||
;
|
||||
|
||||
genericInterfaceMethodDeclaration
|
||||
: interfaceMethodModifier* typeParameters interfaceCommonBodyDeclaration
|
||||
;
|
||||
|
||||
interfaceCommonBodyDeclaration
|
||||
: annotation* typeTypeOrVoid identifier formalParameters ('[' ']')* (THROWS qualifiedNameList)? methodBody
|
||||
;
|
||||
|
||||
variableDeclarators
|
||||
: variableDeclarator (',' variableDeclarator)*
|
||||
;
|
||||
|
||||
variableDeclarator
|
||||
: variableDeclaratorId ('=' variableInitializer)?
|
||||
;
|
||||
|
||||
variableDeclaratorId
|
||||
: identifier arrayDeclarator*
|
||||
;
|
||||
|
||||
arrayDeclarator
|
||||
: '[' ']'
|
||||
;
|
||||
|
||||
variableInitializer
|
||||
: arrayInitializer
|
||||
| expression
|
||||
;
|
||||
|
||||
arrayInitializer
|
||||
: '{' (variableInitializer (',' variableInitializer)* (',')? )? '}'
|
||||
;
|
||||
|
||||
classOrInterfaceType
|
||||
: identifierAndTypeArguments ('.' identifierAndTypeArguments)*
|
||||
;
|
||||
|
||||
identifierAndTypeArguments
|
||||
: identifier typeArguments?
|
||||
;
|
||||
|
||||
typeArgument
|
||||
: typeType
|
||||
| annotation* '?' ((EXTENDS | SUPER) typeType)?
|
||||
;
|
||||
|
||||
qualifiedNameList
|
||||
: qualifiedName (',' qualifiedName)*
|
||||
;
|
||||
|
||||
formalParameters
|
||||
: '(' ( receiverParameter?
|
||||
| receiverParameter (',' formalParameterList)?
|
||||
| formalParameterList?
|
||||
) ')'
|
||||
;
|
||||
|
||||
receiverParameter
|
||||
: typeType (identifier '.')* THIS
|
||||
;
|
||||
|
||||
formalParameterList
|
||||
: formalParameter (',' formalParameter)* (',' lastFormalParameter)?
|
||||
| lastFormalParameter
|
||||
;
|
||||
|
||||
formalParameter
|
||||
: variableModifier* typeType variableDeclaratorId
|
||||
;
|
||||
|
||||
lastFormalParameter
|
||||
: variableModifier* typeType annotation* '...' variableDeclaratorId
|
||||
;
|
||||
|
||||
// local variable type inference
|
||||
lambdaLVTIList
|
||||
: lambdaLVTIParameter (',' lambdaLVTIParameter)*
|
||||
;
|
||||
|
||||
lambdaLVTIParameter
|
||||
: variableModifier* VAR identifier
|
||||
;
|
||||
|
||||
qualifiedName
|
||||
: identifier ('.' identifier)*
|
||||
;
|
||||
|
||||
literal
|
||||
: integerLiteral
|
||||
| floatLiteral
|
||||
| CHAR_LITERAL
|
||||
| STRING_LITERAL
|
||||
| BOOL_LITERAL
|
||||
| NULL_LITERAL
|
||||
| TEXT_BLOCK // Java17
|
||||
;
|
||||
|
||||
integerLiteral
|
||||
: DECIMAL_LITERAL
|
||||
| HEX_LITERAL
|
||||
| OCT_LITERAL
|
||||
| BINARY_LITERAL
|
||||
;
|
||||
|
||||
floatLiteral
|
||||
: FLOAT_LITERAL
|
||||
| HEX_FLOAT_LITERAL
|
||||
;
|
||||
|
||||
// ANNOTATIONS
|
||||
altAnnotationQualifiedName
|
||||
: (identifier DOT)* '@' identifier
|
||||
;
|
||||
|
||||
annotation
|
||||
: ('@' qualifiedName | altAnnotationQualifiedName) ('(' ( elementValuePairs | elementValue )? ')')?
|
||||
;
|
||||
|
||||
elementValuePairs
|
||||
: elementValuePair (',' elementValuePair)*
|
||||
;
|
||||
|
||||
elementValuePair
|
||||
: identifier '=' elementValue
|
||||
;
|
||||
|
||||
elementValue
|
||||
: expression
|
||||
| annotation
|
||||
| elementValueArrayInitializer
|
||||
;
|
||||
|
||||
elementValueArrayInitializer
|
||||
: '{' (elementValue (',' elementValue)*)? (',')? '}'
|
||||
;
|
||||
|
||||
annotationTypeDeclaration
|
||||
: '@' INTERFACE identifier annotationTypeBody
|
||||
;
|
||||
|
||||
annotationTypeBody
|
||||
: '{' (annotationTypeElementDeclaration)* '}'
|
||||
;
|
||||
|
||||
annotationTypeElementDeclaration
|
||||
: modifier* annotationTypeElementRest
|
||||
| ';' // this is not allowed by the grammar, but apparently allowed by the actual compiler
|
||||
;
|
||||
|
||||
annotationTypeElementRest
|
||||
: typeType annotationMethodOrConstantRest ';'
|
||||
| classDeclaration ';'?
|
||||
| interfaceDeclaration ';'?
|
||||
| enumDeclaration ';'?
|
||||
| annotationTypeDeclaration ';'?
|
||||
| recordDeclaration ';'? // Java17
|
||||
;
|
||||
|
||||
annotationMethodOrConstantRest
|
||||
: annotationMethodRest
|
||||
| annotationConstantRest
|
||||
;
|
||||
|
||||
annotationMethodRest
|
||||
: identifier '(' ')' defaultValue?
|
||||
;
|
||||
|
||||
annotationConstantRest
|
||||
: variableDeclarators
|
||||
;
|
||||
|
||||
defaultValue
|
||||
: DEFAULT elementValue
|
||||
;
|
||||
|
||||
// MODULES - Java9
|
||||
|
||||
moduleDeclaration
|
||||
: OPEN? MODULE qualifiedName moduleBody
|
||||
;
|
||||
|
||||
moduleBody
|
||||
: '{' moduleDirective* '}'
|
||||
;
|
||||
|
||||
moduleDirective
|
||||
: REQUIRES requiresModifier* qualifiedName ';'
|
||||
| EXPORTS qualifiedName (TO qualifiedName)? ';'
|
||||
| OPENS qualifiedName (TO qualifiedName)? ';'
|
||||
| USES qualifiedName ';'
|
||||
| PROVIDES qualifiedName WITH qualifiedName ';'
|
||||
;
|
||||
|
||||
requiresModifier
|
||||
: TRANSITIVE
|
||||
| STATIC
|
||||
;
|
||||
|
||||
// RECORDS - Java 17
|
||||
|
||||
recordDeclaration
|
||||
: RECORD identifier typeParameters? recordHeader
|
||||
(IMPLEMENTS typeList)?
|
||||
recordBody
|
||||
;
|
||||
|
||||
recordHeader
|
||||
: '(' recordComponentList? ')'
|
||||
;
|
||||
|
||||
recordComponentList
|
||||
: recordComponent (',' recordComponent)*
|
||||
;
|
||||
|
||||
recordComponent
|
||||
: typeType identifier
|
||||
;
|
||||
|
||||
recordBody
|
||||
: '{' classBodyDeclaration* '}'
|
||||
;
|
||||
|
||||
// STATEMENTS / BLOCKS
|
||||
|
||||
block
|
||||
: '{' blockStatement* '}'
|
||||
;
|
||||
|
||||
blockStatement
|
||||
: localVariableDeclaration ';'
|
||||
| statement
|
||||
| localTypeDeclaration
|
||||
;
|
||||
|
||||
localVariableDeclaration
|
||||
: variableModifier* (typeType variableDeclarators | VAR identifier '=' expression)
|
||||
;
|
||||
|
||||
identifier
|
||||
: IDENTIFIER
|
||||
| MODULE
|
||||
| OPEN
|
||||
| REQUIRES
|
||||
| EXPORTS
|
||||
| OPENS
|
||||
| TO
|
||||
| USES
|
||||
| PROVIDES
|
||||
| WITH
|
||||
| TRANSITIVE
|
||||
| YIELD
|
||||
| SEALED
|
||||
| PERMITS
|
||||
| RECORD
|
||||
| VAR
|
||||
;
|
||||
|
||||
localTypeDeclaration
|
||||
: classOrInterfaceModifier*
|
||||
(classDeclaration | interfaceDeclaration | recordDeclaration)
|
||||
| ';'
|
||||
;
|
||||
|
||||
statement
|
||||
: blockLabel=block
|
||||
| ASSERT expression (':' expression)? ';'
|
||||
| IF parExpression statement (ELSE statement)?
|
||||
| FOR '(' forControl ')' statement
|
||||
| WHILE parExpression statement
|
||||
| DO statement WHILE parExpression ';'
|
||||
| TRY block (catchClause+ finallyBlock? | finallyBlock)
|
||||
| TRY resourceSpecification block catchClause* finallyBlock?
|
||||
| SWITCH parExpression '{' switchBlockStatementGroup* switchLabel* '}'
|
||||
| SYNCHRONIZED parExpression block
|
||||
| RETURN expression? ';'
|
||||
| THROW expression ';'
|
||||
| BREAK identifier? ';'
|
||||
| CONTINUE identifier? ';'
|
||||
| YIELD expression ';' // Java17
|
||||
| SEMI
|
||||
| statementExpression=expression ';'
|
||||
| switchExpression ';'? // Java17
|
||||
| identifierLabel=identifier ':' statement
|
||||
;
|
||||
|
||||
catchClause
|
||||
: CATCH '(' variableModifier* catchType identifier ')' block
|
||||
;
|
||||
|
||||
catchType
|
||||
: qualifiedName ('|' qualifiedName)*
|
||||
;
|
||||
|
||||
finallyBlock
|
||||
: FINALLY block
|
||||
;
|
||||
|
||||
resourceSpecification
|
||||
: '(' resources ';'? ')'
|
||||
;
|
||||
|
||||
resources
|
||||
: resource (';' resource)*
|
||||
;
|
||||
|
||||
resource
|
||||
: variableModifier* ( classOrInterfaceType variableDeclaratorId | VAR identifier ) '=' expression
|
||||
| identifier
|
||||
;
|
||||
|
||||
/** Matches cases then statements, both of which are mandatory.
|
||||
* To handle empty cases at the end, we add switchLabel* to statement.
|
||||
*/
|
||||
switchBlockStatementGroup
|
||||
: switchLabel+ blockStatement+
|
||||
;
|
||||
|
||||
switchLabel
|
||||
: CASE (constantExpression=expression | enumConstantName=IDENTIFIER | typeType varName=identifier) ':'
|
||||
| DEFAULT ':'
|
||||
;
|
||||
|
||||
forControl
|
||||
: enhancedForControl
|
||||
| forInit? ';' expression? ';' forUpdate=expressionList?
|
||||
;
|
||||
|
||||
forInit
|
||||
: localVariableDeclaration
|
||||
| expressionList
|
||||
;
|
||||
|
||||
enhancedForControl
|
||||
: variableModifier* (typeType | VAR) variableDeclaratorId ':' expression
|
||||
;
|
||||
|
||||
// EXPRESSIONS
|
||||
|
||||
parExpression
|
||||
: '(' expression ')'
|
||||
;
|
||||
|
||||
expressionList
|
||||
: expression (',' expression)*
|
||||
;
|
||||
|
||||
methodCall
|
||||
: identifier '(' expressionList? ')'
|
||||
| THIS '(' expressionList? ')'
|
||||
| SUPER '(' expressionList? ')'
|
||||
;
|
||||
|
||||
expression
|
||||
: primary
|
||||
| expression bop='.'
|
||||
(
|
||||
identifier
|
||||
| methodCall
|
||||
| THIS
|
||||
| NEW nonWildcardTypeArguments? innerCreator
|
||||
| SUPER superSuffix
|
||||
| explicitGenericInvocation
|
||||
)
|
||||
| expression '[' expression ']'
|
||||
| methodCall
|
||||
| NEW creator
|
||||
| '(' annotation* typeType ('&' typeType)* ')' expression
|
||||
| expression postfix=('++' | '--')
|
||||
| prefix=('+'|'-'|'++'|'--') expression
|
||||
| prefix=('~'|'!') expression
|
||||
| expression bop=('*'|'/'|'%') expression
|
||||
| expression bop=('+'|'-') expression
|
||||
| expression ('<' '<' | '>' '>' '>' | '>' '>') expression
|
||||
| expression bop=('<=' | '>=' | '>' | '<') expression
|
||||
| expression bop=INSTANCEOF (typeType | pattern)
|
||||
| expression bop=('==' | '!=') expression
|
||||
| expression bop='&' expression
|
||||
| expression bop='^' expression
|
||||
| expression bop='|' expression
|
||||
| expression bop='&&' expression
|
||||
| expression bop='||' expression
|
||||
| <assoc=right> expression bop='?' expression ':' expression
|
||||
| <assoc=right> expression
|
||||
bop=('=' | '+=' | '-=' | '*=' | '/=' | '&=' | '|=' | '^=' | '>>=' | '>>>=' | '<<=' | '%=')
|
||||
expression
|
||||
| lambdaExpression // Java8
|
||||
| switchExpression // Java17
|
||||
|
||||
// Java 8 methodReference
|
||||
| expression '::' typeArguments? identifier
|
||||
| typeType '::' (typeArguments? identifier | NEW)
|
||||
| classType '::' typeArguments? NEW
|
||||
;
|
||||
|
||||
// Java17
|
||||
pattern
|
||||
: variableModifier* typeType annotation* identifier
|
||||
;
|
||||
|
||||
// Java8
|
||||
lambdaExpression
|
||||
: lambdaParameters '->' lambdaBody
|
||||
;
|
||||
|
||||
// Java8
|
||||
lambdaParameters
|
||||
: identifier
|
||||
| '(' formalParameterList? ')'
|
||||
| '(' identifier (',' identifier)* ')'
|
||||
| '(' lambdaLVTIList? ')'
|
||||
;
|
||||
|
||||
// Java8
|
||||
lambdaBody
|
||||
: expression
|
||||
| block
|
||||
;
|
||||
|
||||
primary
|
||||
: '(' expression ')'
|
||||
| THIS
|
||||
| SUPER
|
||||
| literal
|
||||
| identifier
|
||||
| typeTypeOrVoid '.' CLASS
|
||||
| nonWildcardTypeArguments (explicitGenericInvocationSuffix | THIS arguments)
|
||||
;
|
||||
|
||||
// Java17
|
||||
switchExpression
|
||||
: SWITCH parExpression '{' switchLabeledRule* '}'
|
||||
;
|
||||
|
||||
// Java17
|
||||
switchLabeledRule
|
||||
: CASE (expressionList | NULL_LITERAL | guardedPattern) (ARROW | COLON) switchRuleOutcome
|
||||
| DEFAULT (ARROW | COLON) switchRuleOutcome
|
||||
;
|
||||
|
||||
// Java17
|
||||
guardedPattern
|
||||
: '(' guardedPattern ')'
|
||||
| variableModifier* typeType annotation* identifier ('&&' expression)*
|
||||
| guardedPattern '&&' expression
|
||||
;
|
||||
|
||||
// Java17
|
||||
switchRuleOutcome
|
||||
: block
|
||||
| blockStatement*
|
||||
;
|
||||
|
||||
classType
|
||||
: (classOrInterfaceType '.')? annotation* identifier typeArguments?
|
||||
;
|
||||
|
||||
creator
|
||||
: nonWildcardTypeArguments createdName classCreatorRest
|
||||
| createdName (arrayCreatorRest | classCreatorRest)
|
||||
;
|
||||
|
||||
createdName
|
||||
: identifier typeArgumentsOrDiamond? ('.' identifier typeArgumentsOrDiamond?)*
|
||||
| primitiveType
|
||||
;
|
||||
|
||||
innerCreator
|
||||
: identifier nonWildcardTypeArgumentsOrDiamond? classCreatorRest
|
||||
;
|
||||
|
||||
arrayCreatorRest
|
||||
: '[' (']' ('[' ']')* arrayInitializer | expression ']' ('[' expression ']')* ('[' ']')*)
|
||||
;
|
||||
|
||||
classCreatorRest
|
||||
: arguments classBody?
|
||||
;
|
||||
|
||||
explicitGenericInvocation
|
||||
: nonWildcardTypeArguments explicitGenericInvocationSuffix
|
||||
;
|
||||
|
||||
typeArgumentsOrDiamond
|
||||
: '<' '>'
|
||||
| typeArguments
|
||||
;
|
||||
|
||||
nonWildcardTypeArgumentsOrDiamond
|
||||
: '<' '>'
|
||||
| nonWildcardTypeArguments
|
||||
;
|
||||
|
||||
nonWildcardTypeArguments
|
||||
: '<' typeList '>'
|
||||
;
|
||||
|
||||
typeList
|
||||
: typeType (',' typeType)*
|
||||
;
|
||||
|
||||
typeType
|
||||
: annotation* (classOrInterfaceType | primitiveType) (annotation* '[' ']')*
|
||||
;
|
||||
|
||||
primitiveType
|
||||
: BOOLEAN
|
||||
| CHAR
|
||||
| BYTE
|
||||
| SHORT
|
||||
| INT
|
||||
| LONG
|
||||
| FLOAT
|
||||
| DOUBLE
|
||||
;
|
||||
|
||||
typeArguments
|
||||
: '<' typeArgument (',' typeArgument)* '>'
|
||||
;
|
||||
|
||||
superSuffix
|
||||
: arguments
|
||||
| '.' typeArguments? identifier arguments?
|
||||
;
|
||||
|
||||
explicitGenericInvocationSuffix
|
||||
: SUPER superSuffix
|
||||
| identifier arguments
|
||||
;
|
||||
|
||||
arguments
|
||||
: '(' expressionList? ')'
|
||||
;
|
||||
@ -29,7 +29,7 @@ import org.apache.doris.nereids.trees.TreeNode;
|
||||
/**
|
||||
* Context used in memo.
|
||||
*/
|
||||
public class OptimizerContext<NODE_TYPE extends TreeNode> {
|
||||
public class OptimizerContext<NODE_TYPE extends TreeNode<NODE_TYPE>> {
|
||||
private final Memo<NODE_TYPE> memo;
|
||||
private RuleSet ruleSet;
|
||||
private JobPool jobPool;
|
||||
|
||||
@ -17,7 +17,6 @@
|
||||
|
||||
package org.apache.doris.nereids;
|
||||
|
||||
import org.apache.doris.nereids.operators.Operator;
|
||||
import org.apache.doris.nereids.operators.plans.physical.PhysicalAggregation;
|
||||
import org.apache.doris.nereids.operators.plans.physical.PhysicalFilter;
|
||||
import org.apache.doris.nereids.operators.plans.physical.PhysicalHashJoin;
|
||||
@ -25,7 +24,9 @@ import org.apache.doris.nereids.operators.plans.physical.PhysicalOlapScan;
|
||||
import org.apache.doris.nereids.operators.plans.physical.PhysicalProject;
|
||||
import org.apache.doris.nereids.operators.plans.physical.PhysicalSort;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalPlan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalBinaryPlan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalLeafPlan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalUnaryPlan;
|
||||
|
||||
/**
|
||||
* Base class for the processing of logical and physical plan.
|
||||
@ -36,35 +37,29 @@ import org.apache.doris.nereids.trees.plans.physical.PhysicalPlan;
|
||||
@SuppressWarnings("rawtypes")
|
||||
public abstract class PlanOperatorVisitor<R, C> {
|
||||
|
||||
public abstract R visit(Plan<? extends Plan, ? extends Operator> plan, C context);
|
||||
public abstract R visit(Plan plan, C context);
|
||||
|
||||
public R visitPhysicalAggregationPlan(PhysicalPlan<? extends PhysicalPlan, PhysicalAggregation> aggPlan,
|
||||
C context) {
|
||||
public R visitPhysicalAggregationPlan(PhysicalUnaryPlan<PhysicalAggregation, Plan> aggPlan, C context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public R visitPhysicalOlapScanPlan(PhysicalPlan<? extends PhysicalPlan, PhysicalOlapScan> olapScanPlan,
|
||||
C context) {
|
||||
public R visitPhysicalOlapScanPlan(PhysicalLeafPlan<PhysicalOlapScan> olapScanPlan, C context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public R visitPhysicalSortPlan(PhysicalPlan<? extends PhysicalPlan, PhysicalSort> sortPlan,
|
||||
C context) {
|
||||
public R visitPhysicalSortPlan(PhysicalUnaryPlan<PhysicalSort, Plan> sortPlan, C context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public R visitPhysicalHashJoinPlan(PhysicalPlan<? extends PhysicalPlan, PhysicalHashJoin> hashJoinPlan,
|
||||
C context) {
|
||||
public R visitPhysicalHashJoinPlan(PhysicalBinaryPlan<PhysicalHashJoin, Plan, Plan> hashJoinPlan, C context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public R visitPhysicalProject(PhysicalPlan<? extends PhysicalPlan, PhysicalProject> projectPlan,
|
||||
C context) {
|
||||
public R visitPhysicalProject(PhysicalUnaryPlan<PhysicalProject, Plan> projectPlan, C context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public R visitPhysicalFilter(PhysicalPlan<? extends PhysicalPlan, PhysicalFilter> filterPlan,
|
||||
C context) {
|
||||
public R visitPhysicalFilter(PhysicalUnaryPlan<PhysicalFilter, Plan> filterPlan, C context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@ -29,8 +29,9 @@ import java.util.List;
|
||||
/**
|
||||
* Expression for unbound alias.
|
||||
*/
|
||||
public class UnboundAlias<CHILD_TYPE extends Expression> extends NamedExpression<UnboundAlias<CHILD_TYPE>>
|
||||
implements UnaryExpression<UnboundAlias<CHILD_TYPE>, CHILD_TYPE> {
|
||||
public class UnboundAlias<CHILD_TYPE extends Expression>
|
||||
extends NamedExpression
|
||||
implements UnaryExpression<CHILD_TYPE> {
|
||||
|
||||
public UnboundAlias(CHILD_TYPE child) {
|
||||
super(NodeType.UNBOUND_ALIAS, child);
|
||||
|
||||
@ -32,7 +32,7 @@ import java.util.List;
|
||||
/**
|
||||
* Represent a relation plan node that has not been bound.
|
||||
*/
|
||||
public class UnboundRelation extends LogicalLeafOperator<UnboundRelation> {
|
||||
public class UnboundRelation extends LogicalLeafOperator {
|
||||
private final List<String> nameParts;
|
||||
|
||||
public UnboundRelation(List<String> nameParts) {
|
||||
|
||||
@ -28,7 +28,7 @@ import java.util.List;
|
||||
/**
|
||||
* Slot has not been bound.
|
||||
*/
|
||||
public class UnboundSlot extends Slot<UnboundSlot> {
|
||||
public class UnboundSlot extends Slot {
|
||||
private final List<String> nameParts;
|
||||
|
||||
public UnboundSlot(List<String> nameParts) {
|
||||
|
||||
@ -29,7 +29,7 @@ import java.util.List;
|
||||
/**
|
||||
* Star expression.
|
||||
*/
|
||||
public class UnboundStar extends NamedExpression<UnboundStar> implements LeafExpression<UnboundStar> {
|
||||
public class UnboundStar extends NamedExpression implements LeafExpression {
|
||||
private final List<String> target;
|
||||
|
||||
public UnboundStar(List<String> target) {
|
||||
|
||||
@ -30,7 +30,7 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* Abstract class for all job using for analyze and optimize query plan in Nereids.
|
||||
*/
|
||||
public abstract class Job<NODE_TYPE extends TreeNode> {
|
||||
public abstract class Job<NODE_TYPE extends TreeNode<NODE_TYPE>> {
|
||||
protected JobType type;
|
||||
protected PlannerContext context;
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@ import java.util.Objects;
|
||||
/**
|
||||
* Bottom up job for rewrite, use pattern match.
|
||||
*/
|
||||
public class RewriteBottomUpJob<NODE_TYPE extends TreeNode> extends Job<NODE_TYPE> {
|
||||
public class RewriteBottomUpJob<NODE_TYPE extends TreeNode<NODE_TYPE>> extends Job<NODE_TYPE> {
|
||||
private final Group group;
|
||||
private final List<Rule<NODE_TYPE>> rules;
|
||||
private final boolean childrenOptimized;
|
||||
|
||||
@ -34,7 +34,7 @@ import java.util.Objects;
|
||||
/**
|
||||
* Top down job for rewrite, use pattern match.
|
||||
*/
|
||||
public class RewriteTopDownJob<NODE_TYPE extends TreeNode> extends Job<NODE_TYPE> {
|
||||
public class RewriteTopDownJob<NODE_TYPE extends TreeNode<NODE_TYPE>> extends Job<NODE_TYPE> {
|
||||
private final Group group;
|
||||
private final List<Rule<NODE_TYPE>> rules;
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ import java.util.Map;
|
||||
*
|
||||
* @param <NODE_TYPE> should be {@link Plan} or {@link Expression}
|
||||
*/
|
||||
public class Memo<NODE_TYPE extends TreeNode> {
|
||||
public class Memo<NODE_TYPE extends TreeNode<NODE_TYPE>> {
|
||||
private final List<Group> groups = Lists.newArrayList();
|
||||
// we could not use Set, because Set has no get method.
|
||||
private final Map<GroupExpression, GroupExpression> groupExpressions = Maps.newHashMap();
|
||||
@ -59,12 +59,11 @@ public class Memo<NODE_TYPE extends TreeNode> {
|
||||
public GroupExpression copyIn(NODE_TYPE node, Group target, boolean rewrite) {
|
||||
Preconditions.checkArgument(!rewrite || target != null);
|
||||
List<Group> childrenGroups = Lists.newArrayList();
|
||||
for (Object object : node.children()) {
|
||||
NODE_TYPE child = (NODE_TYPE) object;
|
||||
for (NODE_TYPE child : node.children()) {
|
||||
childrenGroups.add(copyIn(child, null, rewrite).getParent());
|
||||
}
|
||||
if (node.getGroupExpression() != null && groupExpressions.containsKey(node.getGroupExpression())) {
|
||||
return node.getGroupExpression();
|
||||
if (node.getGroupExpression().isPresent() && groupExpressions.containsKey(node.getGroupExpression().get())) {
|
||||
return node.getGroupExpression().get();
|
||||
}
|
||||
GroupExpression newGroupExpression = new GroupExpression(node.getOperator());
|
||||
newGroupExpression.setChildren(childrenGroups);
|
||||
|
||||
@ -25,7 +25,7 @@ import java.util.Objects;
|
||||
/**
|
||||
* Abstract class for all concrete operator.
|
||||
*/
|
||||
public abstract class AbstractOperator<TYPE extends AbstractOperator<TYPE>> implements Operator<TYPE> {
|
||||
public abstract class AbstractOperator implements Operator {
|
||||
protected final OperatorType type;
|
||||
protected final long limited;
|
||||
|
||||
@ -52,7 +52,7 @@ public abstract class AbstractOperator<TYPE extends AbstractOperator<TYPE>> impl
|
||||
* (PhysicalPlan<? extends PhysicalPlan, PhysicalOlapScan>) plan, context);
|
||||
* </code>
|
||||
*/
|
||||
public <R, C> R accept(PlanOperatorVisitor<R, C> visitor, Plan<?, ?> plan, C context) {
|
||||
public <R, C> R accept(PlanOperatorVisitor<R, C> visitor, Plan plan, C context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@ -25,11 +25,11 @@ import org.apache.doris.nereids.trees.plans.Plan;
|
||||
/**
|
||||
* interface for all concrete operator.
|
||||
*/
|
||||
public interface Operator<TYPE extends Operator<TYPE>> {
|
||||
public interface Operator {
|
||||
OperatorType getType();
|
||||
|
||||
<NODE_TYPE extends TreeNode> NODE_TYPE toTreeNode(GroupExpression groupExpression);
|
||||
<NODE_TYPE extends TreeNode<NODE_TYPE>> NODE_TYPE toTreeNode(GroupExpression groupExpression);
|
||||
|
||||
public <R, C> R accept(PlanOperatorVisitor<R, C> visitor, Plan<?, ?> plan, C context);
|
||||
<R, C> R accept(PlanOperatorVisitor<R, C> visitor, Plan plan, C context);
|
||||
|
||||
}
|
||||
|
||||
@ -46,6 +46,7 @@ public enum OperatorType {
|
||||
PHYSICAL_EXCHANGE,
|
||||
|
||||
// pattern
|
||||
NORMAL_PATTERN,
|
||||
ANY,
|
||||
MULTI,
|
||||
FIXED,
|
||||
|
||||
@ -17,13 +17,8 @@
|
||||
|
||||
package org.apache.doris.nereids.operators.plans;
|
||||
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
|
||||
/**
|
||||
* interface for all concrete binary plan operator.
|
||||
*/
|
||||
public interface BinaryPlanOperator<
|
||||
TYPE extends BinaryPlanOperator<TYPE, LEFT_INPUT_TYPE, RIGHT_INPUT_TYPE>,
|
||||
LEFT_INPUT_TYPE extends Plan,
|
||||
RIGHT_INPUT_TYPE extends Plan> extends PlanOperator<TYPE> {
|
||||
public interface BinaryPlanOperator extends PlanOperator {
|
||||
}
|
||||
|
||||
@ -20,5 +20,5 @@ package org.apache.doris.nereids.operators.plans;
|
||||
/**
|
||||
* interface for all concrete leaf plan operator.
|
||||
*/
|
||||
public interface LeafPlanOperator<TYPE extends LeafPlanOperator<TYPE>> extends PlanOperator<TYPE> {
|
||||
public interface LeafPlanOperator extends PlanOperator {
|
||||
}
|
||||
|
||||
@ -22,5 +22,5 @@ import org.apache.doris.nereids.operators.Operator;
|
||||
/**
|
||||
* interface for all concrete plan operator.
|
||||
*/
|
||||
public interface PlanOperator<TYPE extends PlanOperator<TYPE>> extends Operator<TYPE> {
|
||||
public interface PlanOperator extends Operator {
|
||||
}
|
||||
|
||||
@ -17,12 +17,8 @@
|
||||
|
||||
package org.apache.doris.nereids.operators.plans;
|
||||
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
|
||||
/**
|
||||
* interface for all concrete unary plan operator.
|
||||
*/
|
||||
public interface UnaryPlanOperator<
|
||||
TYPE extends UnaryPlanOperator<TYPE, INPUT_TYPE>,
|
||||
INPUT_TYPE extends Plan> extends PlanOperator<TYPE> {
|
||||
public interface UnaryPlanOperator extends PlanOperator {
|
||||
}
|
||||
|
||||
@ -25,19 +25,15 @@ import org.apache.doris.nereids.properties.LogicalProperties;
|
||||
import org.apache.doris.nereids.trees.expressions.Slot;
|
||||
import org.apache.doris.nereids.trees.plans.PlaceHolderPlan;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalBinary;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalBinaryPlan;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Abstract class for all logical binary operator that have two inputs.
|
||||
*/
|
||||
public abstract class LogicalBinaryOperator<
|
||||
TYPE extends LogicalBinaryOperator<TYPE, LEFT_INPUT_TYPE, RIGHT_INPUT_TYPE>,
|
||||
LEFT_INPUT_TYPE extends Plan,
|
||||
RIGHT_INPUT_TYPE extends Plan>
|
||||
extends AbstractOperator<TYPE>
|
||||
implements LogicalOperator<TYPE>, BinaryPlanOperator<TYPE, LEFT_INPUT_TYPE, RIGHT_INPUT_TYPE> {
|
||||
public abstract class LogicalBinaryOperator extends AbstractOperator
|
||||
implements LogicalOperator, BinaryPlanOperator {
|
||||
|
||||
public LogicalBinaryOperator(OperatorType type) {
|
||||
super(type);
|
||||
@ -45,15 +41,15 @@ public abstract class LogicalBinaryOperator<
|
||||
|
||||
@Override
|
||||
public final List<Slot> computeOutput(Plan... inputs) {
|
||||
return doComputeOutput((LEFT_INPUT_TYPE) inputs[0], (RIGHT_INPUT_TYPE) inputs[1]);
|
||||
return doComputeOutput(inputs[0], inputs[1]);
|
||||
}
|
||||
|
||||
public abstract List<Slot> doComputeOutput(LEFT_INPUT_TYPE left, RIGHT_INPUT_TYPE right);
|
||||
public abstract List<Slot> doComputeOutput(Plan left, Plan right);
|
||||
|
||||
@Override
|
||||
public LogicalBinary toTreeNode(GroupExpression groupExpression) {
|
||||
public LogicalBinaryPlan toTreeNode(GroupExpression groupExpression) {
|
||||
LogicalProperties logicalProperties = groupExpression.getParent().getLogicalProperties();
|
||||
return new LogicalBinary(this, groupExpression, logicalProperties,
|
||||
return new LogicalBinaryPlan(this, groupExpression, logicalProperties,
|
||||
new PlaceHolderPlan(), new PlaceHolderPlan());
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,8 +28,7 @@ import java.util.Objects;
|
||||
/**
|
||||
* Logical filter plan operator.
|
||||
*/
|
||||
public class LogicalFilter<INPUT_TYPE extends Plan>
|
||||
extends LogicalUnaryOperator<LogicalFilter<INPUT_TYPE>, INPUT_TYPE> {
|
||||
public class LogicalFilter extends LogicalUnaryOperator {
|
||||
|
||||
private final Expression predicates;
|
||||
|
||||
@ -44,7 +43,7 @@ public class LogicalFilter<INPUT_TYPE extends Plan>
|
||||
|
||||
|
||||
@Override
|
||||
public List<Slot> doComputeOutput(INPUT_TYPE input) {
|
||||
public List<Slot> doComputeOutput(Plan input) {
|
||||
return input.getOutput();
|
||||
}
|
||||
|
||||
|
||||
@ -33,9 +33,7 @@ import java.util.Optional;
|
||||
/**
|
||||
* Logical join plan operator.
|
||||
*/
|
||||
public class LogicalJoin<LEFT_INPUT_TYPE extends Plan, RIGHT_INPUT_TYPE extends Plan>
|
||||
extends LogicalBinaryOperator<LogicalJoin<LEFT_INPUT_TYPE, RIGHT_INPUT_TYPE>,
|
||||
LEFT_INPUT_TYPE, RIGHT_INPUT_TYPE> {
|
||||
public class LogicalJoin extends LogicalBinaryOperator {
|
||||
|
||||
private final JoinType joinType;
|
||||
private final Optional<Expression> onClause;
|
||||
@ -73,7 +71,7 @@ public class LogicalJoin<LEFT_INPUT_TYPE extends Plan, RIGHT_INPUT_TYPE extends
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Slot> doComputeOutput(LEFT_INPUT_TYPE leftInput, RIGHT_INPUT_TYPE rightInput) {
|
||||
public List<Slot> doComputeOutput(Plan leftInput, Plan rightInput) {
|
||||
switch (joinType) {
|
||||
case LEFT_SEMI_JOIN:
|
||||
return ImmutableList.copyOf(leftInput.getOutput());
|
||||
|
||||
@ -23,16 +23,15 @@ import org.apache.doris.nereids.operators.OperatorType;
|
||||
import org.apache.doris.nereids.operators.plans.LeafPlanOperator;
|
||||
import org.apache.doris.nereids.trees.expressions.Slot;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalLeaf;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalLeafPlan;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Abstract class for all logical operator that have no input.
|
||||
*/
|
||||
public abstract class LogicalLeafOperator<TYPE extends LogicalLeafOperator<TYPE>>
|
||||
extends AbstractOperator<TYPE>
|
||||
implements LogicalOperator<TYPE>, LeafPlanOperator<TYPE> {
|
||||
public abstract class LogicalLeafOperator extends AbstractOperator
|
||||
implements LogicalOperator, LeafPlanOperator {
|
||||
|
||||
public LogicalLeafOperator(OperatorType type) {
|
||||
super(type);
|
||||
@ -46,7 +45,7 @@ public abstract class LogicalLeafOperator<TYPE extends LogicalLeafOperator<TYPE>
|
||||
public abstract List<Slot> doComputeOutput();
|
||||
|
||||
@Override
|
||||
public LogicalLeaf toTreeNode(GroupExpression groupExpression) {
|
||||
return new LogicalLeaf(this, groupExpression, groupExpression.getParent().getLogicalProperties());
|
||||
public LogicalLeafPlan toTreeNode(GroupExpression groupExpression) {
|
||||
return new LogicalLeafPlan(this, groupExpression, groupExpression.getParent().getLogicalProperties());
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,6 +26,6 @@ import java.util.List;
|
||||
/**
|
||||
* interface for all concrete logical plan operator.
|
||||
*/
|
||||
public interface LogicalOperator<TYPE extends LogicalOperator<TYPE>> extends PlanOperator<TYPE> {
|
||||
public interface LogicalOperator extends PlanOperator {
|
||||
List<Slot> computeOutput(Plan... inputs);
|
||||
}
|
||||
|
||||
@ -32,8 +32,7 @@ import java.util.Objects;
|
||||
/**
|
||||
* Logical project plan operator.
|
||||
*/
|
||||
public class LogicalProject<INPUT_TYPE extends Plan>
|
||||
extends LogicalUnaryOperator<LogicalProject<INPUT_TYPE>, INPUT_TYPE> {
|
||||
public class LogicalProject extends LogicalUnaryOperator {
|
||||
|
||||
private final List<? extends NamedExpression> projects;
|
||||
|
||||
@ -57,7 +56,7 @@ public class LogicalProject<INPUT_TYPE extends Plan>
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Slot> doComputeOutput(INPUT_TYPE input) {
|
||||
public List<Slot> doComputeOutput(Plan input) {
|
||||
// fixme: not throw a checked exception
|
||||
return projects.stream()
|
||||
.map(namedExpr -> {
|
||||
|
||||
@ -31,7 +31,7 @@ import java.util.Objects;
|
||||
/**
|
||||
* Logical relation plan operator.
|
||||
*/
|
||||
public class LogicalRelation extends LogicalLeafOperator<LogicalRelation> {
|
||||
public class LogicalRelation extends LogicalLeafOperator {
|
||||
|
||||
private final Table table;
|
||||
private final List<String> qualifier;
|
||||
|
||||
@ -25,18 +25,15 @@ import org.apache.doris.nereids.properties.LogicalProperties;
|
||||
import org.apache.doris.nereids.trees.expressions.Slot;
|
||||
import org.apache.doris.nereids.trees.plans.PlaceHolderPlan;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalUnary;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalUnaryPlan;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Abstract class for all logical operator that have one input.
|
||||
*/
|
||||
public abstract class LogicalUnaryOperator<
|
||||
TYPE extends LogicalUnaryOperator<TYPE, INPUT_TYPE>,
|
||||
INPUT_TYPE extends Plan>
|
||||
extends AbstractOperator<TYPE>
|
||||
implements LogicalOperator<TYPE>, UnaryPlanOperator<TYPE, INPUT_TYPE> {
|
||||
public abstract class LogicalUnaryOperator extends AbstractOperator
|
||||
implements LogicalOperator, UnaryPlanOperator {
|
||||
|
||||
public LogicalUnaryOperator(OperatorType type) {
|
||||
super(type);
|
||||
@ -44,14 +41,14 @@ public abstract class LogicalUnaryOperator<
|
||||
|
||||
@Override
|
||||
public final List<Slot> computeOutput(Plan... inputs) {
|
||||
return doComputeOutput((INPUT_TYPE) inputs[0]);
|
||||
return doComputeOutput(inputs[0]);
|
||||
}
|
||||
|
||||
public abstract List<Slot> doComputeOutput(INPUT_TYPE input);
|
||||
public abstract List<Slot> doComputeOutput(Plan input);
|
||||
|
||||
@Override
|
||||
public LogicalUnary toTreeNode(GroupExpression groupExpression) {
|
||||
public LogicalUnaryPlan toTreeNode(GroupExpression groupExpression) {
|
||||
LogicalProperties logicalProperties = groupExpression.getParent().getLogicalProperties();
|
||||
return new LogicalUnary(this, groupExpression, logicalProperties, new PlaceHolderPlan());
|
||||
return new LogicalUnaryPlan(this, groupExpression, logicalProperties, new PlaceHolderPlan());
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,14 +22,14 @@ import org.apache.doris.nereids.operators.OperatorType;
|
||||
import org.apache.doris.nereids.operators.plans.AggPhase;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalPlan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalUnaryPlan;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Physical aggregation plan operator.
|
||||
*/
|
||||
public class PhysicalAggregation extends PhysicalUnaryOperator<PhysicalAggregation, PhysicalPlan> {
|
||||
public class PhysicalAggregation extends PhysicalUnaryOperator {
|
||||
|
||||
private final List<Expression> groupByExprList;
|
||||
|
||||
@ -80,8 +80,7 @@ public class PhysicalAggregation extends PhysicalUnaryOperator<PhysicalAggregati
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, C> R accept(PlanOperatorVisitor<R, C> visitor, Plan<?, ?> plan, C context) {
|
||||
return visitor.visitPhysicalAggregationPlan(
|
||||
(PhysicalPlan<? extends PhysicalPlan, PhysicalAggregation>) plan, context);
|
||||
public <R, C> R accept(PlanOperatorVisitor<R, C> visitor, Plan plan, C context) {
|
||||
return visitor.visitPhysicalAggregationPlan((PhysicalUnaryPlan<PhysicalAggregation, Plan>) plan, context);
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,19 +25,15 @@ import org.apache.doris.nereids.properties.LogicalProperties;
|
||||
import org.apache.doris.nereids.trees.expressions.Slot;
|
||||
import org.apache.doris.nereids.trees.plans.PlaceHolderPlan;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalBinary;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalBinaryPlan;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Abstract class for all physical operator that have two inputs.
|
||||
*/
|
||||
public abstract class PhysicalBinaryOperator<
|
||||
TYPE extends PhysicalBinaryOperator<TYPE, LEFT_INPUT_TYPE, RIGHT_INPUT_TYPE>,
|
||||
LEFT_INPUT_TYPE extends Plan,
|
||||
RIGHT_INPUT_TYPE extends Plan>
|
||||
extends AbstractOperator<TYPE>
|
||||
implements PhysicalOperator<TYPE>, BinaryPlanOperator<TYPE, LEFT_INPUT_TYPE, RIGHT_INPUT_TYPE> {
|
||||
public abstract class PhysicalBinaryOperator extends AbstractOperator
|
||||
implements PhysicalOperator, BinaryPlanOperator {
|
||||
|
||||
public PhysicalBinaryOperator(OperatorType type) {
|
||||
super(type);
|
||||
@ -45,18 +41,17 @@ public abstract class PhysicalBinaryOperator<
|
||||
|
||||
@Override
|
||||
public final List<Slot> computeOutputs(LogicalProperties logicalProperties, Plan... inputs) {
|
||||
return doComputeOutput(logicalProperties, (LEFT_INPUT_TYPE) inputs[0], (RIGHT_INPUT_TYPE) inputs[1]);
|
||||
return doComputeOutput(logicalProperties, inputs[0], inputs[1]);
|
||||
}
|
||||
|
||||
public List<Slot> doComputeOutput(LogicalProperties logicalProperties,
|
||||
LEFT_INPUT_TYPE left, RIGHT_INPUT_TYPE right) {
|
||||
public List<Slot> doComputeOutput(LogicalProperties logicalProperties, Plan left, Plan right) {
|
||||
return logicalProperties.getOutput();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhysicalBinary toTreeNode(GroupExpression groupExpression) {
|
||||
public PhysicalBinaryPlan toTreeNode(GroupExpression groupExpression) {
|
||||
LogicalProperties logicalProperties = groupExpression.getParent().getLogicalProperties();
|
||||
return new PhysicalBinary(this, groupExpression, logicalProperties,
|
||||
return new PhysicalBinaryPlan(this, groupExpression, logicalProperties,
|
||||
new PlaceHolderPlan(), new PlaceHolderPlan());
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,9 +28,7 @@ import java.util.Optional;
|
||||
/**
|
||||
* Physical operator represents broadcast hash join.
|
||||
*/
|
||||
public class PhysicalBroadcastHashJoin<LEFT_INPUT_TYPE extends Plan, RIGHT_INPUT_TYPE extends Plan>
|
||||
extends PhysicalBinaryOperator<PhysicalBroadcastHashJoin<LEFT_INPUT_TYPE, RIGHT_INPUT_TYPE>,
|
||||
LEFT_INPUT_TYPE, RIGHT_INPUT_TYPE> {
|
||||
public class PhysicalBroadcastHashJoin extends PhysicalBinaryOperator {
|
||||
|
||||
private final JoinType joinType;
|
||||
private final Optional<Expression> onClause;
|
||||
|
||||
@ -21,15 +21,14 @@ import org.apache.doris.nereids.PlanOperatorVisitor;
|
||||
import org.apache.doris.nereids.operators.OperatorType;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalPlan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalUnaryPlan;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Physical filter plan operator.
|
||||
*/
|
||||
public class PhysicalFilter<INPUT_TYPE extends Plan>
|
||||
extends PhysicalUnaryOperator<PhysicalFilter<INPUT_TYPE>, INPUT_TYPE> {
|
||||
public class PhysicalFilter extends PhysicalUnaryOperator {
|
||||
|
||||
private final Expression predicates;
|
||||
|
||||
@ -54,8 +53,7 @@ public class PhysicalFilter<INPUT_TYPE extends Plan>
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, C> R accept(PlanOperatorVisitor<R, C> visitor, Plan<?, ?> plan, C context) {
|
||||
return visitor.visitPhysicalFilter((PhysicalPlan<? extends PhysicalPlan, PhysicalFilter>) plan,
|
||||
context);
|
||||
public <R, C> R accept(PlanOperatorVisitor<R, C> visitor, Plan plan, C context) {
|
||||
return visitor.visitPhysicalFilter((PhysicalUnaryPlan<PhysicalFilter, Plan>) plan, context);
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,12 +22,12 @@ import org.apache.doris.nereids.operators.OperatorType;
|
||||
import org.apache.doris.nereids.operators.plans.JoinType;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalPlan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalBinaryPlan;
|
||||
|
||||
/**
|
||||
* Physical hash join plan operator.
|
||||
*/
|
||||
public class PhysicalHashJoin extends PhysicalBinaryOperator<PhysicalHashJoin, PhysicalPlan, PhysicalPlan> {
|
||||
public class PhysicalHashJoin extends PhysicalBinaryOperator {
|
||||
|
||||
private final JoinType joinType;
|
||||
|
||||
@ -54,9 +54,8 @@ public class PhysicalHashJoin extends PhysicalBinaryOperator<PhysicalHashJoin, P
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, C> R accept(PlanOperatorVisitor<R, C> visitor, Plan<?, ?> plan, C context) {
|
||||
return visitor.visitPhysicalHashJoinPlan(
|
||||
(PhysicalPlan<? extends PhysicalPlan, PhysicalHashJoin>) plan, context);
|
||||
public <R, C> R accept(PlanOperatorVisitor<R, C> visitor, Plan plan, C context) {
|
||||
return visitor.visitPhysicalHashJoinPlan((PhysicalBinaryPlan<PhysicalHashJoin, Plan, Plan>) plan, context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -24,16 +24,15 @@ import org.apache.doris.nereids.operators.plans.LeafPlanOperator;
|
||||
import org.apache.doris.nereids.properties.LogicalProperties;
|
||||
import org.apache.doris.nereids.trees.expressions.Slot;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalLeaf;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalLeafPlan;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Abstract class for all physical operator that have no input.
|
||||
*/
|
||||
public abstract class PhysicalLeafOperator<TYPE extends PhysicalLeafOperator<TYPE>>
|
||||
extends AbstractOperator<TYPE>
|
||||
implements PhysicalOperator<TYPE>, LeafPlanOperator<TYPE> {
|
||||
public abstract class PhysicalLeafOperator extends AbstractOperator
|
||||
implements PhysicalOperator, LeafPlanOperator {
|
||||
|
||||
public PhysicalLeafOperator(OperatorType type) {
|
||||
super(type);
|
||||
@ -49,7 +48,7 @@ public abstract class PhysicalLeafOperator<TYPE extends PhysicalLeafOperator<TYP
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhysicalLeaf toTreeNode(GroupExpression groupExpression) {
|
||||
return new PhysicalLeaf(this, groupExpression, groupExpression.getParent().getLogicalProperties());
|
||||
public PhysicalLeafPlan toTreeNode(GroupExpression groupExpression) {
|
||||
return new PhysicalLeafPlan(this, groupExpression, groupExpression.getParent().getLogicalProperties());
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ import org.apache.doris.catalog.Partition;
|
||||
import org.apache.doris.nereids.PlanOperatorVisitor;
|
||||
import org.apache.doris.nereids.operators.OperatorType;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalPlan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalLeafPlan;
|
||||
|
||||
import com.clearspring.analytics.util.Lists;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -32,7 +32,7 @@ import java.util.List;
|
||||
/**
|
||||
* Physical olap scan plan operator.
|
||||
*/
|
||||
public class PhysicalOlapScan extends PhysicalScan<PhysicalOlapScan> {
|
||||
public class PhysicalOlapScan extends PhysicalScan {
|
||||
private final long selectedIndexId;
|
||||
private final List<Long> selectedTabletId;
|
||||
private final List<Long> selectedPartitionId;
|
||||
@ -80,9 +80,8 @@ public class PhysicalOlapScan extends PhysicalScan<PhysicalOlapScan> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, C> R accept(PlanOperatorVisitor<R, C> visitor, Plan<?, ?> plan, C context) {
|
||||
return visitor.visitPhysicalOlapScanPlan(
|
||||
(PhysicalPlan<? extends PhysicalPlan, PhysicalOlapScan>) plan, context);
|
||||
public <R, C> R accept(PlanOperatorVisitor<R, C> visitor, Plan plan, C context) {
|
||||
return visitor.visitPhysicalOlapScanPlan((PhysicalLeafPlan<PhysicalOlapScan>) plan, context);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ import java.util.List;
|
||||
/**
|
||||
* interface for all concrete physical operator.
|
||||
*/
|
||||
public interface PhysicalOperator<TYPE extends PhysicalOperator<TYPE>> extends PlanOperator<TYPE> {
|
||||
public interface PhysicalOperator extends PlanOperator {
|
||||
|
||||
List<Slot> computeOutputs(LogicalProperties logicalProperties, Plan... inputs);
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ import org.apache.doris.nereids.PlanOperatorVisitor;
|
||||
import org.apache.doris.nereids.operators.OperatorType;
|
||||
import org.apache.doris.nereids.trees.expressions.NamedExpression;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalPlan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalUnaryPlan;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@ -31,8 +31,7 @@ import java.util.Objects;
|
||||
/**
|
||||
* Physical project plan operator.
|
||||
*/
|
||||
public class PhysicalProject<INPUT_TYPE extends Plan>
|
||||
extends PhysicalUnaryOperator<PhysicalProject<INPUT_TYPE>, INPUT_TYPE> {
|
||||
public class PhysicalProject extends PhysicalUnaryOperator {
|
||||
|
||||
private final List<? extends NamedExpression> projects;
|
||||
|
||||
@ -51,8 +50,7 @@ public class PhysicalProject<INPUT_TYPE extends Plan>
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, C> R accept(PlanOperatorVisitor<R, C> visitor, Plan<?, ?> plan, C context) {
|
||||
return visitor.visitPhysicalProject(
|
||||
(PhysicalPlan<? extends PhysicalPlan, PhysicalProject>) plan, context);
|
||||
public <R, C> R accept(PlanOperatorVisitor<R, C> visitor, Plan plan, C context) {
|
||||
return visitor.visitPhysicalProject(((PhysicalUnaryPlan<PhysicalProject, Plan>) plan), context);
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,7 +25,7 @@ import java.util.Objects;
|
||||
/**
|
||||
* Abstract class for all physical scan operator.
|
||||
*/
|
||||
public abstract class PhysicalScan<TYPE extends PhysicalScan<TYPE>> extends PhysicalLeafOperator<TYPE> {
|
||||
public abstract class PhysicalScan extends PhysicalLeafOperator {
|
||||
|
||||
|
||||
protected final List<String> qualifier;
|
||||
|
||||
@ -21,14 +21,14 @@ import org.apache.doris.nereids.PlanOperatorVisitor;
|
||||
import org.apache.doris.nereids.operators.OperatorType;
|
||||
import org.apache.doris.nereids.properties.OrderKey;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalPlan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalUnaryPlan;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Physical sort plan operator.
|
||||
*/
|
||||
public class PhysicalSort extends PhysicalUnaryOperator<PhysicalSort, PhysicalPlan> {
|
||||
public class PhysicalSort extends PhysicalUnaryOperator {
|
||||
|
||||
private final int offset;
|
||||
|
||||
@ -70,8 +70,7 @@ public class PhysicalSort extends PhysicalUnaryOperator<PhysicalSort, PhysicalPl
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, C> R accept(PlanOperatorVisitor<R, C> visitor, Plan<?, ?> plan, C context) {
|
||||
return visitor.visitPhysicalSortPlan((PhysicalPlan<? extends PhysicalPlan, PhysicalSort>) plan,
|
||||
context);
|
||||
public <R, C> R accept(PlanOperatorVisitor<R, C> visitor, Plan plan, C context) {
|
||||
return visitor.visitPhysicalSortPlan((PhysicalUnaryPlan<PhysicalSort, Plan>) plan, context);
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,18 +25,15 @@ import org.apache.doris.nereids.properties.LogicalProperties;
|
||||
import org.apache.doris.nereids.trees.expressions.Slot;
|
||||
import org.apache.doris.nereids.trees.plans.PlaceHolderPlan;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalUnary;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalUnaryPlan;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Abstract class for all physical operator that have one input.
|
||||
*/
|
||||
public abstract class PhysicalUnaryOperator<
|
||||
TYPE extends PhysicalUnaryOperator<TYPE, INPUT_TYPE>,
|
||||
INPUT_TYPE extends Plan>
|
||||
extends AbstractOperator<TYPE>
|
||||
implements PhysicalOperator<TYPE>, UnaryPlanOperator<TYPE, INPUT_TYPE> {
|
||||
public abstract class PhysicalUnaryOperator extends AbstractOperator
|
||||
implements PhysicalOperator, UnaryPlanOperator {
|
||||
|
||||
public PhysicalUnaryOperator(OperatorType type) {
|
||||
super(type);
|
||||
@ -44,16 +41,16 @@ public abstract class PhysicalUnaryOperator<
|
||||
|
||||
@Override
|
||||
public final List<Slot> computeOutputs(LogicalProperties logicalProperties, Plan... inputs) {
|
||||
return doComputeOutput(logicalProperties, (INPUT_TYPE) inputs[0]);
|
||||
return doComputeOutput(logicalProperties, inputs[0]);
|
||||
}
|
||||
|
||||
public List<Slot> doComputeOutput(LogicalProperties logicalProperties, INPUT_TYPE input) {
|
||||
public List<Slot> doComputeOutput(LogicalProperties logicalProperties, Plan input) {
|
||||
return logicalProperties.getOutput();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhysicalUnary toTreeNode(GroupExpression groupExpression) {
|
||||
public PhysicalUnaryPlan toTreeNode(GroupExpression groupExpression) {
|
||||
LogicalProperties logicalProperties = groupExpression.getParent().getLogicalProperties();
|
||||
return new PhysicalUnary(this, groupExpression, logicalProperties, new PlaceHolderPlan());
|
||||
return new PhysicalUnaryPlan(this, groupExpression, logicalProperties, new PlaceHolderPlan());
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,10 +66,10 @@ import org.apache.doris.nereids.trees.expressions.Literal;
|
||||
import org.apache.doris.nereids.trees.expressions.NamedExpression;
|
||||
import org.apache.doris.nereids.trees.expressions.Not;
|
||||
import org.apache.doris.nereids.trees.expressions.NullSafeEqual;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalBinary;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalLeaf;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalBinaryPlan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalLeafPlan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalUnary;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalUnaryPlan;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
@ -95,7 +95,7 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
|
||||
*/
|
||||
private final BiFunction<WhereClauseContext, LogicalPlan, LogicalPlan> withWhereClause =
|
||||
(WhereClauseContext ctx, LogicalPlan plan)
|
||||
-> new LogicalUnary(new LogicalFilter(expression((ctx.booleanExpression()))), plan);
|
||||
-> new LogicalUnaryPlan(new LogicalFilter(expression((ctx.booleanExpression()))), plan);
|
||||
|
||||
protected <T> T typedVisit(ParseTree ctx) {
|
||||
return (T) ctx.accept(this);
|
||||
@ -213,7 +213,7 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
|
||||
|
||||
LogicalPlan withProject;
|
||||
if (CollectionUtils.isNotEmpty(namedExpressions)) {
|
||||
withProject = new LogicalUnary(new LogicalProject(namedExpressions), withFilter);
|
||||
withProject = new LogicalUnaryPlan(new LogicalProject(namedExpressions), withFilter);
|
||||
} else {
|
||||
withProject = withFilter;
|
||||
}
|
||||
@ -229,7 +229,7 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
|
||||
if (left == null) {
|
||||
left = right;
|
||||
} else {
|
||||
left = new LogicalBinary(new LogicalJoin(JoinType.INNER_JOIN, null), left, right);
|
||||
left = new LogicalBinaryPlan(new LogicalJoin(JoinType.INNER_JOIN, null), left, right);
|
||||
}
|
||||
left = withJoinRelations(left, relation);
|
||||
}
|
||||
@ -269,7 +269,7 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
|
||||
condition = expression(joinCriteria.booleanExpression());
|
||||
}
|
||||
|
||||
last = new LogicalBinary(
|
||||
last = new LogicalBinaryPlan(
|
||||
new LogicalJoin(joinType, Optional.ofNullable(condition)),
|
||||
last, plan(join.relationPrimary())
|
||||
);
|
||||
@ -285,7 +285,7 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> {
|
||||
List<String> tableId = visitMultipartIdentifier(ctx.multipartIdentifier());
|
||||
UnboundRelation relation = new UnboundRelation(tableId);
|
||||
// TODO: sample and time travel, alias, sub query
|
||||
return new LogicalLeaf(relation);
|
||||
return new LogicalLeafPlan(relation);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -32,11 +32,11 @@ import java.util.Objects;
|
||||
* TODO: adapt ANY and MULTI
|
||||
* TODO: add ut
|
||||
*/
|
||||
public class GroupExpressionMatching<NODE_TYPE extends TreeNode> implements Iterable<NODE_TYPE> {
|
||||
private final Pattern pattern;
|
||||
public class GroupExpressionMatching<NODE_TYPE extends TreeNode<NODE_TYPE>> implements Iterable<NODE_TYPE> {
|
||||
private final Pattern<? extends NODE_TYPE, NODE_TYPE> pattern;
|
||||
private final GroupExpression groupExpression;
|
||||
|
||||
public GroupExpressionMatching(Pattern pattern, GroupExpression groupExpression) {
|
||||
public GroupExpressionMatching(Pattern<? extends NODE_TYPE, NODE_TYPE> pattern, GroupExpression groupExpression) {
|
||||
this.pattern = Objects.requireNonNull(pattern);
|
||||
this.groupExpression = Objects.requireNonNull(groupExpression);
|
||||
}
|
||||
@ -49,7 +49,7 @@ public class GroupExpressionMatching<NODE_TYPE extends TreeNode> implements Iter
|
||||
/**
|
||||
* Iterator to get all subtrees.
|
||||
*/
|
||||
public static class GroupExpressionIterator<NODE_TYPE extends TreeNode> implements Iterator<NODE_TYPE> {
|
||||
public static class GroupExpressionIterator<NODE_TYPE extends TreeNode<NODE_TYPE>> implements Iterator<NODE_TYPE> {
|
||||
private final List<NODE_TYPE> results;
|
||||
private int resultIndex = 0;
|
||||
|
||||
@ -59,7 +59,8 @@ public class GroupExpressionMatching<NODE_TYPE extends TreeNode> implements Iter
|
||||
* @param pattern pattern to match
|
||||
* @param groupExpression group expression to be matched
|
||||
*/
|
||||
public GroupExpressionIterator(Pattern pattern, GroupExpression groupExpression) {
|
||||
public GroupExpressionIterator(Pattern<? extends NODE_TYPE, NODE_TYPE> pattern,
|
||||
GroupExpression groupExpression) {
|
||||
results = Lists.newArrayList();
|
||||
|
||||
if (!pattern.matchOperator(groupExpression.getOperator())) {
|
||||
@ -74,7 +75,7 @@ public class GroupExpressionMatching<NODE_TYPE extends TreeNode> implements Iter
|
||||
return;
|
||||
}
|
||||
|
||||
NODE_TYPE root = (NODE_TYPE) groupExpression.getOperator().toTreeNode(groupExpression);
|
||||
NODE_TYPE root = groupExpression.getOperator().toTreeNode(groupExpression);
|
||||
|
||||
List<List<NODE_TYPE>> childrenResults = Lists.newArrayListWithCapacity(groupExpression.arity());
|
||||
for (int i = 0; i < groupExpression.arity(); ++i) {
|
||||
@ -96,7 +97,7 @@ public class GroupExpressionMatching<NODE_TYPE extends TreeNode> implements Iter
|
||||
for (int i = 0; i < childrenResults.size(); i++) {
|
||||
children.add(childrenResults.get(i).get(childrenResultsIndex[i]));
|
||||
}
|
||||
NODE_TYPE result = (NODE_TYPE) root.newChildren(children);
|
||||
NODE_TYPE result = root.newChildren(children);
|
||||
results.add(result);
|
||||
offset = 0;
|
||||
while (true) {
|
||||
|
||||
@ -48,7 +48,7 @@ public class GroupMatching<NODE_TYPE extends TreeNode> implements Iterable<NODE_
|
||||
/**
|
||||
* Iterator to get all subtrees from a group.
|
||||
*/
|
||||
public static class GroupIterator<NODE_TYPE extends TreeNode> implements Iterator<NODE_TYPE> {
|
||||
public static class GroupIterator<NODE_TYPE extends TreeNode<NODE_TYPE>> implements Iterator<NODE_TYPE> {
|
||||
private final Pattern pattern;
|
||||
private final List<Iterator<NODE_TYPE>> iterator;
|
||||
private int iteratorIndex = 0;
|
||||
@ -59,19 +59,19 @@ public class GroupMatching<NODE_TYPE extends TreeNode> implements Iterable<NODE_
|
||||
* @param pattern pattern to match
|
||||
* @param group group to be matched
|
||||
*/
|
||||
public GroupIterator(Pattern pattern, Group group) {
|
||||
public GroupIterator(Pattern<? extends NODE_TYPE, NODE_TYPE> pattern, Group group) {
|
||||
this.pattern = pattern;
|
||||
this.iterator = Lists.newArrayList();
|
||||
for (GroupExpression groupExpression : group.getLogicalExpressions()) {
|
||||
GroupExpressionMatching.GroupExpressionIterator<NODE_TYPE> groupExpressionIterator =
|
||||
new GroupExpressionMatching<NODE_TYPE>(pattern, groupExpression).iterator();
|
||||
new GroupExpressionMatching(pattern, groupExpression).iterator();
|
||||
if (groupExpressionIterator.hasNext()) {
|
||||
this.iterator.add(groupExpressionIterator);
|
||||
}
|
||||
}
|
||||
for (GroupExpression groupExpression : group.getPhysicalExpressions()) {
|
||||
GroupExpressionMatching.GroupExpressionIterator<NODE_TYPE> groupExpressionIterator =
|
||||
new GroupExpressionMatching<NODE_TYPE>(pattern, groupExpression).iterator();
|
||||
new GroupExpressionMatching(pattern, groupExpression).iterator();
|
||||
if (groupExpressionIterator.hasNext()) {
|
||||
this.iterator.add(groupExpressionIterator);
|
||||
}
|
||||
|
||||
@ -23,6 +23,10 @@ import org.apache.doris.nereids.trees.TreeNode;
|
||||
* Define an callback action when match a pattern, usually implement as a rule body.
|
||||
* e.g. exchange join children for JoinCommutative Rule
|
||||
*/
|
||||
public interface MatchedAction<INPUT_TYPE extends TreeNode, OUTPUT_TYPE extends TreeNode> {
|
||||
OUTPUT_TYPE apply(MatchingContext<INPUT_TYPE> ctx);
|
||||
public interface MatchedAction<
|
||||
INPUT_TYPE extends RULE_TYPE,
|
||||
OUTPUT_TYPE extends RULE_TYPE,
|
||||
RULE_TYPE extends TreeNode<RULE_TYPE>> {
|
||||
|
||||
OUTPUT_TYPE apply(MatchingContext<INPUT_TYPE, RULE_TYPE> ctx);
|
||||
}
|
||||
|
||||
@ -23,9 +23,9 @@ import org.apache.doris.nereids.trees.TreeNode;
|
||||
/**
|
||||
* Define a context when match a pattern pass through a MatchedAction.
|
||||
*/
|
||||
public class MatchingContext<T extends TreeNode> {
|
||||
public final T root;
|
||||
public final Pattern<T> pattern;
|
||||
public class MatchingContext<TYPE extends RULE_TYPE, RULE_TYPE extends TreeNode<RULE_TYPE>> {
|
||||
public final TYPE root;
|
||||
public final Pattern<TYPE, RULE_TYPE> pattern;
|
||||
public final PlannerContext plannerContext;
|
||||
|
||||
/**
|
||||
@ -35,7 +35,7 @@ public class MatchingContext<T extends TreeNode> {
|
||||
* @param pattern the defined pattern
|
||||
* @param plannerContext the planner context
|
||||
*/
|
||||
public MatchingContext(T root, Pattern<T> pattern, PlannerContext plannerContext) {
|
||||
public MatchingContext(TYPE root, Pattern<TYPE, RULE_TYPE> pattern, PlannerContext plannerContext) {
|
||||
this.root = root;
|
||||
this.pattern = pattern;
|
||||
this.plannerContext = plannerContext;
|
||||
|
||||
@ -28,20 +28,21 @@ import com.google.common.collect.ImmutableList;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
|
||||
/**
|
||||
* Pattern node used in pattern matching.
|
||||
*/
|
||||
public class Pattern<T extends TreeNode> extends AbstractTreeNode<Pattern<T>> {
|
||||
public class Pattern<TYPE extends NODE_TYPE, NODE_TYPE extends TreeNode<NODE_TYPE>>
|
||||
extends AbstractTreeNode<Pattern<? extends NODE_TYPE, NODE_TYPE>> {
|
||||
public static final Pattern ANY = new Pattern(OperatorType.ANY);
|
||||
public static final Pattern MULTI = new Pattern(OperatorType.MULTI);
|
||||
public static final Pattern FIXED = new Pattern(OperatorType.FIXED);
|
||||
public static final Pattern MULTI_FIXED = new Pattern(OperatorType.MULTI_FIXED);
|
||||
|
||||
private final List<Predicate<T>> predicates;
|
||||
private final OperatorType operatorType;
|
||||
protected final List<Predicate<TYPE>> predicates;
|
||||
protected final OperatorType operatorType;
|
||||
|
||||
/**
|
||||
* Constructor for Pattern.
|
||||
@ -62,7 +63,7 @@ public class Pattern<T extends TreeNode> extends AbstractTreeNode<Pattern<T>> {
|
||||
* @param predicates custom matching predicate
|
||||
* @param children sub pattern
|
||||
*/
|
||||
public Pattern(OperatorType operatorType, List<Predicate<T>> predicates, Pattern... children) {
|
||||
public Pattern(OperatorType operatorType, List<Predicate<TYPE>> predicates, Pattern... children) {
|
||||
super(NodeType.PATTERN, children);
|
||||
this.operatorType = operatorType;
|
||||
this.predicates = ImmutableList.copyOf(predicates);
|
||||
@ -112,7 +113,7 @@ public class Pattern<T extends TreeNode> extends AbstractTreeNode<Pattern<T>> {
|
||||
* @param root wait to match
|
||||
* @return ture if current Pattern match Plan in params
|
||||
*/
|
||||
public boolean matchRoot(T root) {
|
||||
public boolean matchRoot(TYPE root) {
|
||||
if (root == null) {
|
||||
return false;
|
||||
}
|
||||
@ -125,6 +126,10 @@ public class Pattern<T extends TreeNode> extends AbstractTreeNode<Pattern<T>> {
|
||||
return true;
|
||||
}
|
||||
|
||||
return doMatchRoot(root);
|
||||
}
|
||||
|
||||
protected boolean doMatchRoot(TYPE root) {
|
||||
return getOperatorType().equals(root.getOperator().getType())
|
||||
&& predicates.stream().allMatch(predicate -> predicate.test(root));
|
||||
}
|
||||
@ -135,9 +140,10 @@ public class Pattern<T extends TreeNode> extends AbstractTreeNode<Pattern<T>> {
|
||||
* @param root wait to match
|
||||
* @return ture if children Patterns match root's children in params
|
||||
*/
|
||||
public boolean matchChildren(T root) {
|
||||
public boolean matchChildren(TYPE root) {
|
||||
for (int i = 0; i < arity(); i++) {
|
||||
if (!child(i).match(root.child(i))) {
|
||||
Pattern child = child(i);
|
||||
if (!child.match(root.child(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -150,18 +156,22 @@ public class Pattern<T extends TreeNode> extends AbstractTreeNode<Pattern<T>> {
|
||||
* @param root wait to match
|
||||
* @return ture if current pattern and children patterns match root in params
|
||||
*/
|
||||
public boolean match(T root) {
|
||||
public boolean match(TYPE root) {
|
||||
return matchRoot(root) && matchChildren(root);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pattern<T> newChildren(List<TreeNode> children) {
|
||||
public Pattern<? extends NODE_TYPE, NODE_TYPE> newChildren(List<Pattern<? extends NODE_TYPE, NODE_TYPE>> children) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
public Pattern<TYPE, NODE_TYPE> withPredicates(List<Predicate<TYPE>> predicates) {
|
||||
return new Pattern(operatorType, predicates, children.toArray(new Pattern[0]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public GroupExpression getGroupExpression() {
|
||||
throw new RuntimeException();
|
||||
public Optional<GroupExpression> getGroupExpression() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -180,14 +190,4 @@ public class Pattern<T extends TreeNode> extends AbstractTreeNode<Pattern<T>> {
|
||||
public int hashCode() {
|
||||
return Objects.hash(operatorType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Pattern> children() {
|
||||
return (List) children;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pattern child(int index) {
|
||||
return (Pattern) children.get(index);
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,12 +30,12 @@ import java.util.function.Predicate;
|
||||
* Define a descriptor to wrap a pattern tree to define a pattern shape.
|
||||
* It can support pattern generic type to MatchedAction.
|
||||
*/
|
||||
public class PatternDescriptor<INPUT_TYPE extends RULE_TYPE, RULE_TYPE extends TreeNode> {
|
||||
public final Pattern<INPUT_TYPE> pattern;
|
||||
public class PatternDescriptor<INPUT_TYPE extends RULE_TYPE, RULE_TYPE extends TreeNode<RULE_TYPE>> {
|
||||
public final Pattern<INPUT_TYPE, RULE_TYPE> pattern;
|
||||
public final RulePromise defaultPromise;
|
||||
public final List<Predicate<INPUT_TYPE>> predicates = new ArrayList<>();
|
||||
|
||||
public PatternDescriptor(Pattern<INPUT_TYPE> pattern, RulePromise defaultPromise) {
|
||||
public PatternDescriptor(Pattern<INPUT_TYPE, RULE_TYPE> pattern, RulePromise defaultPromise) {
|
||||
this.pattern = Objects.requireNonNull(pattern, "pattern can not be null");
|
||||
this.defaultPromise = Objects.requireNonNull(defaultPromise, "defaultPromise can not be null");
|
||||
}
|
||||
@ -47,16 +47,12 @@ public class PatternDescriptor<INPUT_TYPE extends RULE_TYPE, RULE_TYPE extends T
|
||||
|
||||
public <OUTPUT_TYPE extends RULE_TYPE> PatternMatcher<INPUT_TYPE, OUTPUT_TYPE, RULE_TYPE> then(
|
||||
Function<INPUT_TYPE, OUTPUT_TYPE> matchedAction) {
|
||||
return new PatternMatcher<>(patternWithPredicates(), defaultPromise, ctx -> matchedAction.apply(ctx.root));
|
||||
return new PatternMatcher<>(
|
||||
pattern.withPredicates(predicates), defaultPromise, ctx -> matchedAction.apply(ctx.root));
|
||||
}
|
||||
|
||||
public <OUTPUT_TYPE extends RULE_TYPE> PatternMatcher<INPUT_TYPE, OUTPUT_TYPE, RULE_TYPE> thenApply(
|
||||
MatchedAction<INPUT_TYPE, OUTPUT_TYPE> matchedAction) {
|
||||
return new PatternMatcher<>(patternWithPredicates(), defaultPromise, matchedAction);
|
||||
}
|
||||
|
||||
public Pattern<INPUT_TYPE> patternWithPredicates() {
|
||||
Pattern[] children = pattern.children().toArray(new Pattern[0]);
|
||||
return new Pattern<>(pattern.getOperatorType(), predicates, children);
|
||||
MatchedAction<INPUT_TYPE, OUTPUT_TYPE, RULE_TYPE> matchedAction) {
|
||||
return new PatternMatcher<>(pattern.withPredicates(predicates), defaultPromise, matchedAction);
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,11 +35,11 @@ import java.util.Objects;
|
||||
public class PatternMatcher<
|
||||
INPUT_TYPE extends RULE_TYPE,
|
||||
OUTPUT_TYPE extends RULE_TYPE,
|
||||
RULE_TYPE extends TreeNode> {
|
||||
RULE_TYPE extends TreeNode<RULE_TYPE>> {
|
||||
|
||||
public final Pattern<INPUT_TYPE> pattern;
|
||||
public final Pattern<INPUT_TYPE, RULE_TYPE> pattern;
|
||||
public final RulePromise defaultRulePromise;
|
||||
public final MatchedAction<INPUT_TYPE, OUTPUT_TYPE> matchedAction;
|
||||
public final MatchedAction<INPUT_TYPE, OUTPUT_TYPE, RULE_TYPE> matchedAction;
|
||||
|
||||
/**
|
||||
* PatternMatcher wrap a pattern, defaultRulePromise and matchedAction.
|
||||
@ -48,8 +48,8 @@ public class PatternMatcher<
|
||||
* @param defaultRulePromise defaultRulePromise
|
||||
* @param matchedAction matched callback function
|
||||
*/
|
||||
public PatternMatcher(Pattern<INPUT_TYPE> pattern, RulePromise defaultRulePromise,
|
||||
MatchedAction<INPUT_TYPE, OUTPUT_TYPE> matchedAction) {
|
||||
public PatternMatcher(Pattern<INPUT_TYPE, RULE_TYPE> pattern, RulePromise defaultRulePromise,
|
||||
MatchedAction<INPUT_TYPE, OUTPUT_TYPE, RULE_TYPE> matchedAction) {
|
||||
this.pattern = Objects.requireNonNull(pattern, "pattern can not be null");
|
||||
this.defaultRulePromise = Objects.requireNonNull(
|
||||
defaultRulePromise, "defaultRulePromise can not be null");
|
||||
@ -71,7 +71,7 @@ public class PatternMatcher<
|
||||
return new Rule<RULE_TYPE>(ruleType, pattern, rulePromise) {
|
||||
@Override
|
||||
public List<RULE_TYPE> transform(RULE_TYPE originPlan, PlannerContext context) {
|
||||
MatchingContext<INPUT_TYPE> matchingContext =
|
||||
MatchingContext<INPUT_TYPE, RULE_TYPE> matchingContext =
|
||||
new MatchingContext<>((INPUT_TYPE) originPlan, pattern, context);
|
||||
OUTPUT_TYPE replacePlan = matchedAction.apply(matchingContext);
|
||||
return ImmutableList.of(replacePlan == null ? originPlan : replacePlan);
|
||||
|
||||
@ -17,26 +17,28 @@
|
||||
|
||||
package org.apache.doris.nereids.pattern;
|
||||
|
||||
import org.apache.doris.nereids.analyzer.UnboundRelation;
|
||||
import org.apache.doris.nereids.operators.OperatorType;
|
||||
import org.apache.doris.nereids.operators.plans.JoinType;
|
||||
import org.apache.doris.nereids.operators.plans.logical.LogicalFilter;
|
||||
import org.apache.doris.nereids.operators.plans.logical.LogicalJoin;
|
||||
import org.apache.doris.nereids.operators.plans.logical.LogicalProject;
|
||||
import org.apache.doris.nereids.operators.plans.logical.LogicalRelation;
|
||||
import org.apache.doris.nereids.operators.plans.physical.PhysicalBroadcastHashJoin;
|
||||
import org.apache.doris.nereids.operators.plans.physical.PhysicalFilter;
|
||||
import org.apache.doris.nereids.operators.plans.physical.PhysicalOlapScan;
|
||||
import org.apache.doris.nereids.operators.plans.physical.PhysicalProject;
|
||||
import org.apache.doris.nereids.operators.plans.BinaryPlanOperator;
|
||||
import org.apache.doris.nereids.operators.plans.LeafPlanOperator;
|
||||
import org.apache.doris.nereids.operators.plans.UnaryPlanOperator;
|
||||
import org.apache.doris.nereids.operators.plans.logical.LogicalBinaryOperator;
|
||||
import org.apache.doris.nereids.operators.plans.logical.LogicalLeafOperator;
|
||||
import org.apache.doris.nereids.operators.plans.logical.LogicalUnaryOperator;
|
||||
import org.apache.doris.nereids.operators.plans.physical.PhysicalBinaryOperator;
|
||||
import org.apache.doris.nereids.operators.plans.physical.PhysicalLeafOperator;
|
||||
import org.apache.doris.nereids.operators.plans.physical.PhysicalScan;
|
||||
import org.apache.doris.nereids.operators.plans.physical.PhysicalUnaryOperator;
|
||||
import org.apache.doris.nereids.rules.RulePromise;
|
||||
import org.apache.doris.nereids.trees.TreeNode;
|
||||
import org.apache.doris.nereids.trees.plans.BinaryPlan;
|
||||
import org.apache.doris.nereids.trees.plans.LeafPlan;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalBinary;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalLeaf;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalUnary;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalBinary;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalLeaf;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalUnary;
|
||||
import org.apache.doris.nereids.trees.plans.UnaryPlan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalBinaryPlan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalLeafPlan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalUnaryPlan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalBinaryPlan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalLeafPlan;
|
||||
import org.apache.doris.nereids.trees.plans.physical.PhysicalUnaryPlan;
|
||||
|
||||
/**
|
||||
* An interface provided some PatternDescriptor.
|
||||
@ -47,231 +49,171 @@ public interface Patterns {
|
||||
// need implement
|
||||
RulePromise defaultPromise();
|
||||
|
||||
// logical pattern descriptors
|
||||
/* special pattern descriptors */
|
||||
|
||||
default <T extends RULE_TYPE, RULE_TYPE extends TreeNode> PatternDescriptor<T, RULE_TYPE> any() {
|
||||
default <T extends RULE_TYPE, RULE_TYPE extends TreeNode<RULE_TYPE>> PatternDescriptor<T, RULE_TYPE> any() {
|
||||
return new PatternDescriptor<>(Pattern.ANY, defaultPromise());
|
||||
}
|
||||
|
||||
default <T extends RULE_TYPE, RULE_TYPE extends TreeNode> PatternDescriptor<T, RULE_TYPE> multi() {
|
||||
default <T extends RULE_TYPE, RULE_TYPE extends TreeNode<RULE_TYPE>> PatternDescriptor<T, RULE_TYPE> multi() {
|
||||
return new PatternDescriptor<>(Pattern.MULTI, defaultPromise());
|
||||
}
|
||||
|
||||
default <T extends RULE_TYPE, RULE_TYPE extends TreeNode> PatternDescriptor<T, RULE_TYPE> fixed() {
|
||||
default <T extends RULE_TYPE, RULE_TYPE extends TreeNode<RULE_TYPE>> PatternDescriptor<T, RULE_TYPE> fixed() {
|
||||
return new PatternDescriptor<>(Pattern.FIXED, defaultPromise());
|
||||
}
|
||||
|
||||
default <T extends RULE_TYPE, RULE_TYPE extends TreeNode<RULE_TYPE>> PatternDescriptor<T, RULE_TYPE> multiFixed() {
|
||||
return new PatternDescriptor<>(Pattern.MULTI_FIXED, defaultPromise());
|
||||
}
|
||||
|
||||
/* abstract plan operator patterns */
|
||||
|
||||
/**
|
||||
* create a unboundRelation pattern.
|
||||
* create a leafPlan pattern.
|
||||
*/
|
||||
default PatternDescriptor<LogicalLeaf<UnboundRelation>, Plan> unboundRelation() {
|
||||
return new PatternDescriptor<>(
|
||||
new Pattern<>(OperatorType.LOGICAL_UNBOUND_RELATION),
|
||||
default PatternDescriptor<LeafPlan, Plan> leafPlan() {
|
||||
return new PatternDescriptor(new TypePattern(LeafPlanOperator.class), defaultPromise());
|
||||
}
|
||||
|
||||
/**
|
||||
* create a unaryPlan pattern.
|
||||
*/
|
||||
default PatternDescriptor<UnaryPlan<Plan>, Plan> unaryPlan() {
|
||||
return new PatternDescriptor(new TypePattern(UnaryPlanOperator.class, Pattern.FIXED), defaultPromise());
|
||||
}
|
||||
|
||||
/**
|
||||
* create a unaryPlan pattern.
|
||||
*/
|
||||
default <C extends Plan> PatternDescriptor<UnaryPlan<C>, Plan>
|
||||
unaryPlan(PatternDescriptor<C, Plan> child) {
|
||||
return new PatternDescriptor(new TypePattern(UnaryPlanOperator.class, child.pattern), defaultPromise());
|
||||
}
|
||||
|
||||
/**
|
||||
* create a binaryPlan pattern.
|
||||
*/
|
||||
default PatternDescriptor<BinaryPlan<Plan, Plan>, Plan> binaryPlan() {
|
||||
return new PatternDescriptor(
|
||||
new TypePattern(BinaryPlanOperator.class, Pattern.FIXED, Pattern.FIXED),
|
||||
defaultPromise()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a logicalFilter pattern.
|
||||
* create a binaryPlan pattern.
|
||||
*/
|
||||
default PatternDescriptor<LogicalUnary<LogicalFilter, Plan>, Plan> logicalFilter() {
|
||||
return new PatternDescriptor<>(
|
||||
new Pattern<>(OperatorType.LOGICAL_FILTER, new Pattern<>(OperatorType.FIXED)),
|
||||
default <LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends Plan>
|
||||
PatternDescriptor<BinaryPlan<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE>, Plan> binaryPlan(
|
||||
PatternDescriptor<LEFT_CHILD_TYPE, Plan> leftChild,
|
||||
PatternDescriptor<RIGHT_CHILD_TYPE, Plan> rightChild) {
|
||||
return new PatternDescriptor(
|
||||
new TypePattern(BinaryPlanOperator.class, leftChild.pattern, rightChild.pattern),
|
||||
defaultPromise()
|
||||
);
|
||||
}
|
||||
|
||||
/* abstract logical operator patterns */
|
||||
|
||||
/**
|
||||
* create a logicalLeaf pattern.
|
||||
*/
|
||||
default PatternDescriptor<LogicalLeafPlan<LogicalLeafOperator>, Plan> logicalLeaf() {
|
||||
return new PatternDescriptor(new TypePattern(LogicalLeafPlan.class), defaultPromise());
|
||||
}
|
||||
|
||||
/**
|
||||
* create a logicalUnary pattern.
|
||||
*/
|
||||
default PatternDescriptor<LogicalUnaryPlan<LogicalUnaryOperator, Plan>, Plan> logicalUnary() {
|
||||
return new PatternDescriptor(new TypePattern(LogicalUnaryPlan.class, Pattern.FIXED), defaultPromise());
|
||||
}
|
||||
|
||||
/**
|
||||
* create a logicalUnary pattern.
|
||||
*/
|
||||
default <C extends Plan> PatternDescriptor<LogicalUnaryPlan<LogicalUnaryOperator, C>, Plan>
|
||||
logicalUnary(PatternDescriptor<C, Plan> child) {
|
||||
return new PatternDescriptor(new TypePattern(LogicalUnaryPlan.class, child.pattern), defaultPromise());
|
||||
}
|
||||
|
||||
/**
|
||||
* create a logicalBinary pattern.
|
||||
*/
|
||||
default PatternDescriptor<LogicalBinaryPlan<LogicalBinaryOperator, Plan, Plan>, Plan> logicalBinary() {
|
||||
return new PatternDescriptor(
|
||||
new TypePattern(LogicalBinaryPlan.class, Pattern.FIXED, Pattern.FIXED),
|
||||
defaultPromise()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a logicalFilter pattern with child pattern.
|
||||
* create a logicalBinary pattern.
|
||||
*/
|
||||
default <T extends Plan> PatternDescriptor<LogicalUnary<LogicalFilter, T>, Plan>
|
||||
logicalFilter(PatternDescriptor<T, Plan> childPattern) {
|
||||
return new PatternDescriptor<>(
|
||||
new Pattern<>(OperatorType.LOGICAL_FILTER, childPattern.pattern),
|
||||
default <LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends Plan>
|
||||
PatternDescriptor<LogicalBinaryPlan<LogicalBinaryOperator, LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE>, Plan>
|
||||
logicalBinary(
|
||||
PatternDescriptor<LEFT_CHILD_TYPE, Plan> leftChild,
|
||||
PatternDescriptor<RIGHT_CHILD_TYPE, Plan> rightChild) {
|
||||
return new PatternDescriptor(
|
||||
new TypePattern(LogicalBinaryPlan.class, leftChild.pattern, rightChild.pattern),
|
||||
defaultPromise()
|
||||
);
|
||||
}
|
||||
|
||||
/* abstract physical operator patterns */
|
||||
|
||||
/**
|
||||
* create a physicalLeaf pattern.
|
||||
*/
|
||||
default PatternDescriptor<PhysicalLeafPlan<PhysicalLeafOperator>, Plan> physicalLeaf() {
|
||||
return new PatternDescriptor(new TypePattern(PhysicalLeafPlan.class), defaultPromise());
|
||||
}
|
||||
|
||||
/**
|
||||
* create a physicalUnary pattern.
|
||||
*/
|
||||
default PatternDescriptor<PhysicalUnaryPlan<PhysicalUnaryOperator, Plan>, Plan> physicalUnary() {
|
||||
return new PatternDescriptor(new TypePattern(PhysicalUnaryPlan.class, Pattern.FIXED), defaultPromise());
|
||||
}
|
||||
|
||||
/**
|
||||
* create a physicalUnary pattern.
|
||||
*/
|
||||
default <C extends Plan> PatternDescriptor<PhysicalUnaryPlan<PhysicalUnaryOperator, C>, Plan>
|
||||
physicalUnary(PatternDescriptor<C, Plan> child) {
|
||||
return new PatternDescriptor(new TypePattern(PhysicalUnaryPlan.class, child.pattern), defaultPromise());
|
||||
}
|
||||
|
||||
/**
|
||||
* create a physicalBinary pattern.
|
||||
*/
|
||||
default PatternDescriptor<PhysicalBinaryPlan<PhysicalBinaryOperator, Plan, Plan>, Plan> physicalBinary() {
|
||||
return new PatternDescriptor(
|
||||
new TypePattern(PhysicalBinaryPlan.class, Pattern.FIXED, Pattern.FIXED),
|
||||
defaultPromise()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a logicalProject pattern.
|
||||
* create a physicalBinary pattern.
|
||||
*/
|
||||
default PatternDescriptor<LogicalUnary<LogicalProject, Plan>, Plan> logicalProject() {
|
||||
return new PatternDescriptor<>(
|
||||
new Pattern<>(OperatorType.LOGICAL_PROJECT, new Pattern<>(OperatorType.FIXED)),
|
||||
default <LEFT_CHILD_TYPE extends Plan, RIGHT_CHILD_TYPE extends Plan>
|
||||
PatternDescriptor<PhysicalBinaryPlan<PhysicalBinaryOperator, LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE>, Plan>
|
||||
physicalBinary(
|
||||
PatternDescriptor<LEFT_CHILD_TYPE, Plan> leftChild,
|
||||
PatternDescriptor<RIGHT_CHILD_TYPE, Plan> rightChild) {
|
||||
return new PatternDescriptor(
|
||||
new TypePattern(PhysicalBinaryPlan.class, leftChild.pattern, rightChild.pattern),
|
||||
defaultPromise()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a logicalProject pattern.
|
||||
* create a physicalScan pattern.
|
||||
*/
|
||||
default <T extends Plan> PatternDescriptor<LogicalUnary<LogicalProject, T>, Plan>
|
||||
logicalProject(PatternDescriptor<T, Plan> childPattern) {
|
||||
return new PatternDescriptor<>(
|
||||
new Pattern<>(OperatorType.LOGICAL_PROJECT, childPattern.pattern),
|
||||
defaultPromise()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a logicalJoin pattern.
|
||||
*/
|
||||
default PatternDescriptor<LogicalBinary<LogicalJoin, Plan, Plan>, Plan> logicalJoin() {
|
||||
return new PatternDescriptor<>(
|
||||
new Pattern<>(OperatorType.LOGICAL_JOIN,
|
||||
new Pattern<>(OperatorType.FIXED), new Pattern<>(OperatorType.FIXED)),
|
||||
defaultPromise()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a logicalJoin pattern with join type.
|
||||
*/
|
||||
default PatternDescriptor<LogicalBinary<LogicalJoin, Plan, Plan>, Plan> logicalJoin(JoinType joinType) {
|
||||
return new PatternDescriptor<LogicalBinary<LogicalJoin, Plan, Plan>, Plan>(
|
||||
new Pattern<>(OperatorType.LOGICAL_JOIN,
|
||||
new Pattern<>(OperatorType.FIXED), new Pattern<>(OperatorType.FIXED)),
|
||||
defaultPromise()
|
||||
).when(j -> j.operator.getJoinType() == joinType);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a logicalJoin pattern with joinType and children patterns.
|
||||
*/
|
||||
default <C1 extends Plan, C2 extends Plan>
|
||||
PatternDescriptor<LogicalBinary<LogicalJoin, C1, C2>, Plan> logicalJoin(
|
||||
JoinType joinType, PatternDescriptor<C1, Plan> leftChildPattern,
|
||||
PatternDescriptor<C2, Plan> rightChildPattern) {
|
||||
return new PatternDescriptor<LogicalBinary<LogicalJoin, C1, C2>, Plan>(
|
||||
new Pattern<>(OperatorType.LOGICAL_JOIN, leftChildPattern.pattern, rightChildPattern.pattern),
|
||||
defaultPromise()
|
||||
).when(j -> j.operator.getJoinType() == joinType);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a logicalJoin pattern with children patterns.
|
||||
*/
|
||||
default <C1 extends Plan, C2 extends Plan>
|
||||
PatternDescriptor<LogicalBinary<LogicalJoin, C1, C2>, Plan> logicalJoin(
|
||||
PatternDescriptor<C1, Plan> leftChildPattern, PatternDescriptor<C2, Plan> rightChildPattern) {
|
||||
return new PatternDescriptor<>(
|
||||
new Pattern<>(OperatorType.LOGICAL_JOIN, leftChildPattern.pattern, rightChildPattern.pattern),
|
||||
defaultPromise()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a logicalJoin pattern with joinType is inner.
|
||||
*/
|
||||
default PatternDescriptor<LogicalBinary<LogicalJoin, Plan, Plan>, Plan> innerLogicalJoin() {
|
||||
return new PatternDescriptor<LogicalBinary<LogicalJoin, Plan, Plan>, Plan>(
|
||||
new Pattern<>(OperatorType.LOGICAL_JOIN,
|
||||
new Pattern<>(OperatorType.FIXED), new Pattern<>(OperatorType.FIXED)),
|
||||
defaultPromise()
|
||||
).when(j -> j.operator.getJoinType() == JoinType.INNER_JOIN);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a logical join pattern with join type is inner and children patterns.
|
||||
*/
|
||||
default <C1 extends Plan, C2 extends Plan>
|
||||
PatternDescriptor<LogicalBinary<LogicalJoin, C1, C2>, Plan> innerLogicalJoin(
|
||||
PatternDescriptor<C1, Plan> leftChildPattern, PatternDescriptor<C2, Plan> rightChildPattern) {
|
||||
return new PatternDescriptor<LogicalBinary<LogicalJoin, C1, C2>, Plan>(
|
||||
new Pattern<>(OperatorType.LOGICAL_JOIN, leftChildPattern.pattern, rightChildPattern.pattern),
|
||||
defaultPromise()
|
||||
).when(j -> j.operator.getJoinType() == JoinType.INNER_JOIN);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a logicalRelation pattern.
|
||||
*/
|
||||
default PatternDescriptor<LogicalLeaf<LogicalRelation>, Plan> logicalRelation() {
|
||||
return new PatternDescriptor<>(
|
||||
new Pattern<>(OperatorType.LOGICAL_BOUND_RELATION),
|
||||
defaultPromise()
|
||||
);
|
||||
}
|
||||
|
||||
// physical pattern descriptors
|
||||
|
||||
/**
|
||||
* create a physicalFilter pattern.
|
||||
*/
|
||||
default PatternDescriptor<PhysicalUnary<PhysicalFilter, Plan>, Plan> physicalFilter() {
|
||||
return new PatternDescriptor<>(
|
||||
new Pattern<>(OperatorType.PHYSICAL_FILTER, new Pattern<>(OperatorType.FIXED)),
|
||||
defaultPromise()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a physicalFilter pattern with child pattern.
|
||||
*/
|
||||
default <T extends Plan> PatternDescriptor<PhysicalUnary<PhysicalFilter, T>, Plan>
|
||||
physicalFilter(PatternDescriptor<T, Plan> childPattern) {
|
||||
return new PatternDescriptor<>(
|
||||
new Pattern<>(OperatorType.PHYSICAL_FILTER, childPattern.pattern),
|
||||
defaultPromise()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a physicalProject pattern.
|
||||
*/
|
||||
default PatternDescriptor<PhysicalUnary<PhysicalProject, Plan>, Plan> physicalProject() {
|
||||
return new PatternDescriptor<>(
|
||||
new Pattern<>(OperatorType.PHYSICAL_PROJECT, new Pattern<>(OperatorType.FIXED)),
|
||||
defaultPromise()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a physicalProject pattern with child pattern.
|
||||
*/
|
||||
default <T extends Plan> PatternDescriptor<PhysicalUnary<PhysicalProject, T>, Plan>
|
||||
physicalProject(PatternDescriptor<T, Plan> childPattern) {
|
||||
return new PatternDescriptor<>(
|
||||
new Pattern<>(OperatorType.PHYSICAL_PROJECT, childPattern.pattern),
|
||||
defaultPromise()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a physicalBroadcastHashJoin pattern.
|
||||
*/
|
||||
default PatternDescriptor<PhysicalBinary<PhysicalBroadcastHashJoin, Plan, Plan>, Plan>
|
||||
physicalBroadcastHashJoin() {
|
||||
return new PatternDescriptor<>(
|
||||
new Pattern<>(OperatorType.PHYSICAL_BROADCAST_HASH_JOIN,
|
||||
new Pattern<>(OperatorType.FIXED), new Pattern<>(OperatorType.FIXED)),
|
||||
defaultPromise()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a physicalBroadcastHashJoin pattern with children patterns.
|
||||
*/
|
||||
default <C1 extends Plan, C2 extends Plan>
|
||||
PatternDescriptor<PhysicalBinary<PhysicalBroadcastHashJoin, C1, C2>, Plan>
|
||||
physicalBroadcastHashJoin(PatternDescriptor<C1, Plan> leftChildPattern,
|
||||
PatternDescriptor<C2, Plan> rightChildPattern) {
|
||||
return new PatternDescriptor<>(
|
||||
new Pattern<>(OperatorType.PHYSICAL_BROADCAST_HASH_JOIN,
|
||||
leftChildPattern.pattern,
|
||||
rightChildPattern.pattern
|
||||
),
|
||||
defaultPromise()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a physicalOlapScan pattern.
|
||||
*/
|
||||
default PatternDescriptor<PhysicalLeaf<PhysicalOlapScan>, Plan> physicalOlapScan() {
|
||||
return new PatternDescriptor<>(
|
||||
new Pattern<>(OperatorType.PHYSICAL_OLAP_SCAN),
|
||||
defaultPromise()
|
||||
);
|
||||
default PatternDescriptor<PhysicalLeafPlan<PhysicalScan>, Plan> physicalScan() {
|
||||
return new PatternDescriptor(new TypePattern(PhysicalScan.class), defaultPromise());
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,57 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern;
|
||||
|
||||
import org.apache.doris.nereids.operators.Operator;
|
||||
import org.apache.doris.nereids.operators.OperatorType;
|
||||
import org.apache.doris.nereids.trees.TreeNode;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/** pattern that used to match class type. */
|
||||
public class TypePattern<TYPE extends NODE_TYPE, NODE_TYPE extends TreeNode<NODE_TYPE>>
|
||||
extends Pattern<TYPE, NODE_TYPE> {
|
||||
protected final Class<TYPE> type;
|
||||
|
||||
public TypePattern(Class<TYPE> clazz, Pattern... children) {
|
||||
super(OperatorType.NORMAL_PATTERN, children);
|
||||
this.type = Objects.requireNonNull(clazz, "class can not be null");
|
||||
}
|
||||
|
||||
public TypePattern(Class<TYPE> clazz, List<Predicate<TYPE>> predicates, Pattern... children) {
|
||||
super(OperatorType.NORMAL_PATTERN, predicates, children);
|
||||
this.type = Objects.requireNonNull(clazz, "class can not be null");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean doMatchRoot(TYPE root) {
|
||||
return type.isInstance(root) && predicates.stream().allMatch(predicate -> predicate.test(root));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypePattern<TYPE, NODE_TYPE> withPredicates(List<Predicate<TYPE>> predicates) {
|
||||
return new TypePattern(type, predicates, children.toArray(new Pattern[0]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matchOperator(Operator operator) {
|
||||
return type.isInstance(operator);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,445 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator;
|
||||
|
||||
import org.apache.doris.nereids.JavaParser.ClassBodyDeclarationContext;
|
||||
import org.apache.doris.nereids.JavaParser.ClassDeclarationContext;
|
||||
import org.apache.doris.nereids.JavaParser.ClassOrInterfaceModifierContext;
|
||||
import org.apache.doris.nereids.JavaParser.ClassOrInterfaceTypeContext;
|
||||
import org.apache.doris.nereids.JavaParser.EnumConstantContext;
|
||||
import org.apache.doris.nereids.JavaParser.EnumDeclarationContext;
|
||||
import org.apache.doris.nereids.JavaParser.FieldDeclarationContext;
|
||||
import org.apache.doris.nereids.JavaParser.FormalParameterListContext;
|
||||
import org.apache.doris.nereids.JavaParser.IdentifierAndTypeArgumentsContext;
|
||||
import org.apache.doris.nereids.JavaParser.IdentifierContext;
|
||||
import org.apache.doris.nereids.JavaParser.ImportDeclarationContext;
|
||||
import org.apache.doris.nereids.JavaParser.InterfaceDeclarationContext;
|
||||
import org.apache.doris.nereids.JavaParser.MemberDeclarationContext;
|
||||
import org.apache.doris.nereids.JavaParser.MethodDeclarationContext;
|
||||
import org.apache.doris.nereids.JavaParser.PackageDeclarationContext;
|
||||
import org.apache.doris.nereids.JavaParser.PrimitiveTypeContext;
|
||||
import org.apache.doris.nereids.JavaParser.QualifiedNameContext;
|
||||
import org.apache.doris.nereids.JavaParser.TypeArgumentContext;
|
||||
import org.apache.doris.nereids.JavaParser.TypeArgumentsContext;
|
||||
import org.apache.doris.nereids.JavaParser.TypeBoundContext;
|
||||
import org.apache.doris.nereids.JavaParser.TypeDeclarationContext;
|
||||
import org.apache.doris.nereids.JavaParser.TypeListContext;
|
||||
import org.apache.doris.nereids.JavaParser.TypeParameterContext;
|
||||
import org.apache.doris.nereids.JavaParser.TypeParametersContext;
|
||||
import org.apache.doris.nereids.JavaParser.TypeTypeContext;
|
||||
import org.apache.doris.nereids.JavaParser.TypeTypeOrVoidContext;
|
||||
import org.apache.doris.nereids.JavaParser.VariableDeclaratorContext;
|
||||
import org.apache.doris.nereids.JavaParser.VariableDeclaratorIdContext;
|
||||
import org.apache.doris.nereids.JavaParser.VariableDeclaratorsContext;
|
||||
import org.apache.doris.nereids.JavaParserBaseVisitor;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.ClassDeclaration;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.ClassOrInterfaceModifier;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.ClassOrInterfaceType;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.EnumConstant;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.EnumDeclaration;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.FieldDeclaration;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.IdentifyTypeArgumentsPair;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.ImportDeclaration;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.InterfaceDeclaration;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.JavaAstNode;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.MethodDeclaration;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.QualifiedName;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.TypeArgument;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.TypeArgument.ArgType;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.TypeArguments;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.TypeBound;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.TypeDeclaration;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.TypeParameter;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.TypeParameters;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.TypeType;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.TypeTypeOrVoid;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.VariableDeclarator;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.VariableDeclaratorId;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.VariableDeclarators;
|
||||
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Stack;
|
||||
|
||||
/**
|
||||
* Used to build a copy from antlr ast.
|
||||
*/
|
||||
public class JavaAstBuilder extends JavaParserBaseVisitor<JavaAstNode> {
|
||||
Optional<QualifiedName> packageName = Optional.empty();
|
||||
List<ImportDeclaration> importDeclarations = new ArrayList<>();
|
||||
List<TypeDeclaration> rootTypeDeclarations = new ArrayList<>();
|
||||
Stack<List<TypeDeclaration>> childrenStack = new Stack<>();
|
||||
|
||||
public List<TypeDeclaration> build(ParserRuleContext tree) {
|
||||
visit(tree);
|
||||
return rootTypeDeclarations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaAstNode visitPackageDeclaration(PackageDeclarationContext ctx) {
|
||||
packageName = Optional.of(visitQualifiedName(ctx.qualifiedName()));
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImportDeclaration visitImportDeclaration(ImportDeclarationContext ctx) {
|
||||
ImportDeclaration importDeclaration = new ImportDeclaration(ctx.STATIC() != null,
|
||||
visitQualifiedName(ctx.qualifiedName()), ctx.importStar() != null);
|
||||
importDeclarations.add(importDeclaration);
|
||||
return importDeclaration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaAstNode visitTypeDeclaration(TypeDeclarationContext ctx) {
|
||||
ClassOrInterfaceModifier modifier = mergeModifiers(ctx.classOrInterfaceModifier());
|
||||
if (ctx.classDeclaration() != null) {
|
||||
return visitClassDeclaration(ctx.classDeclaration(), modifier);
|
||||
} else if (ctx.interfaceDeclaration() != null) {
|
||||
return visitInterfaceDeclaration(ctx.interfaceDeclaration(), modifier);
|
||||
} else if (ctx.enumDeclaration() != null) {
|
||||
return visitEnumDeclaration(ctx.enumDeclaration(), modifier);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/** create enum declaration. */
|
||||
public EnumDeclaration visitEnumDeclaration(EnumDeclarationContext ctx, ClassOrInterfaceModifier modifier) {
|
||||
List<TypeType> implementTypes = new ArrayList<>();
|
||||
if (ctx.IMPLEMENTS() != null) {
|
||||
implementTypes = getTypes(ctx.typeList());
|
||||
}
|
||||
|
||||
List<EnumConstant> enumConstants = new ArrayList<>();
|
||||
if (ctx.enumConstants() != null) {
|
||||
enumConstants = visit(EnumConstant.class, ctx.enumConstants().enumConstant());
|
||||
}
|
||||
|
||||
childrenStack.add(new ArrayList<>());
|
||||
if (ctx.enumBodyDeclarations() != null) {
|
||||
// find inner class
|
||||
ctx.enumBodyDeclarations().accept(this);
|
||||
}
|
||||
|
||||
String enumName = getText(ctx.identifier());
|
||||
EnumDeclaration enumDeclaration = new EnumDeclaration(packageName.orElse(null),
|
||||
importDeclarations, modifier, enumName, implementTypes, enumConstants, childrenStack.pop());
|
||||
addTypeDeclaration(enumDeclaration);
|
||||
|
||||
return enumDeclaration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumConstant visitEnumConstant(EnumConstantContext ctx) {
|
||||
return new EnumConstant(getText(ctx.identifier()));
|
||||
}
|
||||
|
||||
|
||||
/** create interface declaration. */
|
||||
public InterfaceDeclaration visitInterfaceDeclaration(
|
||||
InterfaceDeclarationContext ctx, ClassOrInterfaceModifier modifier) {
|
||||
TypeParameters typeParameters = null;
|
||||
if (ctx.typeParameters() != null) {
|
||||
typeParameters = visitTypeParameters(ctx.typeParameters());
|
||||
}
|
||||
List<TypeType> extendsTypes = new ArrayList<>();
|
||||
if (ctx.EXTENDS() != null) {
|
||||
extendsTypes = getTypes(ctx.typeList().get(0));
|
||||
}
|
||||
|
||||
childrenStack.add(new ArrayList<>());
|
||||
// find inner class
|
||||
ctx.interfaceBody().accept(this);
|
||||
|
||||
String interfaceName = getText(ctx.identifier());
|
||||
InterfaceDeclaration interfaceDeclaration = new InterfaceDeclaration(packageName.orElse(null),
|
||||
importDeclarations, modifier, interfaceName, typeParameters, extendsTypes, childrenStack.pop());
|
||||
addTypeDeclaration(interfaceDeclaration);
|
||||
|
||||
return interfaceDeclaration;
|
||||
}
|
||||
|
||||
|
||||
/** create class declaration. */
|
||||
public ClassDeclaration visitClassDeclaration(ClassDeclarationContext ctx, ClassOrInterfaceModifier modifier) {
|
||||
TypeParameters typeParameters = null;
|
||||
if (ctx.typeParameters() != null) {
|
||||
typeParameters = visitTypeParameters(ctx.typeParameters());
|
||||
}
|
||||
TypeType extendsType = null;
|
||||
if (ctx.EXTENDS() != null) {
|
||||
extendsType = visitTypeType(ctx.typeType());
|
||||
}
|
||||
List<TypeType> implementTypes = new ArrayList<>();
|
||||
if (ctx.IMPLEMENTS() != null) {
|
||||
implementTypes = getTypes(ctx.typeList().get(0));
|
||||
}
|
||||
|
||||
childrenStack.add(new ArrayList<>());
|
||||
List<FieldDeclaration> fieldDeclarations = new ArrayList<>();
|
||||
List<MethodDeclaration> methodDeclarations = new ArrayList<>();
|
||||
for (ClassBodyDeclarationContext classBodyCtx : ctx.classBody().classBodyDeclaration()) {
|
||||
MemberDeclarationContext memberCtx = classBodyCtx.memberDeclaration();
|
||||
if (memberCtx != null) {
|
||||
if (memberCtx.fieldDeclaration() != null) {
|
||||
fieldDeclarations.add(visitFieldDeclaration(memberCtx.fieldDeclaration()));
|
||||
continue;
|
||||
} else if (memberCtx.methodDeclaration() != null) {
|
||||
methodDeclarations.add(visitMethodDeclaration(memberCtx.methodDeclaration()));
|
||||
}
|
||||
}
|
||||
// find inner class
|
||||
memberCtx.accept(this);
|
||||
}
|
||||
|
||||
String className = getText(ctx.identifier());
|
||||
ClassDeclaration classDeclaration = new ClassDeclaration(
|
||||
packageName.orElse(null), importDeclarations,
|
||||
modifier, className, typeParameters, extendsType, implementTypes,
|
||||
fieldDeclarations, methodDeclarations, childrenStack.pop());
|
||||
addTypeDeclaration(classDeclaration);
|
||||
return classDeclaration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassOrInterfaceModifier visitClassOrInterfaceModifier(ClassOrInterfaceModifierContext ctx) {
|
||||
int mod = 0;
|
||||
if (ctx.PUBLIC() != null) {
|
||||
mod |= Modifier.PUBLIC;
|
||||
} else if (ctx.PROTECTED() != null) {
|
||||
mod |= Modifier.PROTECTED;
|
||||
} else if (ctx.PRIVATE() != null) {
|
||||
mod |= Modifier.PRIVATE;
|
||||
} else if (ctx.STATIC() != null) {
|
||||
mod |= Modifier.STATIC;
|
||||
} else if (ctx.ABSTRACT() != null) {
|
||||
mod |= Modifier.ABSTRACT;
|
||||
} else if (ctx.ABSTRACT() != null) {
|
||||
mod |= Modifier.FINAL;
|
||||
}
|
||||
return new ClassOrInterfaceModifier(mod);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldDeclaration visitFieldDeclaration(FieldDeclarationContext ctx) {
|
||||
TypeType typeType = visitTypeType(ctx.typeType());
|
||||
VariableDeclarators variableDeclarators = visitVariableDeclarators(ctx.variableDeclarators());
|
||||
return new FieldDeclaration(typeType, variableDeclarators);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodDeclaration visitMethodDeclaration(MethodDeclarationContext ctx) {
|
||||
TypeTypeOrVoid typeTypeOrVoid = visitTypeTypeOrVoid(ctx.typeTypeOrVoid());
|
||||
String identifier = getText(ctx.identifier());
|
||||
int paramNum = 0;
|
||||
FormalParameterListContext paramListCtx = ctx.formalParameters().formalParameterList();
|
||||
if (paramListCtx != null && paramListCtx.formalParameter() != null) {
|
||||
paramNum = paramListCtx.formalParameter().size() + 1; // + lastFormalParameter
|
||||
}
|
||||
return new MethodDeclaration(typeTypeOrVoid, identifier, paramNum);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeTypeOrVoid visitTypeTypeOrVoid(TypeTypeOrVoidContext ctx) {
|
||||
TypeType typeType = null;
|
||||
if (ctx.typeType() != null) {
|
||||
typeType = visitTypeType(ctx.typeType());
|
||||
}
|
||||
return new TypeTypeOrVoid(typeType, ctx.VOID() != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VariableDeclarators visitVariableDeclarators(VariableDeclaratorsContext ctx) {
|
||||
List<VariableDeclarator> vars = visit(VariableDeclarator.class, ctx.variableDeclarator());
|
||||
return new VariableDeclarators(vars);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VariableDeclarator visitVariableDeclarator(VariableDeclaratorContext ctx) {
|
||||
VariableDeclaratorId id = visitVariableDeclaratorId(ctx.variableDeclaratorId());
|
||||
return new VariableDeclarator(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VariableDeclaratorId visitVariableDeclaratorId(VariableDeclaratorIdContext ctx) {
|
||||
String text = getText(ctx.identifier());
|
||||
int arrayDimension = ctx.arrayDeclarator().size();
|
||||
return new VariableDeclaratorId(text, arrayDimension);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassOrInterfaceType visitClassOrInterfaceType(ClassOrInterfaceTypeContext ctx) {
|
||||
List<IdentifyTypeArgumentsPair> pairs = new ArrayList<>();
|
||||
for (IdentifierAndTypeArgumentsContext identifierAndTypeArgument : ctx.identifierAndTypeArguments()) {
|
||||
String identifier = getText(identifierAndTypeArgument.identifier());
|
||||
TypeArguments typeArguments = null;
|
||||
if (identifierAndTypeArgument.typeArguments() != null) {
|
||||
typeArguments = visitTypeArguments(identifierAndTypeArgument.typeArguments());
|
||||
}
|
||||
pairs.add(new IdentifyTypeArgumentsPair(identifier, typeArguments));
|
||||
}
|
||||
return new ClassOrInterfaceType(pairs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeParameters visitTypeParameters(TypeParametersContext ctx) {
|
||||
List<TypeParameter> typeParameters = new ArrayList<>();
|
||||
for (TypeParameterContext typeParameterContext : ctx.typeParameter()) {
|
||||
typeParameters.add(visitTypeParameter(typeParameterContext));
|
||||
}
|
||||
return new TypeParameters(typeParameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeParameter visitTypeParameter(TypeParameterContext ctx) {
|
||||
String identifier = getText(ctx.identifier());
|
||||
TypeBound typeBound = null;
|
||||
if (ctx.typeBound() != null) {
|
||||
typeBound = visitTypeBound(ctx.typeBound());
|
||||
}
|
||||
return new TypeParameter(identifier, typeBound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeBound visitTypeBound(TypeBoundContext ctx) {
|
||||
List<TypeType> typeParameters = new ArrayList<>();
|
||||
for (TypeTypeContext typeTypeContext : ctx.typeType()) {
|
||||
typeParameters.add(visitTypeType(typeTypeContext));
|
||||
}
|
||||
return new TypeBound(typeParameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeArguments visitTypeArguments(TypeArgumentsContext ctx) {
|
||||
List<TypeArgument> typeArguments = new ArrayList<>();
|
||||
for (TypeArgumentContext typeArgumentContext : ctx.typeArgument()) {
|
||||
typeArguments.add(visitTypeArgument(typeArgumentContext));
|
||||
}
|
||||
return new TypeArguments(typeArguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeArgument visitTypeArgument(TypeArgumentContext ctx) {
|
||||
TypeType typeType = null;
|
||||
ArgType argType = ArgType.UNKNOWN;
|
||||
if (ctx.typeType() != null) {
|
||||
typeType = visitTypeType(ctx.typeType());
|
||||
if (ctx.EXTENDS() != null) {
|
||||
argType = ArgType.EXTENDS;
|
||||
} else if (ctx.SUPER() != null) {
|
||||
argType = ArgType.SUPER;
|
||||
} else {
|
||||
argType = ArgType.NORMAL;
|
||||
}
|
||||
}
|
||||
return new TypeArgument(argType, typeType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeType visitTypeType(TypeTypeContext ctx) {
|
||||
ClassOrInterfaceType classOrInterfaceType = null;
|
||||
if (ctx.classOrInterfaceType() != null) {
|
||||
classOrInterfaceType = visitClassOrInterfaceType(ctx.classOrInterfaceType());
|
||||
}
|
||||
String primitiveType = null;
|
||||
if (ctx.primitiveType() != null) {
|
||||
primitiveType = getText(ctx.primitiveType());
|
||||
}
|
||||
return new TypeType(classOrInterfaceType, primitiveType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public QualifiedName visitQualifiedName(QualifiedNameContext ctx) {
|
||||
List<String> identifiers = new ArrayList<>();
|
||||
for (IdentifierContext identifierContext : ctx.identifier()) {
|
||||
identifiers.add(getText(identifierContext));
|
||||
}
|
||||
return new QualifiedName(identifiers);
|
||||
}
|
||||
|
||||
|
||||
/** merge modifiers, e.g public + static + final. */
|
||||
public ClassOrInterfaceModifier mergeModifiers(List<ClassOrInterfaceModifierContext> contexts) {
|
||||
int mod = 0;
|
||||
for (ClassOrInterfaceModifierContext context : contexts) {
|
||||
ClassOrInterfaceModifier modifier = visitClassOrInterfaceModifier(context);
|
||||
mod |= modifier.mod;
|
||||
}
|
||||
return new ClassOrInterfaceModifier(mod);
|
||||
}
|
||||
|
||||
|
||||
/** create a type list. */
|
||||
public List<TypeType> getTypes(TypeListContext typeListContext) {
|
||||
List<TypeType> types = new ArrayList<>();
|
||||
for (TypeTypeContext typeTypeContext : typeListContext.typeType()) {
|
||||
types.add(visitTypeType(typeTypeContext));
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
|
||||
/** create a List by class and contexts. */
|
||||
public <T extends JavaAstNode, C extends ParserRuleContext> List<T> visit(Class<T> clazz, List<C> contexts) {
|
||||
List<T> list = new ArrayList<>();
|
||||
for (C ctx : contexts) {
|
||||
list.add((T) ctx.accept(this));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public String getText(IdentifierContext ctx) {
|
||||
return ctx.getText();
|
||||
}
|
||||
|
||||
public String getText(PrimitiveTypeContext ctx) {
|
||||
return ctx.getText();
|
||||
}
|
||||
|
||||
private void addTypeDeclaration(TypeDeclaration typeDeclaration) {
|
||||
if (!childrenStack.isEmpty()) {
|
||||
childrenStack.peek().add(typeDeclaration);
|
||||
} else {
|
||||
rootTypeDeclarations.add(typeDeclaration);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** get full qualified name, e.g. OuterClassName.InnerClassName. */
|
||||
public static String getFullQualifiedName(Stack<String> outerClassStack,
|
||||
Optional<QualifiedName> packageName, String name) {
|
||||
if (!outerClassStack.isEmpty()) {
|
||||
return outerClassStack.peek() + "." + name;
|
||||
}
|
||||
return TypeDeclaration.getFullQualifiedName(packageName, name);
|
||||
}
|
||||
|
||||
class OuterClass {
|
||||
public final Optional<QualifiedName> packageName;
|
||||
public final String name;
|
||||
|
||||
public OuterClass(Optional<QualifiedName> packageName, String name) {
|
||||
this.packageName = packageName;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator;
|
||||
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.ClassDeclaration;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/** used to generate pattern for LogicalBinaryOperator. */
|
||||
public class LogicalBinaryPatternGenerator extends PatternGenerator {
|
||||
|
||||
public LogicalBinaryPatternGenerator(PatternGeneratorAnalyzer analyzer,
|
||||
ClassDeclaration opType, Set<String> parentClass) {
|
||||
super(analyzer, opType, parentClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String genericType() {
|
||||
return "<LogicalBinaryPlan<" + opType.name + ", Plan, Plan>, Plan>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String genericTypeWithChildren() {
|
||||
return "<LogicalBinaryPlan<" + opType.name + ", C1, C2>, Plan>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getImports() {
|
||||
Set<String> imports = new TreeSet<>();
|
||||
imports.add(opType.getFullQualifiedName());
|
||||
imports.add("org.apache.doris.nereids.operators.OperatorType");
|
||||
imports.add("org.apache.doris.nereids.trees.plans.Plan");
|
||||
imports.add("org.apache.doris.nereids.trees.plans.logical.LogicalBinaryPlan");
|
||||
enumFieldPatternInfos.stream()
|
||||
.map(info -> info.enumFullName)
|
||||
.forEach(imports::add);
|
||||
return imports;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLogical() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int childrenNum() {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator;
|
||||
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.ClassDeclaration;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/** used to generate pattern for LogicalLeafOperator. */
|
||||
public class LogicalLeafPatternGenerator extends PatternGenerator {
|
||||
|
||||
public LogicalLeafPatternGenerator(PatternGeneratorAnalyzer analyzer,
|
||||
ClassDeclaration opType, Set<String> parentClass) {
|
||||
super(analyzer, opType, parentClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generate() {
|
||||
String opClassName = opType.name;
|
||||
String methodName = getPatternMethodName();
|
||||
|
||||
String patternParam = "<LogicalLeafPlan<" + opClassName + ">, Plan>";
|
||||
|
||||
generateTypePattern(methodName, opClassName, patternParam, "", false);
|
||||
|
||||
for (EnumFieldPatternInfo info : enumFieldPatternInfos) {
|
||||
String predicate = ".when(p -> p.operator." + info.enumInstanceGetter + "() == "
|
||||
+ info.enumType + "." + info.enumInstance + ")";
|
||||
generateTypePattern(info.patternName, opClassName, patternParam, predicate, false);
|
||||
}
|
||||
|
||||
return generatePatterns();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String genericType() {
|
||||
return "<LogicalLeafPlan<" + opType.name + ">, Plan>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String genericTypeWithChildren() {
|
||||
throw new IllegalStateException("Can not get children generic type by LogicalLeafPlan");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getImports() {
|
||||
Set<String> imports = new TreeSet<>();
|
||||
imports.add(opType.getFullQualifiedName());
|
||||
imports.add("org.apache.doris.nereids.trees.plans.Plan");
|
||||
imports.add("org.apache.doris.nereids.trees.plans.logical.LogicalLeafPlan");
|
||||
enumFieldPatternInfos.stream()
|
||||
.map(info -> info.enumFullName)
|
||||
.forEach(imports::add);
|
||||
return imports;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLogical() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int childrenNum() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator;
|
||||
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.ClassDeclaration;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/** used to generate pattern for LogicalUnaryOperator. */
|
||||
public class LogicalUnaryPatternGenerator extends PatternGenerator {
|
||||
|
||||
public LogicalUnaryPatternGenerator(PatternGeneratorAnalyzer analyzer,
|
||||
ClassDeclaration opType, Set<String> parentClass) {
|
||||
super(analyzer, opType, parentClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String genericType() {
|
||||
return "<LogicalUnaryPlan<" + opType.name + ", Plan>, Plan>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String genericTypeWithChildren() {
|
||||
return "<LogicalUnaryPlan<" + opType.name + ", C1>, Plan>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getImports() {
|
||||
Set<String> imports = new TreeSet<>();
|
||||
imports.add(opType.getFullQualifiedName());
|
||||
imports.add("org.apache.doris.nereids.operators.OperatorType");
|
||||
imports.add("org.apache.doris.nereids.trees.plans.Plan");
|
||||
imports.add("org.apache.doris.nereids.trees.plans.logical.LogicalUnaryPlan");
|
||||
enumFieldPatternInfos.stream()
|
||||
.map(info -> info.enumFullName)
|
||||
.forEach(imports::add);
|
||||
return imports;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLogical() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int childrenNum() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/** used to trigger PatternDescribableProcessor. */
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface PatternDescribable {
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator;
|
||||
|
||||
/** just for process entry point. */
|
||||
@PatternDescribable
|
||||
public class PatternDescribableProcessPoint {
|
||||
}
|
||||
@ -0,0 +1,157 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator;
|
||||
|
||||
import org.apache.doris.nereids.JavaLexer;
|
||||
import org.apache.doris.nereids.JavaParser;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.TypeDeclaration;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import org.antlr.v4.runtime.CharStreams;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.DefaultErrorStrategy;
|
||||
import org.antlr.v4.runtime.InputMismatchException;
|
||||
import org.antlr.v4.runtime.Parser;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.RecognitionException;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.atn.PredictionMode;
|
||||
import org.antlr.v4.runtime.misc.ParseCancellationException;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.processing.AbstractProcessor;
|
||||
import javax.annotation.processing.ProcessingEnvironment;
|
||||
import javax.annotation.processing.RoundEnvironment;
|
||||
import javax.annotation.processing.SupportedAnnotationTypes;
|
||||
import javax.annotation.processing.SupportedSourceVersion;
|
||||
import javax.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.tools.Diagnostic.Kind;
|
||||
import javax.tools.StandardLocation;
|
||||
|
||||
/**
|
||||
* annotation processor for generate GeneratedPattern.java.
|
||||
*/
|
||||
@SupportedSourceVersion(SourceVersion.RELEASE_8)
|
||||
@SupportedAnnotationTypes("org.apache.doris.nereids.pattern.generator.PatternDescribable")
|
||||
public class PatternDescribableProcessor extends AbstractProcessor {
|
||||
private List<File> operatorPaths;
|
||||
|
||||
@Override
|
||||
public synchronized void init(ProcessingEnvironment processingEnv) {
|
||||
super.init(processingEnv);
|
||||
this.operatorPaths = Arrays.stream(processingEnv.getOptions().get("operatorPath").split(","))
|
||||
.map(path -> path.trim())
|
||||
.filter(path -> !path.isEmpty())
|
||||
.collect(Collectors.toSet())
|
||||
.stream()
|
||||
.map(path -> new File(path))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||
if (annotations.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
List<File> operatorFiles = findJavaFiles(operatorPaths);
|
||||
PatternGeneratorAnalyzer patternGeneratorAnalyzer = new PatternGeneratorAnalyzer();
|
||||
for (File file : operatorFiles) {
|
||||
List<TypeDeclaration> asts = parseJavaFile(file);
|
||||
patternGeneratorAnalyzer.addAsts(asts);
|
||||
}
|
||||
String generatePatternCode = patternGeneratorAnalyzer.generatePatterns();
|
||||
File generatePatternFile = new File(processingEnv.getFiler()
|
||||
.getResource(StandardLocation.SOURCE_OUTPUT, "org.apache.doris.nereids.pattern",
|
||||
"GeneratedPatterns.java").toUri());
|
||||
if (generatePatternFile.exists()) {
|
||||
generatePatternFile.delete();
|
||||
}
|
||||
if (!generatePatternFile.getParentFile().exists()) {
|
||||
generatePatternFile.getParentFile().mkdirs();
|
||||
}
|
||||
|
||||
// bypass create file for processingEnv.getFiler(), compile GeneratePatterns in next compile term
|
||||
try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(generatePatternFile))) {
|
||||
bufferedWriter.write(generatePatternCode);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
String exceptionMsg = Throwables.getStackTraceAsString(t);
|
||||
processingEnv.getMessager().printMessage(Kind.ERROR,
|
||||
"Analyze and generate patterns failed:\n" + exceptionMsg);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private List<File> findJavaFiles(List<File> dirs) {
|
||||
List<File> files = new ArrayList<>();
|
||||
for (File dir : dirs) {
|
||||
files.addAll(FileUtils.listFiles(dir, new String[] {"java"}, true));
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
private List<TypeDeclaration> parseJavaFile(File javaFile) throws IOException {
|
||||
String javaCodeString = FileUtils.readFileToString(javaFile, StandardCharsets.UTF_8);
|
||||
JavaLexer lexer = new JavaLexer(CharStreams.fromString(javaCodeString));
|
||||
|
||||
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
|
||||
JavaParser parser = new JavaParser(tokenStream);
|
||||
parser.setErrorHandler(new DefaultErrorStrategy() {
|
||||
@Override
|
||||
public Token recoverInline(Parser recognizer) throws RecognitionException {
|
||||
if (nextTokensContext == null) {
|
||||
throw new InputMismatchException(recognizer);
|
||||
} else {
|
||||
throw new InputMismatchException(recognizer, nextTokensState, nextTokensContext);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// parser.addParseListener(PostProcessor)
|
||||
// parser.removeErrorListeners()
|
||||
// parser.addErrorListener(ParseErrorListener)
|
||||
|
||||
ParserRuleContext tree;
|
||||
try {
|
||||
// first, try parsing with potentially faster SLL mode
|
||||
parser.getInterpreter().setPredictionMode(PredictionMode.SLL);
|
||||
tree = parser.compilationUnit();
|
||||
} catch (ParseCancellationException ex) {
|
||||
// if we fail, parse with LL mode
|
||||
tokenStream.seek(0); // rewind input stream
|
||||
parser.reset();
|
||||
|
||||
parser.getInterpreter().setPredictionMode(PredictionMode.LL);
|
||||
tree = parser.compilationUnit();
|
||||
}
|
||||
|
||||
return new JavaAstBuilder().build(tree);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,325 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator;
|
||||
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.ClassDeclaration;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.EnumConstant;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.EnumDeclaration;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.FieldDeclaration;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.MethodDeclaration;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.VariableDeclarator;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import org.apache.commons.lang.math.IntRange;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/** used to generate pattern by operator. */
|
||||
public abstract class PatternGenerator {
|
||||
protected final PatternGeneratorAnalyzer analyzer;
|
||||
protected final ClassDeclaration opType;
|
||||
protected final Set<String> parentClass;
|
||||
protected final List<EnumFieldPatternInfo> enumFieldPatternInfos;
|
||||
protected final List<String> generatePatterns = new ArrayList<>();
|
||||
|
||||
/** constructor. */
|
||||
public PatternGenerator(PatternGeneratorAnalyzer analyzer, ClassDeclaration opType, Set<String> parentClass) {
|
||||
this.analyzer = analyzer;
|
||||
this.opType = opType;
|
||||
this.parentClass = parentClass;
|
||||
this.enumFieldPatternInfos = getEnumFieldPatternInfos();
|
||||
}
|
||||
|
||||
public abstract String genericType();
|
||||
|
||||
public abstract String genericTypeWithChildren();
|
||||
|
||||
public abstract Set<String> getImports();
|
||||
|
||||
public abstract boolean isLogical();
|
||||
|
||||
public abstract int childrenNum();
|
||||
|
||||
public String getPatternMethodName() {
|
||||
return opType.name.substring(0, 1).toLowerCase(Locale.ENGLISH) + opType.name.substring(1);
|
||||
}
|
||||
|
||||
/** generate code by generators and analyzer. */
|
||||
public static String generateCode(List<PatternGenerator> generators, PatternGeneratorAnalyzer analyzer) {
|
||||
String generateCode
|
||||
= "// Licensed to the Apache Software Foundation (ASF) under one\n"
|
||||
+ "// or more contributor license agreements. See the NOTICE file\n"
|
||||
+ "// distributed with this work for additional information\n"
|
||||
+ "// regarding copyright ownership. The ASF licenses this file\n"
|
||||
+ "// to you under the Apache License, Version 2.0 (the\n"
|
||||
+ "// \"License\"); you may not use this file except in compliance\n"
|
||||
+ "// with the License. You may obtain a copy of the License at\n"
|
||||
+ "//\n"
|
||||
+ "// http://www.apache.org/licenses/LICENSE-2.0\n"
|
||||
+ "//\n"
|
||||
+ "// Unless required by applicable law or agreed to in writing,\n"
|
||||
+ "// software distributed under the License is distributed on an\n"
|
||||
+ "// \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n"
|
||||
+ "// KIND, either express or implied. See the License for the\n"
|
||||
+ "// specific language governing permissions and limitations\n"
|
||||
+ "// under the License.\n"
|
||||
+ "\n"
|
||||
+ "package org.apache.doris.nereids.pattern;\n"
|
||||
+ "\n"
|
||||
+ generateImports(generators)
|
||||
+ "\n";
|
||||
|
||||
generateCode += "public interface GeneratedPatterns extends Patterns {\n";
|
||||
generateCode += generators.stream()
|
||||
.map(generator -> {
|
||||
String patternMethods = generator.generate();
|
||||
// add indent
|
||||
return Arrays.stream(patternMethods.split("\n"))
|
||||
.map(line -> " " + line + "\n")
|
||||
.collect(Collectors.joining(""));
|
||||
}).collect(Collectors.joining("\n"));
|
||||
return generateCode + "}\n";
|
||||
}
|
||||
|
||||
protected List<EnumFieldPatternInfo> getEnumFieldPatternInfos() {
|
||||
List<EnumFieldPatternInfo> enumFieldInfos = new ArrayList<>();
|
||||
for (Entry<FieldDeclaration, EnumDeclaration> pair : findEnumFieldType()) {
|
||||
FieldDeclaration fieldDecl = pair.getKey();
|
||||
EnumDeclaration enumDecl = pair.getValue();
|
||||
|
||||
Set<String> enumClassNameParts = splitCase(enumDecl.name)
|
||||
.stream()
|
||||
.map(part -> part.toLowerCase(Locale.ENGLISH))
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
for (VariableDeclarator varDecl : fieldDecl.variableDeclarators.variableDeclarators) {
|
||||
String enumFieldName = varDecl.variableDeclaratorId.identifier;
|
||||
Optional<String> getter = findGetter(enumDecl.name, enumFieldName);
|
||||
if (getter.isPresent()) {
|
||||
for (EnumConstant constant : enumDecl.constants) {
|
||||
String enumInstance = constant.identifier;
|
||||
String enumPatternName = getEnumPatternName(enumInstance, enumClassNameParts) + opType.name;
|
||||
|
||||
enumFieldInfos.add(new EnumFieldPatternInfo(enumPatternName,
|
||||
enumDecl.getFullQualifiedName(), enumDecl.name, enumInstance, getter.get()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return enumFieldInfos;
|
||||
}
|
||||
|
||||
protected Optional<String> findGetter(String type, String name) {
|
||||
String getterName = "get" + name.substring(0, 1).toUpperCase(Locale.ENGLISH) + name.substring(1);
|
||||
for (MethodDeclaration methodDecl : opType.methodDeclarations) {
|
||||
if (methodDecl.typeTypeOrVoid.isVoid) {
|
||||
continue;
|
||||
}
|
||||
if (methodDecl.typeTypeOrVoid.typeType.isPresent()
|
||||
&& methodDecl.typeTypeOrVoid.typeType.get().toString().equals(type)) {
|
||||
if (methodDecl.identifier.equals(getterName) && methodDecl.paramNum == 0) {
|
||||
return Optional.of(getterName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
protected String getEnumPatternName(String enumInstance, Set<String> enumClassNameParts) {
|
||||
String[] instanceNameParts = enumInstance.split("_+");
|
||||
List<String> newParts = new ArrayList<>();
|
||||
|
||||
boolean isFirst = true;
|
||||
for (int i = 0; i < instanceNameParts.length; i++) {
|
||||
String part = instanceNameParts[i].toLowerCase(Locale.ENGLISH);
|
||||
// skip instanceNameParts, e.g. INNER_JOIN has two part: [inner and Join].
|
||||
// because 'Join' is the part of the 'JoinType' enum className, so skip 'Join' and return 'inner'
|
||||
if (part.isEmpty() || enumClassNameParts.contains(part)) {
|
||||
continue;
|
||||
}
|
||||
if (!isFirst) {
|
||||
newParts.add(part.substring(0, 1).toUpperCase(Locale.ENGLISH) + part.substring(1));
|
||||
} else {
|
||||
newParts.add(part.substring(0, 1).toLowerCase(Locale.ENGLISH) + part.substring(1));
|
||||
}
|
||||
isFirst = false;
|
||||
}
|
||||
|
||||
return Joiner.on("").join(newParts);
|
||||
}
|
||||
|
||||
protected List<Map.Entry<FieldDeclaration, EnumDeclaration>> findEnumFieldType() {
|
||||
return opType.fieldDeclarations
|
||||
.stream()
|
||||
.map(f -> new SimpleEntry<>(f, analyzer.getType(opType, f.type)))
|
||||
.filter(pair -> pair.getValue().isPresent() && pair.getValue().get() instanceof EnumDeclaration)
|
||||
.map(pair -> new SimpleEntry<>(pair.getKey(), (EnumDeclaration) (pair.getValue().get())))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
// e.g. split PhysicalBroadcastHashJoin to [Physical, Broadcast, Hash, Join]
|
||||
// e.g. split JoinType to [Join, Type]
|
||||
protected List<String> splitCase(String name) {
|
||||
Pattern pattern = Pattern.compile("([A-Z]+[^A-Z]*)");
|
||||
Matcher matcher = pattern.matcher(name);
|
||||
List<String> parts = new ArrayList<>();
|
||||
while (matcher.find()) {
|
||||
parts.add(matcher.group(0));
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
|
||||
/** create generator by operator's type. */
|
||||
public static Optional<PatternGenerator> create(PatternGeneratorAnalyzer analyzer,
|
||||
ClassDeclaration opType, Set<String> parentClass) {
|
||||
if (parentClass.contains("org.apache.doris.nereids.operators.plans.logical.LogicalLeafOperator")) {
|
||||
return Optional.of(new LogicalLeafPatternGenerator(analyzer, opType, parentClass));
|
||||
} else if (parentClass.contains("org.apache.doris.nereids.operators.plans.logical.LogicalUnaryOperator")) {
|
||||
return Optional.of(new LogicalUnaryPatternGenerator(analyzer, opType, parentClass));
|
||||
} else if (parentClass.contains("org.apache.doris.nereids.operators.plans.logical.LogicalBinaryOperator")) {
|
||||
return Optional.of(new LogicalBinaryPatternGenerator(analyzer, opType, parentClass));
|
||||
} else if (parentClass.contains("org.apache.doris.nereids.operators.plans.physical.PhysicalLeafOperator")) {
|
||||
return Optional.of(new PhysicalLeafPatternGenerator(analyzer, opType, parentClass));
|
||||
} else if (parentClass.contains("org.apache.doris.nereids.operators.plans.physical.PhysicalUnaryOperator")) {
|
||||
return Optional.of(new PhysicalUnaryPatternGenerator(analyzer, opType, parentClass));
|
||||
} else if (parentClass.contains("org.apache.doris.nereids.operators.plans.physical.PhysicalBinaryOperator")) {
|
||||
return Optional.of(new PhysicalBinaryPatternGenerator(analyzer, opType, parentClass));
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
private static String generateImports(List<PatternGenerator> generators) {
|
||||
Set<String> imports = new HashSet<>();
|
||||
for (PatternGenerator generator : generators) {
|
||||
imports.addAll(generator.getImports());
|
||||
}
|
||||
List<String> sortedImports = new ArrayList<>(imports);
|
||||
sortedImports.sort(Comparator.naturalOrder());
|
||||
|
||||
return sortedImports.stream()
|
||||
.map(it -> "import " + it + ";\n")
|
||||
.collect(Collectors.joining(""));
|
||||
}
|
||||
|
||||
/** generate some pattern method code. */
|
||||
public String generate() {
|
||||
String opClassName = opType.name;
|
||||
String methodName = getPatternMethodName();
|
||||
|
||||
generateTypePattern(methodName, opClassName, genericType(), "", false);
|
||||
if (childrenNum() > 0) {
|
||||
generateTypePattern(methodName, opClassName, genericTypeWithChildren(), "", true);
|
||||
}
|
||||
|
||||
for (EnumFieldPatternInfo info : enumFieldPatternInfos) {
|
||||
String predicate = ".when(p -> p.operator." + info.enumInstanceGetter + "() == "
|
||||
+ info.enumType + "." + info.enumInstance + ")";
|
||||
generateTypePattern(info.patternName, opClassName, genericType(), predicate, false);
|
||||
if (childrenNum() > 0) {
|
||||
generateTypePattern(info.patternName, opClassName, genericTypeWithChildren(), predicate, true);
|
||||
}
|
||||
}
|
||||
return generatePatterns();
|
||||
}
|
||||
|
||||
/** generate a pattern method code. */
|
||||
public String generateTypePattern(String patterName, String className,
|
||||
String genericParam, String predicate, boolean specifyChildren) {
|
||||
|
||||
int childrenNum = childrenNum();
|
||||
|
||||
if (specifyChildren) {
|
||||
String methodGeneric = Arrays.stream(new IntRange(1, childrenNum).toArray())
|
||||
.mapToObj(i -> "C" + i + " extends Plan")
|
||||
.collect(Collectors.joining(", ", "<", ">"));
|
||||
|
||||
String methodParam = Arrays.stream(new IntRange(1, childrenNum).toArray())
|
||||
.mapToObj(i -> "PatternDescriptor<C" + i + ", Plan> child" + i)
|
||||
.collect(Collectors.joining(", "));
|
||||
|
||||
String childrenPattern = Arrays.stream(new IntRange(1, childrenNum).toArray())
|
||||
.mapToObj(i -> "child" + i + ".pattern")
|
||||
.collect(Collectors.joining(", "));
|
||||
if (childrenNum > 0) {
|
||||
childrenPattern = ", " + childrenPattern;
|
||||
}
|
||||
|
||||
String pattern = "default " + methodGeneric + "\n"
|
||||
+ "PatternDescriptor" + genericParam + "\n"
|
||||
+ " " + patterName + "(" + methodParam + ") {\n"
|
||||
+ " return new PatternDescriptor" + genericParam + "(\n"
|
||||
+ " new TypePattern(" + className + ".class" + childrenPattern + "),\n"
|
||||
+ " defaultPromise()\n"
|
||||
+ " )" + predicate + ";\n"
|
||||
+ "}\n";
|
||||
generatePatterns.add(pattern);
|
||||
return pattern;
|
||||
} else {
|
||||
String childrenPattern = StringUtils.repeat("Pattern.FIXED", ", ", childrenNum);
|
||||
if (childrenNum > 0) {
|
||||
childrenPattern = ", " + childrenPattern;
|
||||
}
|
||||
|
||||
String pattern = "default PatternDescriptor" + genericParam + " " + patterName + "() {\n"
|
||||
+ " return new PatternDescriptor" + genericParam + "(\n"
|
||||
+ " new TypePattern(" + className + ".class" + childrenPattern + "),\n"
|
||||
+ " defaultPromise()\n"
|
||||
+ " )" + predicate + ";\n"
|
||||
+ "}\n";
|
||||
generatePatterns.add(pattern);
|
||||
return pattern;
|
||||
}
|
||||
}
|
||||
|
||||
public String generatePatterns() {
|
||||
return generatePatterns.stream().collect(Collectors.joining("\n"));
|
||||
}
|
||||
|
||||
static class EnumFieldPatternInfo {
|
||||
public final String patternName;
|
||||
public final String enumFullName;
|
||||
public final String enumType;
|
||||
public final String enumInstance;
|
||||
public final String enumInstanceGetter;
|
||||
|
||||
public EnumFieldPatternInfo(String patternName, String enumFullName, String enumType,
|
||||
String enumInstance, String enumInstanceGetter) {
|
||||
this.patternName = patternName;
|
||||
this.enumFullName = enumFullName;
|
||||
this.enumType = enumType;
|
||||
this.enumInstance = enumInstance;
|
||||
this.enumInstanceGetter = enumInstanceGetter;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,226 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator;
|
||||
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.ClassDeclaration;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.ClassOrInterfaceType;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.EnumDeclaration;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.IdentifyTypeArgumentsPair;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.ImportDeclaration;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.InterfaceDeclaration;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.QualifiedName;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.TypeDeclaration;
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.TypeType;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* used to analyze operator class extends hierarchy and then generated pattern builder methods.
|
||||
*/
|
||||
public class PatternGeneratorAnalyzer {
|
||||
private final Map<String, TypeDeclaration> name2Ast = new LinkedHashMap<>();
|
||||
private final IdentityHashMap<TypeDeclaration, String> ast2Name = new IdentityHashMap<>();
|
||||
private final IdentityHashMap<TypeDeclaration, Map<String, String>> ast2Import = new IdentityHashMap<>();
|
||||
private final IdentityHashMap<TypeDeclaration, Set<String>> parentClassMap = new IdentityHashMap<>();
|
||||
|
||||
/** add java AST. */
|
||||
public void addAsts(List<TypeDeclaration> typeDeclarations) {
|
||||
for (TypeDeclaration typeDeclaration : typeDeclarations) {
|
||||
addAst(Optional.empty(), typeDeclaration);
|
||||
}
|
||||
}
|
||||
|
||||
/** generate pattern methods. */
|
||||
public String generatePatterns() {
|
||||
analyzeImport();
|
||||
analyzeParentClass();
|
||||
return doGenerate();
|
||||
}
|
||||
|
||||
Optional<TypeDeclaration> getType(TypeDeclaration typeDeclaration, TypeType type) {
|
||||
String typeName = analyzeClass(new LinkedHashSet<>(), typeDeclaration, type);
|
||||
if (typeName != null) {
|
||||
TypeDeclaration ast = name2Ast.get(typeName);
|
||||
return Optional.ofNullable(ast);
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private String doGenerate() {
|
||||
Map<ClassDeclaration, Set<String>> planOpClassMap = parentClassMap.entrySet().stream()
|
||||
.filter(kv -> kv.getValue().contains("org.apache.doris.nereids.operators.plans.PlanOperator"))
|
||||
.filter(kv -> !Modifier.isAbstract(kv.getKey().modifiers.mod)
|
||||
&& kv.getKey() instanceof ClassDeclaration)
|
||||
.collect(Collectors.toMap(kv -> (ClassDeclaration) kv.getKey(), kv -> kv.getValue()));
|
||||
|
||||
List<PatternGenerator> generators = planOpClassMap.entrySet()
|
||||
.stream()
|
||||
.map(kv -> PatternGenerator.create(this, kv.getKey(), kv.getValue()))
|
||||
.filter(generator -> generator.isPresent())
|
||||
.map(Optional::get)
|
||||
.sorted((g1, g2) -> {
|
||||
// logical first
|
||||
if (g1.isLogical() != g2.isLogical()) {
|
||||
return g1.isLogical() ? -1 : 1;
|
||||
}
|
||||
// leaf first
|
||||
if (g1.childrenNum() != g2.childrenNum()) {
|
||||
return g1.childrenNum() - g2.childrenNum();
|
||||
}
|
||||
// string dict sort
|
||||
return g1.opType.name.compareTo(g2.opType.name);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return PatternGenerator.generateCode(generators, this);
|
||||
}
|
||||
|
||||
private void analyzeImport() {
|
||||
for (TypeDeclaration typeDeclaration : name2Ast.values()) {
|
||||
Map<String, String> imports = new LinkedHashMap<>();
|
||||
for (ImportDeclaration importDeclaration : typeDeclaration.imports) {
|
||||
QualifiedName name = importDeclaration.name;
|
||||
if (!importDeclaration.isStatic && !importDeclaration.importAll
|
||||
&& name.suffix().isPresent()) {
|
||||
String importName = Joiner.on(".").join(name.identifiers);
|
||||
imports.put(name.suffix().get(), importName);
|
||||
}
|
||||
}
|
||||
ast2Import.put(typeDeclaration, imports);
|
||||
}
|
||||
}
|
||||
|
||||
private void analyzeParentClass() {
|
||||
for (TypeDeclaration typeDeclaration : name2Ast.values()) {
|
||||
analyzeParentClass(new LinkedHashSet<>(), typeDeclaration);
|
||||
}
|
||||
}
|
||||
|
||||
private void analyzeParentClass(Set<String> parentClasses, TypeDeclaration typeDeclaration) {
|
||||
Set<String> currentParentClasses = new LinkedHashSet<>();
|
||||
if (typeDeclaration instanceof InterfaceDeclaration) {
|
||||
for (TypeType extendsType : ((InterfaceDeclaration) typeDeclaration).extendsTypes) {
|
||||
analyzeClass(currentParentClasses, typeDeclaration, extendsType);
|
||||
}
|
||||
} else if (typeDeclaration instanceof EnumDeclaration) {
|
||||
for (TypeType implementType : ((EnumDeclaration) typeDeclaration).implementTypes) {
|
||||
analyzeClass(currentParentClasses, typeDeclaration, implementType);
|
||||
}
|
||||
} else if (typeDeclaration instanceof ClassDeclaration) {
|
||||
ClassDeclaration classDeclaration = (ClassDeclaration) typeDeclaration;
|
||||
if (classDeclaration.extendsType.isPresent()) {
|
||||
analyzeClass(currentParentClasses, typeDeclaration, classDeclaration.extendsType.get());
|
||||
}
|
||||
if (!classDeclaration.implementTypes.isEmpty()) {
|
||||
for (TypeType implementType : classDeclaration.implementTypes) {
|
||||
analyzeClass(currentParentClasses, typeDeclaration, implementType);
|
||||
}
|
||||
}
|
||||
}
|
||||
parentClassMap.put(typeDeclaration, currentParentClasses);
|
||||
parentClasses.addAll(currentParentClasses);
|
||||
}
|
||||
|
||||
String analyzeClass(Set<String> parentClasses, TypeDeclaration typeDeclaration, TypeType type) {
|
||||
if (type.classOrInterfaceType.isPresent()) {
|
||||
List<String> identifiers = new ArrayList<>();
|
||||
ClassOrInterfaceType classOrInterfaceType = type.classOrInterfaceType.get();
|
||||
for (IdentifyTypeArgumentsPair identifyTypeArgument : classOrInterfaceType.identifyTypeArguments) {
|
||||
identifiers.add(identifyTypeArgument.identifier);
|
||||
}
|
||||
String className = Joiner.on(".").join(identifiers);
|
||||
|
||||
if (analyzeIfExist(parentClasses, className)) {
|
||||
parentClasses.add(className);
|
||||
return className;
|
||||
}
|
||||
Optional<String> importName = findFullImportName(typeDeclaration, className);
|
||||
if (importName.isPresent() && analyzeIfExist(parentClasses, importName.get())) {
|
||||
parentClasses.add(importName.get());
|
||||
return importName.get();
|
||||
}
|
||||
if (typeDeclaration.packageName.isPresent()) {
|
||||
String currentPackageClass = Joiner.on(".")
|
||||
.join(typeDeclaration.packageName.get().identifiers) + "." + className;
|
||||
if (analyzeIfExist(parentClasses, currentPackageClass)) {
|
||||
parentClasses.add(currentPackageClass);
|
||||
return currentPackageClass;
|
||||
}
|
||||
}
|
||||
parentClasses.add(className);
|
||||
return className;
|
||||
} else if (type.primitiveType.isPresent()) {
|
||||
parentClasses.add(type.primitiveType.get());
|
||||
return type.primitiveType.get();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean analyzeIfExist(Set<String> parentClasses, String name) {
|
||||
if (name2Ast.get(name) != null) {
|
||||
analyzeParentClass(parentClasses, name2Ast.get(name));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<String> findFullImportName(TypeDeclaration typeDeclaration, String name) {
|
||||
Map<String, String> name2FullName = ast2Import.get(typeDeclaration);
|
||||
if (name2FullName != null && name2FullName.get(name) != null) {
|
||||
return Optional.of(name2FullName.get(name));
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private void addAst(Optional<String> outerClassName, TypeDeclaration typeDeclaration) {
|
||||
String nameWithOuterClass;
|
||||
if (!outerClassName.isPresent()) {
|
||||
nameWithOuterClass = typeDeclaration.name;
|
||||
String fullQualifiedName = typeDeclaration.getFullQualifiedName();
|
||||
name2Ast.put(fullQualifiedName, typeDeclaration);
|
||||
ast2Name.put(typeDeclaration, fullQualifiedName);
|
||||
} else if (typeDeclaration.packageName.isPresent()) {
|
||||
nameWithOuterClass = outerClassName.get() + "." + typeDeclaration.name;
|
||||
String fullName = typeDeclaration.packageName.get() + "." + nameWithOuterClass;
|
||||
name2Ast.put(fullName, typeDeclaration);
|
||||
ast2Name.put(typeDeclaration, fullName);
|
||||
} else {
|
||||
nameWithOuterClass = outerClassName.get() + "." + typeDeclaration.name;
|
||||
name2Ast.put(nameWithOuterClass, typeDeclaration);
|
||||
ast2Name.put(typeDeclaration, nameWithOuterClass);
|
||||
}
|
||||
|
||||
for (TypeDeclaration child : typeDeclaration.children) {
|
||||
addAst(Optional.of(nameWithOuterClass), child);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,66 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator;
|
||||
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.ClassDeclaration;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
|
||||
/** used to generate pattern for PhysicalBinaryOperator. */
|
||||
public class PhysicalBinaryPatternGenerator extends PatternGenerator {
|
||||
|
||||
public PhysicalBinaryPatternGenerator(PatternGeneratorAnalyzer analyzer,
|
||||
ClassDeclaration opType, Set<String> parentClass) {
|
||||
super(analyzer, opType, parentClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String genericType() {
|
||||
return "<PhysicalBinaryPlan<" + opType.name + ", Plan, Plan>, Plan>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String genericTypeWithChildren() {
|
||||
return "<PhysicalBinaryPlan<" + opType.name + ", C1, C2>, Plan>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getImports() {
|
||||
Set<String> imports = new TreeSet<>();
|
||||
imports.add(opType.getFullQualifiedName());
|
||||
imports.add("org.apache.doris.nereids.operators.OperatorType");
|
||||
imports.add("org.apache.doris.nereids.trees.plans.Plan");
|
||||
imports.add("org.apache.doris.nereids.trees.plans.physical.PhysicalBinaryPlan");
|
||||
enumFieldPatternInfos.stream()
|
||||
.map(info -> info.enumFullName)
|
||||
.forEach(imports::add);
|
||||
return imports;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLogical() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int childrenNum() {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator;
|
||||
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.ClassDeclaration;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/** used to generate pattern for PhysicalLeafOperator. */
|
||||
public class PhysicalLeafPatternGenerator extends PatternGenerator {
|
||||
|
||||
public PhysicalLeafPatternGenerator(PatternGeneratorAnalyzer analyzer,
|
||||
ClassDeclaration opType, Set<String> parentClass) {
|
||||
super(analyzer, opType, parentClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String genericType() {
|
||||
return "<PhysicalLeafPlan<" + opType.name + ">, Plan>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String genericTypeWithChildren() {
|
||||
throw new IllegalStateException("Can not get children generic type by PhysicalLeafPlan");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getImports() {
|
||||
Set<String> imports = new TreeSet<>();
|
||||
imports.add(opType.getFullQualifiedName());
|
||||
imports.add("org.apache.doris.nereids.trees.plans.Plan");
|
||||
imports.add("org.apache.doris.nereids.trees.plans.physical.PhysicalLeafPlan");
|
||||
enumFieldPatternInfos.stream()
|
||||
.map(info -> info.enumFullName)
|
||||
.forEach(imports::add);
|
||||
return imports;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLogical() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int childrenNum() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator;
|
||||
|
||||
import org.apache.doris.nereids.pattern.generator.javaast.ClassDeclaration;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/** used to generate pattern for PhysicalUnaryOperator. */
|
||||
public class PhysicalUnaryPatternGenerator extends PatternGenerator {
|
||||
|
||||
public PhysicalUnaryPatternGenerator(PatternGeneratorAnalyzer analyzer,
|
||||
ClassDeclaration opType, Set<String> parentClass) {
|
||||
super(analyzer, opType, parentClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String genericType() {
|
||||
return "<PhysicalUnaryPlan<" + opType.name + ", Plan>, Plan>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String genericTypeWithChildren() {
|
||||
return "<PhysicalUnaryPlan<" + opType.name + ", C1>, Plan>";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getImports() {
|
||||
Set<String> imports = new TreeSet<>();
|
||||
imports.add(opType.getFullQualifiedName());
|
||||
imports.add("org.apache.doris.nereids.operators.OperatorType");
|
||||
imports.add("org.apache.doris.nereids.trees.plans.Plan");
|
||||
imports.add("org.apache.doris.nereids.trees.plans.physical.PhysicalUnaryPlan");
|
||||
enumFieldPatternInfos.stream()
|
||||
.map(info -> info.enumFullName)
|
||||
.forEach(imports::add);
|
||||
return imports;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLogical() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int childrenNum() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,88 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator.javaast;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
/** java's class declaration. */
|
||||
public class ClassDeclaration extends TypeDeclaration {
|
||||
public final Optional<TypeType> extendsType;
|
||||
public final Optional<TypeParameters> typeParameters;
|
||||
public final List<TypeType> implementTypes;
|
||||
public final List<FieldDeclaration> fieldDeclarations;
|
||||
public final List<MethodDeclaration> methodDeclarations;
|
||||
|
||||
/** constructor. */
|
||||
public ClassDeclaration(QualifiedName packageName, List<ImportDeclaration> imports,
|
||||
ClassOrInterfaceModifier modifier, String name, TypeParameters typeParameters,
|
||||
TypeType extendsType, List<TypeType> implementTypes,
|
||||
List<FieldDeclaration> fieldDeclarations, List<MethodDeclaration> methodDeclarations,
|
||||
List<TypeDeclaration> children) {
|
||||
super(packageName, imports, modifier, name, children);
|
||||
this.typeParameters = Optional.ofNullable(typeParameters);
|
||||
this.extendsType = Optional.ofNullable(extendsType);
|
||||
this.implementTypes = ImmutableList.copyOf(implementTypes);
|
||||
this.fieldDeclarations = ImmutableList.copyOf(fieldDeclarations);
|
||||
this.methodDeclarations = ImmutableList.copyOf(methodDeclarations);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
if (packageName.isPresent()) {
|
||||
buffer.append("package ").append(packageName.get()).append(";\n\n");
|
||||
}
|
||||
|
||||
if (!imports.isEmpty()) {
|
||||
for (ImportDeclaration importDeclaration : imports) {
|
||||
buffer.append(importDeclaration).append("\n");
|
||||
}
|
||||
buffer.append("\n");
|
||||
}
|
||||
|
||||
String mod = modifiers.toString();
|
||||
if (!mod.isEmpty()) {
|
||||
mod += " ";
|
||||
}
|
||||
buffer.append(mod).append("class ").append(name);
|
||||
if (typeParameters.isPresent()) {
|
||||
buffer.append(typeParameters.get());
|
||||
}
|
||||
buffer.append(" ");
|
||||
if (extendsType.isPresent()) {
|
||||
buffer.append("extends ").append(extendsType.get()).append(" ");
|
||||
}
|
||||
if (!implementTypes.isEmpty()) {
|
||||
buffer.append("implements ").append(Joiner.on(", ").join(implementTypes)).append(" ");
|
||||
}
|
||||
buffer.append("{\n");
|
||||
for (FieldDeclaration fieldDeclaration : fieldDeclarations) {
|
||||
buffer.append(" ").append(fieldDeclaration).append("\n");
|
||||
}
|
||||
for (MethodDeclaration methodDeclaration : methodDeclarations) {
|
||||
buffer.append(" ").append(methodDeclaration).append("\n");
|
||||
}
|
||||
buffer.append("}\n");
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator.javaast;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/** java's class or interface's modifiers. */
|
||||
public class ClassOrInterfaceModifier implements JavaAstNode {
|
||||
public final int mod;
|
||||
|
||||
public ClassOrInterfaceModifier(int mod) {
|
||||
this.mod = mod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
List<String> modifiers = new ArrayList<>(3);
|
||||
if (Modifier.isPublic(mod)) {
|
||||
modifiers.add("public");
|
||||
} else if (Modifier.isProtected(mod)) {
|
||||
modifiers.add("protected");
|
||||
} else if (Modifier.isPrivate(mod)) {
|
||||
modifiers.add("private");
|
||||
}
|
||||
|
||||
if (Modifier.isStatic(mod)) {
|
||||
modifiers.add("static");
|
||||
}
|
||||
|
||||
if (Modifier.isAbstract(mod)) {
|
||||
modifiers.add("abstract");
|
||||
} else if (Modifier.isFinal(mod)) {
|
||||
modifiers.add("final");
|
||||
}
|
||||
return Joiner.on(" ").join(modifiers);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator.javaast;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/** java class or interface's type. */
|
||||
public class ClassOrInterfaceType implements JavaAstNode {
|
||||
public final List<IdentifyTypeArgumentsPair> identifyTypeArguments;
|
||||
|
||||
public ClassOrInterfaceType(List<IdentifyTypeArgumentsPair> identifyTypeArguments) {
|
||||
this.identifyTypeArguments = ImmutableList.copyOf(identifyTypeArguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Joiner.on(".").join(identifyTypeArguments);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator.javaast;
|
||||
|
||||
|
||||
/** java enum instance. */
|
||||
public class EnumConstant implements JavaAstNode {
|
||||
public final String identifier;
|
||||
|
||||
public EnumConstant(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return identifier;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,67 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator.javaast;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** java's enum declaration. */
|
||||
public class EnumDeclaration extends TypeDeclaration {
|
||||
public final List<TypeType> implementTypes;
|
||||
public final List<EnumConstant> constants;
|
||||
|
||||
/** constructor. */
|
||||
public EnumDeclaration(QualifiedName packageName, List<ImportDeclaration> imports,
|
||||
ClassOrInterfaceModifier modifier, String name, List<TypeType> implementTypes,
|
||||
List<EnumConstant> constants, List<TypeDeclaration> children) {
|
||||
super(packageName, imports, modifier, name, children);
|
||||
this.implementTypes = ImmutableList.copyOf(implementTypes);
|
||||
this.constants = ImmutableList.copyOf(constants);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
if (packageName.isPresent()) {
|
||||
buffer.append("package ").append(packageName.get()).append(";\n\n");
|
||||
}
|
||||
|
||||
if (!imports.isEmpty()) {
|
||||
for (ImportDeclaration importDeclaration : imports) {
|
||||
buffer.append(importDeclaration).append("\n");
|
||||
}
|
||||
buffer.append("\n");
|
||||
}
|
||||
String mod = modifiers.toString();
|
||||
if (!mod.isEmpty()) {
|
||||
mod += " ";
|
||||
}
|
||||
buffer.append(mod).append("enum ").append(name).append(" ");
|
||||
if (!implementTypes.isEmpty()) {
|
||||
buffer.append("implements ").append(Joiner.on(", ").join(implementTypes)).append(" ");
|
||||
}
|
||||
buffer.append("{\n");
|
||||
if (!constants.isEmpty()) {
|
||||
buffer.append(" ").append(Joiner.on(", ").join(constants)).append(";\n");
|
||||
}
|
||||
buffer.append("}\n");
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator.javaast;
|
||||
|
||||
/** java class field declaration. */
|
||||
public class FieldDeclaration extends MemberDeclaration {
|
||||
public final TypeType type;
|
||||
public final VariableDeclarators variableDeclarators;
|
||||
|
||||
public FieldDeclaration(TypeType type, VariableDeclarators variableDeclarators) {
|
||||
this.type = type;
|
||||
this.variableDeclarators = variableDeclarators;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return type + " " + variableDeclarators + ";";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator.javaast;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
/** java's identify type and type arguments. */
|
||||
public class IdentifyTypeArgumentsPair implements JavaAstNode {
|
||||
public final String identifier;
|
||||
public final Optional<TypeArguments> typeArguments;
|
||||
|
||||
public IdentifyTypeArgumentsPair(String identifier, TypeArguments typeArguments) {
|
||||
this.identifier = identifier;
|
||||
this.typeArguments = Optional.ofNullable(typeArguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (typeArguments.isPresent()) {
|
||||
return identifier + typeArguments.get();
|
||||
} else {
|
||||
return identifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator.javaast;
|
||||
|
||||
|
||||
/** java import declaration. */
|
||||
public class ImportDeclaration implements JavaAstNode {
|
||||
public final boolean isStatic;
|
||||
public final QualifiedName name;
|
||||
public final boolean importAll;
|
||||
|
||||
/** import declaration constructor. */
|
||||
public ImportDeclaration(boolean isStatic, QualifiedName name, boolean importAll) {
|
||||
this.isStatic = isStatic;
|
||||
this.name = name;
|
||||
this.importAll = importAll;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "import " + (isStatic ? "static " : "") + name + (importAll ? ".*" : "") + ";";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator.javaast;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/** java's interface declaration. */
|
||||
public class InterfaceDeclaration extends TypeDeclaration {
|
||||
public final Optional<TypeParameters> typeParameters;
|
||||
public final List<TypeType> extendsTypes;
|
||||
|
||||
/** constructor. */
|
||||
public InterfaceDeclaration(QualifiedName packageName, List<ImportDeclaration> imports,
|
||||
ClassOrInterfaceModifier modifier, String name, TypeParameters typeParameters,
|
||||
List<TypeType> extendsTypes, List<TypeDeclaration> children) {
|
||||
super(packageName, imports, modifier, name, children);
|
||||
this.typeParameters = Optional.ofNullable(typeParameters);
|
||||
this.extendsTypes = ImmutableList.copyOf(extendsTypes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
if (packageName.isPresent()) {
|
||||
buffer.append("package ").append(packageName.get()).append(";\n\n");
|
||||
}
|
||||
|
||||
if (!imports.isEmpty()) {
|
||||
for (ImportDeclaration importDeclaration : imports) {
|
||||
buffer.append(importDeclaration).append("\n");
|
||||
}
|
||||
buffer.append("\n");
|
||||
}
|
||||
String mod = modifiers.toString();
|
||||
if (!mod.isEmpty()) {
|
||||
mod += " ";
|
||||
}
|
||||
buffer.append(mod).append("interface ").append(name);
|
||||
if (typeParameters.isPresent()) {
|
||||
buffer.append(typeParameters.get());
|
||||
}
|
||||
buffer.append(" ");
|
||||
if (!extendsTypes.isEmpty()) {
|
||||
buffer.append("extends ").append(Joiner.on(", ").join(extendsTypes)).append(" ");
|
||||
}
|
||||
buffer.append("{}");
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator.javaast;
|
||||
|
||||
|
||||
/** java ast base interface. */
|
||||
public interface JavaAstNode {
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator.javaast;
|
||||
|
||||
/** java's member declaration. */
|
||||
public class MemberDeclaration implements JavaAstNode {}
|
||||
@ -0,0 +1,37 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator.javaast;
|
||||
|
||||
/** java's method declaration. */
|
||||
public class MethodDeclaration extends MemberDeclaration {
|
||||
public final TypeTypeOrVoid typeTypeOrVoid;
|
||||
public final String identifier;
|
||||
public final int paramNum;
|
||||
|
||||
/** constructor. */
|
||||
public MethodDeclaration(TypeTypeOrVoid typeTypeOrVoid, String identifier, int paramNum) {
|
||||
this.typeTypeOrVoid = typeTypeOrVoid;
|
||||
this.identifier = identifier;
|
||||
this.paramNum = paramNum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return typeTypeOrVoid.toString() + " " + identifier + "();";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator.javaast;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
/** java's qualified name. */
|
||||
public class QualifiedName implements JavaAstNode {
|
||||
public final List<String> identifiers;
|
||||
|
||||
public QualifiedName(List<String> identifiers) {
|
||||
this.identifiers = ImmutableList.copyOf(identifiers);
|
||||
}
|
||||
|
||||
public boolean suffixIs(String name) {
|
||||
return !identifiers.isEmpty() && identifiers.get(identifiers.size() - 1).equals(name);
|
||||
}
|
||||
|
||||
/** get suffix name. */
|
||||
public Optional<String> suffix() {
|
||||
if (identifiers.isEmpty()) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
return Optional.of(identifiers.get(identifiers.size() - 1));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Joiner.on(".").join(identifiers);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator.javaast;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
/** java generic type argument. */
|
||||
public class TypeArgument implements JavaAstNode {
|
||||
/** generic type. */
|
||||
public enum ArgType {
|
||||
NORMAL, EXTENDS, SUPER, UNKNOWN
|
||||
}
|
||||
|
||||
private final ArgType argType;
|
||||
private final Optional<TypeType> typeType;
|
||||
|
||||
public TypeArgument(ArgType argType, TypeType typeType) {
|
||||
this.argType = argType;
|
||||
this.typeType = Optional.ofNullable(typeType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
switch (argType) {
|
||||
case NORMAL:
|
||||
return typeType.get().toString();
|
||||
case EXTENDS:
|
||||
return "? extends " + typeType.get();
|
||||
case SUPER:
|
||||
return "? super " + typeType.get();
|
||||
case UNKNOWN:
|
||||
return "?";
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unknown argument type: " + argType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator.javaast;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/** java's type arguments. */
|
||||
public class TypeArguments implements JavaAstNode {
|
||||
public final List<TypeArgument> typeArguments;
|
||||
|
||||
public TypeArguments(List<TypeArgument> typeArguments) {
|
||||
this.typeArguments = ImmutableList.copyOf(typeArguments);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "<" + Joiner.on(", ").join(typeArguments) + ">";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator.javaast;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/** java's type bound. */
|
||||
public class TypeBound implements JavaAstNode {
|
||||
public final List<TypeType> types;
|
||||
|
||||
public TypeBound(List<TypeType> types) {
|
||||
this.types = ImmutableList.copyOf(types);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Joiner.on(" & ").join(types);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator.javaast;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
/** java's type declaration. */
|
||||
public abstract class TypeDeclaration implements JavaAstNode {
|
||||
public final Optional<QualifiedName> packageName;
|
||||
public final List<ImportDeclaration> imports;
|
||||
public final ClassOrInterfaceModifier modifiers;
|
||||
public final String name;
|
||||
public final List<TypeDeclaration> children;
|
||||
|
||||
/** type declaration's constructor. */
|
||||
public TypeDeclaration(QualifiedName packageName, List<ImportDeclaration> imports,
|
||||
ClassOrInterfaceModifier modifiers, String name, List<TypeDeclaration> children) {
|
||||
this.packageName = Optional.ofNullable(packageName);
|
||||
this.imports = ImmutableList.copyOf(imports);
|
||||
this.modifiers = modifiers;
|
||||
this.name = name;
|
||||
this.children = ImmutableList.copyOf(children);
|
||||
}
|
||||
|
||||
public String getFullQualifiedName() {
|
||||
return getFullQualifiedName(packageName, name);
|
||||
}
|
||||
|
||||
/** function to concat package name and type name. */
|
||||
public static String getFullQualifiedName(Optional<QualifiedName> packageName, String name) {
|
||||
if (packageName.isPresent()) {
|
||||
return Joiner.on(".").join(packageName.get().identifiers) + "." + name;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator.javaast;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
/** java's type. */
|
||||
public class TypeParameter implements JavaAstNode {
|
||||
public final String identifier;
|
||||
public final Optional<TypeBound> typeBound;
|
||||
|
||||
public TypeParameter(String identifier, TypeBound typeBound) {
|
||||
this.identifier = identifier;
|
||||
this.typeBound = Optional.ofNullable(typeBound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (typeBound.isPresent()) {
|
||||
return identifier + " extends " + typeBound.get();
|
||||
} else {
|
||||
return identifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator.javaast;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/** java's types. */
|
||||
public class TypeParameters implements JavaAstNode {
|
||||
public final List<TypeParameter> typeParameters;
|
||||
|
||||
public TypeParameters(List<TypeParameter> typeParameters) {
|
||||
this.typeParameters = ImmutableList.copyOf(typeParameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "<" + Joiner.on(", ").join(typeParameters) + ">";
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator.javaast;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/** java's type. */
|
||||
public class TypeType implements JavaAstNode {
|
||||
public final Optional<ClassOrInterfaceType> classOrInterfaceType;
|
||||
public final Optional<String> primitiveType;
|
||||
|
||||
public TypeType(ClassOrInterfaceType classOrInterfaceType, String primitiveType) {
|
||||
this.classOrInterfaceType = Optional.ofNullable(classOrInterfaceType);
|
||||
this.primitiveType = Optional.ofNullable(primitiveType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (primitiveType.isPresent()) {
|
||||
return primitiveType.get();
|
||||
} else {
|
||||
return classOrInterfaceType.get().toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator.javaast;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
/** java's type or void. */
|
||||
public class TypeTypeOrVoid implements JavaAstNode {
|
||||
public final Optional<TypeType> typeType;
|
||||
public final boolean isVoid;
|
||||
|
||||
public TypeTypeOrVoid(TypeType typeType, boolean isVoid) {
|
||||
this.typeType = Optional.ofNullable(typeType);
|
||||
this.isVoid = isVoid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return isVoid ? "void" : typeType.get().toString();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator.javaast;
|
||||
|
||||
|
||||
/** java variable's declarator. */
|
||||
public class VariableDeclarator implements JavaAstNode {
|
||||
public final VariableDeclaratorId variableDeclaratorId;
|
||||
|
||||
public VariableDeclarator(VariableDeclaratorId variableDeclaratorId) {
|
||||
this.variableDeclaratorId = variableDeclaratorId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return variableDeclaratorId.toString();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator.javaast;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
|
||||
/** java's variable. */
|
||||
public class VariableDeclaratorId implements JavaAstNode {
|
||||
public final String identifier;
|
||||
public final int arrayDimension;
|
||||
|
||||
public VariableDeclaratorId(String identifier, int arrayDimension) {
|
||||
this.identifier = identifier;
|
||||
this.arrayDimension = arrayDimension;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return identifier + StringUtils.repeat("[]", arrayDimension);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.doris.nereids.pattern.generator.javaast;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/** java's variable declarators. */
|
||||
public class VariableDeclarators implements JavaAstNode {
|
||||
public final List<VariableDeclarator> variableDeclarators;
|
||||
|
||||
public VariableDeclarators(List<VariableDeclarator> variableDeclarators) {
|
||||
this.variableDeclarators = ImmutableList.copyOf(variableDeclarators);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Joiner.on(", ").join(variableDeclarators);
|
||||
}
|
||||
}
|
||||
@ -26,7 +26,7 @@ import java.util.List;
|
||||
/**
|
||||
* abstract class for all rule factories build one rule.
|
||||
*/
|
||||
public abstract class OneRuleFactory<TYPE extends TreeNode> implements RuleFactory<TYPE> {
|
||||
public abstract class OneRuleFactory<TYPE extends TreeNode<TYPE>> implements RuleFactory<TYPE> {
|
||||
@Override
|
||||
public final List<Rule<TYPE>> buildRules() {
|
||||
return ImmutableList.of(build());
|
||||
|
||||
@ -28,9 +28,9 @@ import java.util.List;
|
||||
/**
|
||||
* Abstract class for all rules.
|
||||
*/
|
||||
public abstract class Rule<TYPE extends TreeNode> {
|
||||
public abstract class Rule<TYPE extends TreeNode<TYPE>> {
|
||||
private final RuleType ruleType;
|
||||
private final Pattern pattern;
|
||||
private final Pattern<? extends TYPE, TYPE> pattern;
|
||||
private final RulePromise rulePromise;
|
||||
|
||||
/**
|
||||
@ -40,7 +40,7 @@ public abstract class Rule<TYPE extends TreeNode> {
|
||||
* @param pattern target pattern of rule
|
||||
* @param rulePromise rule promise
|
||||
*/
|
||||
public Rule(RuleType ruleType, Pattern pattern, RulePromise rulePromise) {
|
||||
public Rule(RuleType ruleType, Pattern<? extends TYPE, TYPE> pattern, RulePromise rulePromise) {
|
||||
this.ruleType = ruleType;
|
||||
this.pattern = pattern;
|
||||
this.rulePromise = rulePromise;
|
||||
@ -54,7 +54,7 @@ public abstract class Rule<TYPE extends TreeNode> {
|
||||
return rulePromise;
|
||||
}
|
||||
|
||||
public Pattern getPattern() {
|
||||
public Pattern<? extends TYPE, TYPE> getPattern() {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
|
||||
package org.apache.doris.nereids.rules;
|
||||
|
||||
import org.apache.doris.nereids.pattern.Patterns;
|
||||
import org.apache.doris.nereids.pattern.GeneratedPatterns;
|
||||
import org.apache.doris.nereids.trees.TreeNode;
|
||||
|
||||
import java.util.List;
|
||||
@ -25,7 +25,7 @@ import java.util.List;
|
||||
/**
|
||||
* interface for all rule factories for build some rules.
|
||||
*/
|
||||
public interface RuleFactory<TYPE extends TreeNode> extends Patterns {
|
||||
public interface RuleFactory<TYPE extends TreeNode<TYPE>> extends GeneratedPatterns {
|
||||
// need implement
|
||||
List<Rule<TYPE>> buildRules();
|
||||
|
||||
|
||||
@ -62,7 +62,7 @@ public class RuleSet {
|
||||
return new RuleFactories();
|
||||
}
|
||||
|
||||
private static class RuleFactories<TYPE extends TreeNode> {
|
||||
private static class RuleFactories<TYPE extends TreeNode<TYPE>> {
|
||||
final Builder<Rule<TYPE>> rules = ImmutableList.builder();
|
||||
|
||||
public RuleFactories<TYPE> add(RuleFactory<TYPE> ruleFactory) {
|
||||
|
||||
@ -22,7 +22,7 @@ import org.apache.doris.nereids.rules.Rule;
|
||||
import org.apache.doris.nereids.rules.RuleType;
|
||||
import org.apache.doris.nereids.rules.exploration.OneExplorationRuleFactory;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalBinary;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalBinaryPlan;
|
||||
|
||||
|
||||
/**
|
||||
@ -39,8 +39,8 @@ public class JoinExchange extends OneExplorationRuleFactory {
|
||||
@Override
|
||||
public Rule<Plan> build() {
|
||||
return innerLogicalJoin(innerLogicalJoin(), innerLogicalJoin()).then(topJoin -> {
|
||||
LogicalBinary<LogicalJoin, Plan, Plan> leftJoin = topJoin.left();
|
||||
LogicalBinary<LogicalJoin, Plan, Plan> rightJoin = topJoin.right();
|
||||
LogicalBinaryPlan<LogicalJoin, Plan, Plan> leftJoin = topJoin.left();
|
||||
LogicalBinaryPlan<LogicalJoin, Plan, Plan> rightJoin = topJoin.right();
|
||||
|
||||
Plan a = leftJoin.left();
|
||||
Plan b = leftJoin.right();
|
||||
|
||||
@ -22,7 +22,7 @@ import org.apache.doris.nereids.rules.Rule;
|
||||
import org.apache.doris.nereids.rules.RuleType;
|
||||
import org.apache.doris.nereids.rules.exploration.OneExplorationRuleFactory;
|
||||
import org.apache.doris.nereids.trees.plans.Plan;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalBinary;
|
||||
import org.apache.doris.nereids.trees.plans.logical.LogicalBinaryPlan;
|
||||
|
||||
/**
|
||||
* Rule for change inner join left associative to right.
|
||||
@ -38,7 +38,7 @@ public class JoinLAsscom extends OneExplorationRuleFactory {
|
||||
@Override
|
||||
public Rule<Plan> build() {
|
||||
return innerLogicalJoin(innerLogicalJoin(), any()).then(topJoin -> {
|
||||
LogicalBinary<LogicalJoin, Plan, Plan> bottomJoin = topJoin.left();
|
||||
LogicalBinaryPlan<LogicalJoin, Plan, Plan> bottomJoin = topJoin.left();
|
||||
|
||||
Plan a = bottomJoin.left();
|
||||
Plan b = bottomJoin.right();
|
||||
|
||||
@ -24,6 +24,7 @@ import org.apache.doris.nereids.operators.Operator;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Abstract class for plan node in Nereids, include plan node and expression.
|
||||
@ -31,17 +32,17 @@ import java.util.List;
|
||||
* @param <NODE_TYPE> either {@link org.apache.doris.nereids.trees.plans.Plan}
|
||||
* or {@link org.apache.doris.nereids.trees.expressions.Expression}
|
||||
*/
|
||||
public abstract class AbstractTreeNode<NODE_TYPE extends AbstractTreeNode<NODE_TYPE>>
|
||||
public abstract class AbstractTreeNode<NODE_TYPE extends TreeNode<NODE_TYPE>>
|
||||
implements TreeNode<NODE_TYPE> {
|
||||
|
||||
protected final NodeType type;
|
||||
protected final List<TreeNode> children;
|
||||
protected final List<NODE_TYPE> children;
|
||||
// TODO: Maybe we should use a GroupPlan to avoid TreeNode hold the GroupExpression.
|
||||
// https://github.com/apache/incubator-doris/pull/9807#discussion_r884829067
|
||||
protected final GroupExpression groupExpression;
|
||||
protected final Optional<GroupExpression> groupExpression;
|
||||
|
||||
|
||||
public AbstractTreeNode(NodeType type, TreeNode... children) {
|
||||
public AbstractTreeNode(NodeType type, NODE_TYPE... children) {
|
||||
this(type, null, children);
|
||||
}
|
||||
|
||||
@ -52,10 +53,10 @@ public abstract class AbstractTreeNode<NODE_TYPE extends AbstractTreeNode<NODE_T
|
||||
* @param groupExpression group expression related to the operator of this node
|
||||
* @param children children of this node
|
||||
*/
|
||||
public AbstractTreeNode(NodeType type, GroupExpression groupExpression, TreeNode... children) {
|
||||
public AbstractTreeNode(NodeType type, GroupExpression groupExpression, NODE_TYPE... children) {
|
||||
this.type = type;
|
||||
this.children = ImmutableList.copyOf(children);
|
||||
this.groupExpression = groupExpression;
|
||||
this.groupExpression = Optional.ofNullable(groupExpression);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -64,13 +65,18 @@ public abstract class AbstractTreeNode<NODE_TYPE extends AbstractTreeNode<NODE_T
|
||||
}
|
||||
|
||||
@Override
|
||||
public GroupExpression getGroupExpression() {
|
||||
public Optional<GroupExpression> getGroupExpression() {
|
||||
return groupExpression;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NODE_TYPE newChildren(List<TreeNode> children) {
|
||||
throw new RuntimeException();
|
||||
public NODE_TYPE child(int index) {
|
||||
return children.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NODE_TYPE> children() {
|
||||
return children;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -78,16 +84,6 @@ public abstract class AbstractTreeNode<NODE_TYPE extends AbstractTreeNode<NODE_T
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <CHILD_TYPE extends TreeNode> List<CHILD_TYPE> children() {
|
||||
return (List) children;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <CHILD_TYPE extends TreeNode> CHILD_TYPE child(int index) {
|
||||
return (CHILD_TYPE) children.get(index);
|
||||
}
|
||||
|
||||
public int arity() {
|
||||
return children.size();
|
||||
}
|
||||
|
||||
@ -21,17 +21,17 @@ package org.apache.doris.nereids.trees;
|
||||
* interface for all tree node that have two children.
|
||||
*/
|
||||
public interface BinaryNode<
|
||||
NODE_TYPE extends BinaryNode<NODE_TYPE, LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE>,
|
||||
NODE_TYPE extends TreeNode<NODE_TYPE>,
|
||||
LEFT_CHILD_TYPE extends TreeNode,
|
||||
RIGHT_CHILD_TYPE extends TreeNode>
|
||||
extends TreeNode<NODE_TYPE> {
|
||||
|
||||
default LEFT_CHILD_TYPE left() {
|
||||
return child(0);
|
||||
return (LEFT_CHILD_TYPE) child(0);
|
||||
}
|
||||
|
||||
default RIGHT_CHILD_TYPE right() {
|
||||
return child(1);
|
||||
return (RIGHT_CHILD_TYPE) child(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -20,7 +20,7 @@ package org.apache.doris.nereids.trees;
|
||||
/**
|
||||
* Abstract class for all tree node that have no child.
|
||||
*/
|
||||
public interface LeafNode<NODE_TYPE extends LeafNode<NODE_TYPE>> extends TreeNode<NODE_TYPE> {
|
||||
public interface LeafNode<NODE_TYPE extends TreeNode<NODE_TYPE>> extends TreeNode<NODE_TYPE> {
|
||||
@Override
|
||||
default int arity() {
|
||||
return 0;
|
||||
|
||||
@ -21,6 +21,7 @@ import org.apache.doris.nereids.memo.GroupExpression;
|
||||
import org.apache.doris.nereids.operators.Operator;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* interface for all node in Nereids, include plan node and expression.
|
||||
@ -32,15 +33,16 @@ public interface TreeNode<NODE_TYPE extends TreeNode<NODE_TYPE>> {
|
||||
|
||||
Operator getOperator();
|
||||
|
||||
GroupExpression getGroupExpression();
|
||||
// cache GroupExpression for fast exit from Memo.copyIn.
|
||||
Optional<GroupExpression> getGroupExpression();
|
||||
|
||||
NodeType getType();
|
||||
|
||||
<CHILD_TYPE extends TreeNode> List<CHILD_TYPE> children();
|
||||
List<NODE_TYPE> children();
|
||||
|
||||
<CHILD_TYPE extends TreeNode> CHILD_TYPE child(int index);
|
||||
NODE_TYPE child(int index);
|
||||
|
||||
int arity();
|
||||
|
||||
NODE_TYPE newChildren(List<TreeNode> children);
|
||||
NODE_TYPE newChildren(List<NODE_TYPE> children);
|
||||
}
|
||||
|
||||
@ -20,13 +20,11 @@ package org.apache.doris.nereids.trees;
|
||||
/**
|
||||
* interface for all tree node that have one child.
|
||||
*/
|
||||
public interface UnaryNode<
|
||||
NODE_TYPE extends UnaryNode<NODE_TYPE, CHILD_TYPE>,
|
||||
CHILD_TYPE extends TreeNode>
|
||||
public interface UnaryNode<NODE_TYPE extends TreeNode<NODE_TYPE>, CHILD_TYPE extends TreeNode>
|
||||
extends TreeNode<NODE_TYPE> {
|
||||
|
||||
default CHILD_TYPE child() {
|
||||
return child(0);
|
||||
return (CHILD_TYPE) child(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -27,8 +27,8 @@ import java.util.List;
|
||||
/**
|
||||
* Expression for alias, such as col1 as c1.
|
||||
*/
|
||||
public class Alias<CHILD_TYPE extends Expression> extends NamedExpression<Alias<CHILD_TYPE>>
|
||||
implements UnaryExpression<Alias<CHILD_TYPE>, CHILD_TYPE> {
|
||||
public class Alias<CHILD_TYPE extends Expression> extends NamedExpression
|
||||
implements UnaryExpression<CHILD_TYPE> {
|
||||
|
||||
private final ExprId exprId;
|
||||
private final String name;
|
||||
|
||||
@ -23,19 +23,18 @@ import org.apache.doris.nereids.trees.BinaryNode;
|
||||
* Interface for all expression that have two children.
|
||||
*/
|
||||
public interface BinaryExpression<
|
||||
EXPR_TYPE extends BinaryExpression<EXPR_TYPE, LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE>,
|
||||
LEFT_CHILD_TYPE extends Expression,
|
||||
RIGHT_CHILD_TYPE extends Expression>
|
||||
extends BinaryNode<EXPR_TYPE, LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> {
|
||||
extends BinaryNode<Expression, LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> {
|
||||
|
||||
@Override
|
||||
default LEFT_CHILD_TYPE left() {
|
||||
return child(0);
|
||||
return (LEFT_CHILD_TYPE) child(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
default RIGHT_CHILD_TYPE right() {
|
||||
return child(1);
|
||||
return (RIGHT_CHILD_TYPE) child(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -30,8 +30,7 @@ import java.util.Objects;
|
||||
* Such as: "=", "<", "<=", ">", ">=", "<=>"
|
||||
*/
|
||||
public class ComparisonPredicate<LEFT_CHILD_TYPE extends Expression, RIGHT_CHILD_TYPE extends Expression>
|
||||
extends Expression<ComparisonPredicate<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE>> implements
|
||||
BinaryExpression<ComparisonPredicate<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE>, LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> {
|
||||
extends Expression implements BinaryExpression<LEFT_CHILD_TYPE, RIGHT_CHILD_TYPE> {
|
||||
|
||||
/**
|
||||
* Constructor of ComparisonPredicate.
|
||||
|
||||
@ -19,7 +19,6 @@ package org.apache.doris.nereids.trees.expressions;
|
||||
|
||||
import org.apache.doris.nereids.exceptions.UnboundException;
|
||||
import org.apache.doris.nereids.trees.NodeType;
|
||||
import org.apache.doris.nereids.trees.TreeNode;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
@ -46,8 +45,8 @@ public class EqualTo<LEFT_CHILD_TYPE extends Expression, RIGHT_CHILD_TYPE extend
|
||||
}
|
||||
|
||||
@Override
|
||||
public EqualTo newChildren(List<TreeNode> children) {
|
||||
public EqualTo<Expression, Expression> newChildren(List<Expression> children) {
|
||||
Preconditions.checkArgument(children.size() == 2);
|
||||
return new EqualTo((Expression) children.get(0), (Expression) children.get(1));
|
||||
return new EqualTo<>(children.get(0), children.get(1));
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user