From 05e38eadbeb3de19e5b26003c2b401e00bb71df4 Mon Sep 17 00:00:00 2001 From: polo Date: Sun, 18 Oct 2026 00:08:23 +0200 Subject: =?UTF-8?q?sortie=20de=20vendor=20du=20d=C3=A9p=C3=B4t,=20oubli=20?= =?UTF-8?q?dans=20config-template.ini?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vendor/doctrine/orm/src/Query/AST/ASTException.php | 20 - .../orm/src/Query/AST/AggregateExpression.php | 23 - .../orm/src/Query/AST/ArithmeticExpression.php | 34 - .../orm/src/Query/AST/ArithmeticFactor.php | 36 - .../doctrine/orm/src/Query/AST/ArithmeticTerm.php | 25 - .../orm/src/Query/AST/BetweenExpression.php | 23 - .../orm/src/Query/AST/CoalesceExpression.php | 25 - .../src/Query/AST/CollectionMemberExpression.php | 27 - .../orm/src/Query/AST/ComparisonExpression.php | 32 - .../orm/src/Query/AST/ConditionalExpression.php | 25 - .../orm/src/Query/AST/ConditionalFactor.php | 26 - .../orm/src/Query/AST/ConditionalPrimary.php | 34 - .../doctrine/orm/src/Query/AST/ConditionalTerm.php | 25 - vendor/doctrine/orm/src/Query/AST/DeleteClause.php | 26 - .../doctrine/orm/src/Query/AST/DeleteStatement.php | 26 - .../AST/EmptyCollectionComparisonExpression.php | 26 - .../orm/src/Query/AST/ExistsExpression.php | 26 - vendor/doctrine/orm/src/Query/AST/FromClause.php | 25 - .../orm/src/Query/AST/Functions/AbsFunction.php | 37 - .../orm/src/Query/AST/Functions/AvgFunction.php | 27 - .../orm/src/Query/AST/Functions/BitAndFunction.php | 43 - .../orm/src/Query/AST/Functions/BitOrFunction.php | 43 - .../orm/src/Query/AST/Functions/ConcatFunction.php | 58 - .../orm/src/Query/AST/Functions/CountFunction.php | 35 - .../Query/AST/Functions/CurrentDateFunction.php | 29 - .../Query/AST/Functions/CurrentTimeFunction.php | 29 - .../AST/Functions/CurrentTimestampFunction.php | 29 - .../src/Query/AST/Functions/DateAddFunction.php | 83 - .../src/Query/AST/Functions/DateDiffFunction.php | 41 - .../src/Query/AST/Functions/DateSubFunction.php | 62 - .../orm/src/Query/AST/Functions/FunctionNode.php | 32 - .../src/Query/AST/Functions/IdentityFunction.php | 90 - .../orm/src/Query/AST/Functions/LengthFunction.php | 45 - .../orm/src/Query/AST/Functions/LocateFunction.php | 62 - .../orm/src/Query/AST/Functions/LowerFunction.php | 40 - .../orm/src/Query/AST/Functions/MaxFunction.php | 27 - .../orm/src/Query/AST/Functions/MinFunction.php | 27 - .../orm/src/Query/AST/Functions/ModFunction.php | 43 - .../orm/src/Query/AST/Functions/SizeFunction.php | 113 - .../orm/src/Query/AST/Functions/SqrtFunction.php | 40 - .../src/Query/AST/Functions/SubstringFunction.php | 58 - .../orm/src/Query/AST/Functions/SumFunction.php | 27 - .../orm/src/Query/AST/Functions/TrimFunction.php | 119 - .../orm/src/Query/AST/Functions/UpperFunction.php | 40 - .../orm/src/Query/AST/GeneralCaseExpression.php | 27 - .../doctrine/orm/src/Query/AST/GroupByClause.php | 20 - vendor/doctrine/orm/src/Query/AST/HavingClause.php | 19 - .../AST/IdentificationVariableDeclaration.php | 28 - .../orm/src/Query/AST/InListExpression.php | 23 - .../orm/src/Query/AST/InSubselectExpression.php | 22 - vendor/doctrine/orm/src/Query/AST/IndexBy.php | 26 - .../doctrine/orm/src/Query/AST/InputParameter.php | 35 - .../orm/src/Query/AST/InstanceOfExpression.php | 29 - vendor/doctrine/orm/src/Query/AST/Join.php | 34 - .../src/Query/AST/JoinAssociationDeclaration.php | 27 - .../Query/AST/JoinAssociationPathExpression.php | 19 - .../orm/src/Query/AST/JoinClassPathExpression.php | 26 - .../orm/src/Query/AST/JoinVariableDeclaration.php | 24 - .../doctrine/orm/src/Query/AST/LikeExpression.php | 29 - vendor/doctrine/orm/src/Query/AST/Literal.php | 26 - .../orm/src/Query/AST/NewObjectExpression.php | 25 - vendor/doctrine/orm/src/Query/AST/Node.php | 85 - .../orm/src/Query/AST/NullComparisonExpression.php | 26 - .../orm/src/Query/AST/NullIfExpression.php | 24 - .../doctrine/orm/src/Query/AST/OrderByClause.php | 25 - vendor/doctrine/orm/src/Query/AST/OrderByItem.php | 38 - .../orm/src/Query/AST/ParenthesisExpression.php | 22 - .../doctrine/orm/src/Query/AST/PathExpression.php | 39 - .../src/Query/AST/Phase2OptimizableConditional.php | 17 - .../orm/src/Query/AST/QuantifiedExpression.php | 43 - .../orm/src/Query/AST/RangeVariableDeclaration.php | 27 - vendor/doctrine/orm/src/Query/AST/SelectClause.php | 27 - .../orm/src/Query/AST/SelectExpression.php | 28 - .../doctrine/orm/src/Query/AST/SelectStatement.php | 32 - .../src/Query/AST/SimpleArithmeticExpression.php | 25 - .../orm/src/Query/AST/SimpleCaseExpression.php | 28 - .../orm/src/Query/AST/SimpleSelectClause.php | 26 - .../orm/src/Query/AST/SimpleSelectExpression.php | 27 - .../orm/src/Query/AST/SimpleWhenClause.php | 26 - vendor/doctrine/orm/src/Query/AST/Subselect.php | 32 - .../orm/src/Query/AST/SubselectFromClause.php | 25 - .../SubselectIdentificationVariableDeclaration.php | 19 - .../doctrine/orm/src/Query/AST/TypedExpression.php | 15 - vendor/doctrine/orm/src/Query/AST/UpdateClause.php | 29 - vendor/doctrine/orm/src/Query/AST/UpdateItem.php | 26 - .../doctrine/orm/src/Query/AST/UpdateStatement.php | 26 - vendor/doctrine/orm/src/Query/AST/WhenClause.php | 26 - vendor/doctrine/orm/src/Query/AST/WhereClause.php | 24 - .../orm/src/Query/Exec/AbstractSqlExecutor.php | 61 - .../src/Query/Exec/MultiTableDeleteExecutor.php | 131 - .../src/Query/Exec/MultiTableUpdateExecutor.php | 180 -- .../orm/src/Query/Exec/SingleSelectExecutor.php | 31 - .../Query/Exec/SingleTableDeleteUpdateExecutor.php | 42 - vendor/doctrine/orm/src/Query/Expr.php | 615 ---- vendor/doctrine/orm/src/Query/Expr/Andx.php | 32 - vendor/doctrine/orm/src/Query/Expr/Base.php | 96 - vendor/doctrine/orm/src/Query/Expr/Comparison.php | 47 - vendor/doctrine/orm/src/Query/Expr/Composite.php | 50 - vendor/doctrine/orm/src/Query/Expr/From.php | 48 - vendor/doctrine/orm/src/Query/Expr/Func.php | 48 - vendor/doctrine/orm/src/Query/Expr/GroupBy.php | 25 - vendor/doctrine/orm/src/Query/Expr/Join.php | 77 - vendor/doctrine/orm/src/Query/Expr/Literal.php | 25 - vendor/doctrine/orm/src/Query/Expr/Math.php | 59 - vendor/doctrine/orm/src/Query/Expr/OrderBy.php | 60 - vendor/doctrine/orm/src/Query/Expr/Orx.php | 32 - vendor/doctrine/orm/src/Query/Expr/Select.php | 28 - .../orm/src/Query/Filter/FilterException.php | 23 - vendor/doctrine/orm/src/Query/Filter/SQLFilter.php | 174 -- vendor/doctrine/orm/src/Query/FilterCollection.php | 260 -- vendor/doctrine/orm/src/Query/Lexer.php | 150 - vendor/doctrine/orm/src/Query/Parameter.php | 89 - .../orm/src/Query/ParameterTypeInferer.php | 77 - vendor/doctrine/orm/src/Query/Parser.php | 3269 -------------------- vendor/doctrine/orm/src/Query/ParserResult.php | 118 - vendor/doctrine/orm/src/Query/Printer.php | 64 - vendor/doctrine/orm/src/Query/QueryException.php | 155 - .../orm/src/Query/QueryExpressionVisitor.php | 180 -- vendor/doctrine/orm/src/Query/ResultSetMapping.php | 547 ---- .../orm/src/Query/ResultSetMappingBuilder.php | 281 -- vendor/doctrine/orm/src/Query/SqlWalker.php | 2264 -------------- vendor/doctrine/orm/src/Query/TokenType.php | 91 - vendor/doctrine/orm/src/Query/TreeWalker.php | 44 - .../doctrine/orm/src/Query/TreeWalkerAdapter.php | 90 - vendor/doctrine/orm/src/Query/TreeWalkerChain.php | 88 - 125 files changed, 12640 deletions(-) delete mode 100644 vendor/doctrine/orm/src/Query/AST/ASTException.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/AggregateExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/ArithmeticExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/ArithmeticFactor.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/ArithmeticTerm.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/BetweenExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/CoalesceExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/CollectionMemberExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/ComparisonExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/ConditionalExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/ConditionalFactor.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/ConditionalPrimary.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/ConditionalTerm.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/DeleteClause.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/DeleteStatement.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/EmptyCollectionComparisonExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/ExistsExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/FromClause.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Functions/AbsFunction.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Functions/AvgFunction.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Functions/BitAndFunction.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Functions/BitOrFunction.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Functions/ConcatFunction.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Functions/CountFunction.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Functions/CurrentDateFunction.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Functions/CurrentTimeFunction.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Functions/CurrentTimestampFunction.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Functions/DateAddFunction.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Functions/DateDiffFunction.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Functions/DateSubFunction.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Functions/FunctionNode.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Functions/IdentityFunction.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Functions/LengthFunction.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Functions/LocateFunction.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Functions/LowerFunction.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Functions/MaxFunction.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Functions/MinFunction.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Functions/ModFunction.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Functions/SizeFunction.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Functions/SqrtFunction.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Functions/SubstringFunction.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Functions/SumFunction.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Functions/TrimFunction.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Functions/UpperFunction.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/GeneralCaseExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/GroupByClause.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/HavingClause.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/IdentificationVariableDeclaration.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/InListExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/InSubselectExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/IndexBy.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/InputParameter.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/InstanceOfExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Join.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/JoinAssociationDeclaration.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/JoinAssociationPathExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/JoinClassPathExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/JoinVariableDeclaration.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/LikeExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Literal.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/NewObjectExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Node.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/NullComparisonExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/NullIfExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/OrderByClause.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/OrderByItem.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/ParenthesisExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/PathExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Phase2OptimizableConditional.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/QuantifiedExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/RangeVariableDeclaration.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/SelectClause.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/SelectExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/SelectStatement.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/SimpleArithmeticExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/SimpleCaseExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/SimpleSelectClause.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/SimpleSelectExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/SimpleWhenClause.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/Subselect.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/SubselectFromClause.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/SubselectIdentificationVariableDeclaration.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/TypedExpression.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/UpdateClause.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/UpdateItem.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/UpdateStatement.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/WhenClause.php delete mode 100644 vendor/doctrine/orm/src/Query/AST/WhereClause.php delete mode 100644 vendor/doctrine/orm/src/Query/Exec/AbstractSqlExecutor.php delete mode 100644 vendor/doctrine/orm/src/Query/Exec/MultiTableDeleteExecutor.php delete mode 100644 vendor/doctrine/orm/src/Query/Exec/MultiTableUpdateExecutor.php delete mode 100644 vendor/doctrine/orm/src/Query/Exec/SingleSelectExecutor.php delete mode 100644 vendor/doctrine/orm/src/Query/Exec/SingleTableDeleteUpdateExecutor.php delete mode 100644 vendor/doctrine/orm/src/Query/Expr.php delete mode 100644 vendor/doctrine/orm/src/Query/Expr/Andx.php delete mode 100644 vendor/doctrine/orm/src/Query/Expr/Base.php delete mode 100644 vendor/doctrine/orm/src/Query/Expr/Comparison.php delete mode 100644 vendor/doctrine/orm/src/Query/Expr/Composite.php delete mode 100644 vendor/doctrine/orm/src/Query/Expr/From.php delete mode 100644 vendor/doctrine/orm/src/Query/Expr/Func.php delete mode 100644 vendor/doctrine/orm/src/Query/Expr/GroupBy.php delete mode 100644 vendor/doctrine/orm/src/Query/Expr/Join.php delete mode 100644 vendor/doctrine/orm/src/Query/Expr/Literal.php delete mode 100644 vendor/doctrine/orm/src/Query/Expr/Math.php delete mode 100644 vendor/doctrine/orm/src/Query/Expr/OrderBy.php delete mode 100644 vendor/doctrine/orm/src/Query/Expr/Orx.php delete mode 100644 vendor/doctrine/orm/src/Query/Expr/Select.php delete mode 100644 vendor/doctrine/orm/src/Query/Filter/FilterException.php delete mode 100644 vendor/doctrine/orm/src/Query/Filter/SQLFilter.php delete mode 100644 vendor/doctrine/orm/src/Query/FilterCollection.php delete mode 100644 vendor/doctrine/orm/src/Query/Lexer.php delete mode 100644 vendor/doctrine/orm/src/Query/Parameter.php delete mode 100644 vendor/doctrine/orm/src/Query/ParameterTypeInferer.php delete mode 100644 vendor/doctrine/orm/src/Query/Parser.php delete mode 100644 vendor/doctrine/orm/src/Query/ParserResult.php delete mode 100644 vendor/doctrine/orm/src/Query/Printer.php delete mode 100644 vendor/doctrine/orm/src/Query/QueryException.php delete mode 100644 vendor/doctrine/orm/src/Query/QueryExpressionVisitor.php delete mode 100644 vendor/doctrine/orm/src/Query/ResultSetMapping.php delete mode 100644 vendor/doctrine/orm/src/Query/ResultSetMappingBuilder.php delete mode 100644 vendor/doctrine/orm/src/Query/SqlWalker.php delete mode 100644 vendor/doctrine/orm/src/Query/TokenType.php delete mode 100644 vendor/doctrine/orm/src/Query/TreeWalker.php delete mode 100644 vendor/doctrine/orm/src/Query/TreeWalkerAdapter.php delete mode 100644 vendor/doctrine/orm/src/Query/TreeWalkerChain.php (limited to 'vendor/doctrine/orm/src/Query') diff --git a/vendor/doctrine/orm/src/Query/AST/ASTException.php b/vendor/doctrine/orm/src/Query/AST/ASTException.php deleted file mode 100644 index 1ef890a..0000000 --- a/vendor/doctrine/orm/src/Query/AST/ASTException.php +++ /dev/null @@ -1,20 +0,0 @@ -walkAggregateExpression($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/ArithmeticExpression.php b/vendor/doctrine/orm/src/Query/AST/ArithmeticExpression.php deleted file mode 100644 index a819e05..0000000 --- a/vendor/doctrine/orm/src/Query/AST/ArithmeticExpression.php +++ /dev/null @@ -1,34 +0,0 @@ -simpleArithmeticExpression; - } - - public function isSubselect(): bool - { - return (bool) $this->subselect; - } - - public function dispatch(SqlWalker $walker): string - { - return $walker->walkArithmeticExpression($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/ArithmeticFactor.php b/vendor/doctrine/orm/src/Query/AST/ArithmeticFactor.php deleted file mode 100644 index 278a921..0000000 --- a/vendor/doctrine/orm/src/Query/AST/ArithmeticFactor.php +++ /dev/null @@ -1,36 +0,0 @@ -sign === true; - } - - public function isNegativeSigned(): bool - { - return $this->sign === false; - } - - public function dispatch(SqlWalker $walker): string - { - return $walker->walkArithmeticFactor($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/ArithmeticTerm.php b/vendor/doctrine/orm/src/Query/AST/ArithmeticTerm.php deleted file mode 100644 index b233612..0000000 --- a/vendor/doctrine/orm/src/Query/AST/ArithmeticTerm.php +++ /dev/null @@ -1,25 +0,0 @@ -walkArithmeticTerm($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/BetweenExpression.php b/vendor/doctrine/orm/src/Query/AST/BetweenExpression.php deleted file mode 100644 index c13292b..0000000 --- a/vendor/doctrine/orm/src/Query/AST/BetweenExpression.php +++ /dev/null @@ -1,23 +0,0 @@ -walkBetweenExpression($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/CoalesceExpression.php b/vendor/doctrine/orm/src/Query/AST/CoalesceExpression.php deleted file mode 100644 index 89f025f..0000000 --- a/vendor/doctrine/orm/src/Query/AST/CoalesceExpression.php +++ /dev/null @@ -1,25 +0,0 @@ -walkCoalesceExpression($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/CollectionMemberExpression.php b/vendor/doctrine/orm/src/Query/AST/CollectionMemberExpression.php deleted file mode 100644 index a62a191..0000000 --- a/vendor/doctrine/orm/src/Query/AST/CollectionMemberExpression.php +++ /dev/null @@ -1,27 +0,0 @@ -walkCollectionMemberExpression($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/ComparisonExpression.php b/vendor/doctrine/orm/src/Query/AST/ComparisonExpression.php deleted file mode 100644 index a7d91f9..0000000 --- a/vendor/doctrine/orm/src/Query/AST/ComparisonExpression.php +++ /dev/null @@ -1,32 +0,0 @@ -" | "!=") (BooleanExpression | QuantifiedExpression) | - * EnumExpression ("=" | "<>" | "!=") (EnumExpression | QuantifiedExpression) | - * DatetimeExpression ComparisonOperator (DatetimeExpression | QuantifiedExpression) | - * EntityExpression ("=" | "<>") (EntityExpression | QuantifiedExpression) - * - * @link www.doctrine-project.org - */ -class ComparisonExpression extends Node -{ - public function __construct( - public Node|string $leftExpression, - public string $operator, - public Node|string $rightExpression, - ) { - } - - public function dispatch(SqlWalker $walker): string - { - return $walker->walkComparisonExpression($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/ConditionalExpression.php b/vendor/doctrine/orm/src/Query/AST/ConditionalExpression.php deleted file mode 100644 index 26a98e5..0000000 --- a/vendor/doctrine/orm/src/Query/AST/ConditionalExpression.php +++ /dev/null @@ -1,25 +0,0 @@ -walkConditionalExpression($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/ConditionalFactor.php b/vendor/doctrine/orm/src/Query/AST/ConditionalFactor.php deleted file mode 100644 index 7881743..0000000 --- a/vendor/doctrine/orm/src/Query/AST/ConditionalFactor.php +++ /dev/null @@ -1,26 +0,0 @@ -walkConditionalFactor($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/ConditionalPrimary.php b/vendor/doctrine/orm/src/Query/AST/ConditionalPrimary.php deleted file mode 100644 index 9344cd9..0000000 --- a/vendor/doctrine/orm/src/Query/AST/ConditionalPrimary.php +++ /dev/null @@ -1,34 +0,0 @@ -simpleConditionalExpression; - } - - public function isConditionalExpression(): bool - { - return (bool) $this->conditionalExpression; - } - - public function dispatch(SqlWalker $walker): string - { - return $walker->walkConditionalPrimary($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/ConditionalTerm.php b/vendor/doctrine/orm/src/Query/AST/ConditionalTerm.php deleted file mode 100644 index dcea50b..0000000 --- a/vendor/doctrine/orm/src/Query/AST/ConditionalTerm.php +++ /dev/null @@ -1,25 +0,0 @@ -walkConditionalTerm($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/DeleteClause.php b/vendor/doctrine/orm/src/Query/AST/DeleteClause.php deleted file mode 100644 index 25e9085..0000000 --- a/vendor/doctrine/orm/src/Query/AST/DeleteClause.php +++ /dev/null @@ -1,26 +0,0 @@ -walkDeleteClause($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/DeleteStatement.php b/vendor/doctrine/orm/src/Query/AST/DeleteStatement.php deleted file mode 100644 index f367d09..0000000 --- a/vendor/doctrine/orm/src/Query/AST/DeleteStatement.php +++ /dev/null @@ -1,26 +0,0 @@ -walkDeleteStatement($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/EmptyCollectionComparisonExpression.php b/vendor/doctrine/orm/src/Query/AST/EmptyCollectionComparisonExpression.php deleted file mode 100644 index 9978800..0000000 --- a/vendor/doctrine/orm/src/Query/AST/EmptyCollectionComparisonExpression.php +++ /dev/null @@ -1,26 +0,0 @@ -walkEmptyCollectionComparisonExpression($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/ExistsExpression.php b/vendor/doctrine/orm/src/Query/AST/ExistsExpression.php deleted file mode 100644 index 72757f4..0000000 --- a/vendor/doctrine/orm/src/Query/AST/ExistsExpression.php +++ /dev/null @@ -1,26 +0,0 @@ -walkExistsExpression($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/FromClause.php b/vendor/doctrine/orm/src/Query/AST/FromClause.php deleted file mode 100644 index 0b74393..0000000 --- a/vendor/doctrine/orm/src/Query/AST/FromClause.php +++ /dev/null @@ -1,25 +0,0 @@ -walkFromClause($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Functions/AbsFunction.php b/vendor/doctrine/orm/src/Query/AST/Functions/AbsFunction.php deleted file mode 100644 index 4edff06..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Functions/AbsFunction.php +++ /dev/null @@ -1,37 +0,0 @@ -walkSimpleArithmeticExpression( - $this->simpleArithmeticExpression, - ) . ')'; - } - - public function parse(Parser $parser): void - { - $parser->match(TokenType::T_IDENTIFIER); - $parser->match(TokenType::T_OPEN_PARENTHESIS); - - $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression(); - - $parser->match(TokenType::T_CLOSE_PARENTHESIS); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Functions/AvgFunction.php b/vendor/doctrine/orm/src/Query/AST/Functions/AvgFunction.php deleted file mode 100644 index ba7b7f3..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Functions/AvgFunction.php +++ /dev/null @@ -1,27 +0,0 @@ -aggregateExpression->dispatch($sqlWalker); - } - - public function parse(Parser $parser): void - { - $this->aggregateExpression = $parser->AggregateExpression(); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Functions/BitAndFunction.php b/vendor/doctrine/orm/src/Query/AST/Functions/BitAndFunction.php deleted file mode 100644 index f2d3146..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Functions/BitAndFunction.php +++ /dev/null @@ -1,43 +0,0 @@ -getConnection()->getDatabasePlatform(); - - return $platform->getBitAndComparisonExpression( - $this->firstArithmetic->dispatch($sqlWalker), - $this->secondArithmetic->dispatch($sqlWalker), - ); - } - - public function parse(Parser $parser): void - { - $parser->match(TokenType::T_IDENTIFIER); - $parser->match(TokenType::T_OPEN_PARENTHESIS); - - $this->firstArithmetic = $parser->ArithmeticPrimary(); - $parser->match(TokenType::T_COMMA); - $this->secondArithmetic = $parser->ArithmeticPrimary(); - - $parser->match(TokenType::T_CLOSE_PARENTHESIS); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Functions/BitOrFunction.php b/vendor/doctrine/orm/src/Query/AST/Functions/BitOrFunction.php deleted file mode 100644 index f3f84da..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Functions/BitOrFunction.php +++ /dev/null @@ -1,43 +0,0 @@ -getConnection()->getDatabasePlatform(); - - return $platform->getBitOrComparisonExpression( - $this->firstArithmetic->dispatch($sqlWalker), - $this->secondArithmetic->dispatch($sqlWalker), - ); - } - - public function parse(Parser $parser): void - { - $parser->match(TokenType::T_IDENTIFIER); - $parser->match(TokenType::T_OPEN_PARENTHESIS); - - $this->firstArithmetic = $parser->ArithmeticPrimary(); - $parser->match(TokenType::T_COMMA); - $this->secondArithmetic = $parser->ArithmeticPrimary(); - - $parser->match(TokenType::T_CLOSE_PARENTHESIS); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Functions/ConcatFunction.php b/vendor/doctrine/orm/src/Query/AST/Functions/ConcatFunction.php deleted file mode 100644 index 5b8d696..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Functions/ConcatFunction.php +++ /dev/null @@ -1,58 +0,0 @@ - */ - public array $concatExpressions = []; - - public function getSql(SqlWalker $sqlWalker): string - { - $platform = $sqlWalker->getConnection()->getDatabasePlatform(); - - $args = []; - - foreach ($this->concatExpressions as $expression) { - $args[] = $sqlWalker->walkStringPrimary($expression); - } - - return $platform->getConcatExpression(...$args); - } - - public function parse(Parser $parser): void - { - $parser->match(TokenType::T_IDENTIFIER); - $parser->match(TokenType::T_OPEN_PARENTHESIS); - - $this->firstStringPrimary = $parser->StringPrimary(); - $this->concatExpressions[] = $this->firstStringPrimary; - - $parser->match(TokenType::T_COMMA); - - $this->secondStringPrimary = $parser->StringPrimary(); - $this->concatExpressions[] = $this->secondStringPrimary; - - while ($parser->getLexer()->isNextToken(TokenType::T_COMMA)) { - $parser->match(TokenType::T_COMMA); - $this->concatExpressions[] = $parser->StringPrimary(); - } - - $parser->match(TokenType::T_CLOSE_PARENTHESIS); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Functions/CountFunction.php b/vendor/doctrine/orm/src/Query/AST/Functions/CountFunction.php deleted file mode 100644 index dc926a5..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Functions/CountFunction.php +++ /dev/null @@ -1,35 +0,0 @@ -aggregateExpression->dispatch($sqlWalker); - } - - public function parse(Parser $parser): void - { - $this->aggregateExpression = $parser->AggregateExpression(); - } - - public function getReturnType(): Type - { - return Type::getType(Types::INTEGER); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Functions/CurrentDateFunction.php b/vendor/doctrine/orm/src/Query/AST/Functions/CurrentDateFunction.php deleted file mode 100644 index cec9632..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Functions/CurrentDateFunction.php +++ /dev/null @@ -1,29 +0,0 @@ -getConnection()->getDatabasePlatform()->getCurrentDateSQL(); - } - - public function parse(Parser $parser): void - { - $parser->match(TokenType::T_IDENTIFIER); - $parser->match(TokenType::T_OPEN_PARENTHESIS); - $parser->match(TokenType::T_CLOSE_PARENTHESIS); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Functions/CurrentTimeFunction.php b/vendor/doctrine/orm/src/Query/AST/Functions/CurrentTimeFunction.php deleted file mode 100644 index 6473fce..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Functions/CurrentTimeFunction.php +++ /dev/null @@ -1,29 +0,0 @@ -getConnection()->getDatabasePlatform()->getCurrentTimeSQL(); - } - - public function parse(Parser $parser): void - { - $parser->match(TokenType::T_IDENTIFIER); - $parser->match(TokenType::T_OPEN_PARENTHESIS); - $parser->match(TokenType::T_CLOSE_PARENTHESIS); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Functions/CurrentTimestampFunction.php b/vendor/doctrine/orm/src/Query/AST/Functions/CurrentTimestampFunction.php deleted file mode 100644 index edcd27c..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Functions/CurrentTimestampFunction.php +++ /dev/null @@ -1,29 +0,0 @@ -getConnection()->getDatabasePlatform()->getCurrentTimestampSQL(); - } - - public function parse(Parser $parser): void - { - $parser->match(TokenType::T_IDENTIFIER); - $parser->match(TokenType::T_OPEN_PARENTHESIS); - $parser->match(TokenType::T_CLOSE_PARENTHESIS); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Functions/DateAddFunction.php b/vendor/doctrine/orm/src/Query/AST/Functions/DateAddFunction.php deleted file mode 100644 index 12920dc..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Functions/DateAddFunction.php +++ /dev/null @@ -1,83 +0,0 @@ -unit->value)) { - 'second' => $sqlWalker->getConnection()->getDatabasePlatform()->getDateAddSecondsExpression( - $this->firstDateExpression->dispatch($sqlWalker), - $this->dispatchIntervalExpression($sqlWalker), - ), - 'minute' => $sqlWalker->getConnection()->getDatabasePlatform()->getDateAddMinutesExpression( - $this->firstDateExpression->dispatch($sqlWalker), - $this->dispatchIntervalExpression($sqlWalker), - ), - 'hour' => $sqlWalker->getConnection()->getDatabasePlatform()->getDateAddHourExpression( - $this->firstDateExpression->dispatch($sqlWalker), - $this->dispatchIntervalExpression($sqlWalker), - ), - 'day' => $sqlWalker->getConnection()->getDatabasePlatform()->getDateAddDaysExpression( - $this->firstDateExpression->dispatch($sqlWalker), - $this->dispatchIntervalExpression($sqlWalker), - ), - 'week' => $sqlWalker->getConnection()->getDatabasePlatform()->getDateAddWeeksExpression( - $this->firstDateExpression->dispatch($sqlWalker), - $this->dispatchIntervalExpression($sqlWalker), - ), - 'month' => $sqlWalker->getConnection()->getDatabasePlatform()->getDateAddMonthExpression( - $this->firstDateExpression->dispatch($sqlWalker), - $this->dispatchIntervalExpression($sqlWalker), - ), - 'year' => $sqlWalker->getConnection()->getDatabasePlatform()->getDateAddYearsExpression( - $this->firstDateExpression->dispatch($sqlWalker), - $this->dispatchIntervalExpression($sqlWalker), - ), - default => throw QueryException::semanticalError( - 'DATE_ADD() only supports units of type second, minute, hour, day, week, month and year.', - ), - }; - } - - /** @throws ASTException */ - private function dispatchIntervalExpression(SqlWalker $sqlWalker): string - { - return $this->intervalExpression->dispatch($sqlWalker); - } - - public function parse(Parser $parser): void - { - $parser->match(TokenType::T_IDENTIFIER); - $parser->match(TokenType::T_OPEN_PARENTHESIS); - - $this->firstDateExpression = $parser->ArithmeticPrimary(); - $parser->match(TokenType::T_COMMA); - $this->intervalExpression = $parser->ArithmeticPrimary(); - $parser->match(TokenType::T_COMMA); - $this->unit = $parser->StringPrimary(); - - $parser->match(TokenType::T_CLOSE_PARENTHESIS); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Functions/DateDiffFunction.php b/vendor/doctrine/orm/src/Query/AST/Functions/DateDiffFunction.php deleted file mode 100644 index 55598c0..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Functions/DateDiffFunction.php +++ /dev/null @@ -1,41 +0,0 @@ -getConnection()->getDatabasePlatform()->getDateDiffExpression( - $this->date1->dispatch($sqlWalker), - $this->date2->dispatch($sqlWalker), - ); - } - - public function parse(Parser $parser): void - { - $parser->match(TokenType::T_IDENTIFIER); - $parser->match(TokenType::T_OPEN_PARENTHESIS); - - $this->date1 = $parser->ArithmeticPrimary(); - $parser->match(TokenType::T_COMMA); - $this->date2 = $parser->ArithmeticPrimary(); - - $parser->match(TokenType::T_CLOSE_PARENTHESIS); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Functions/DateSubFunction.php b/vendor/doctrine/orm/src/Query/AST/Functions/DateSubFunction.php deleted file mode 100644 index 5363680..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Functions/DateSubFunction.php +++ /dev/null @@ -1,62 +0,0 @@ -unit->value)) { - 'second' => $sqlWalker->getConnection()->getDatabasePlatform()->getDateSubSecondsExpression( - $this->firstDateExpression->dispatch($sqlWalker), - $this->dispatchIntervalExpression($sqlWalker), - ), - 'minute' => $sqlWalker->getConnection()->getDatabasePlatform()->getDateSubMinutesExpression( - $this->firstDateExpression->dispatch($sqlWalker), - $this->dispatchIntervalExpression($sqlWalker), - ), - 'hour' => $sqlWalker->getConnection()->getDatabasePlatform()->getDateSubHourExpression( - $this->firstDateExpression->dispatch($sqlWalker), - $this->dispatchIntervalExpression($sqlWalker), - ), - 'day' => $sqlWalker->getConnection()->getDatabasePlatform()->getDateSubDaysExpression( - $this->firstDateExpression->dispatch($sqlWalker), - $this->dispatchIntervalExpression($sqlWalker), - ), - 'week' => $sqlWalker->getConnection()->getDatabasePlatform()->getDateSubWeeksExpression( - $this->firstDateExpression->dispatch($sqlWalker), - $this->dispatchIntervalExpression($sqlWalker), - ), - 'month' => $sqlWalker->getConnection()->getDatabasePlatform()->getDateSubMonthExpression( - $this->firstDateExpression->dispatch($sqlWalker), - $this->dispatchIntervalExpression($sqlWalker), - ), - 'year' => $sqlWalker->getConnection()->getDatabasePlatform()->getDateSubYearsExpression( - $this->firstDateExpression->dispatch($sqlWalker), - $this->dispatchIntervalExpression($sqlWalker), - ), - default => throw QueryException::semanticalError( - 'DATE_SUB() only supports units of type second, minute, hour, day, week, month and year.', - ), - }; - } - - /** @throws ASTException */ - private function dispatchIntervalExpression(SqlWalker $sqlWalker): string - { - return $this->intervalExpression->dispatch($sqlWalker); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Functions/FunctionNode.php b/vendor/doctrine/orm/src/Query/AST/Functions/FunctionNode.php deleted file mode 100644 index 4cc549e..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Functions/FunctionNode.php +++ /dev/null @@ -1,32 +0,0 @@ -walkFunction($this); - } - - abstract public function parse(Parser $parser): void; -} diff --git a/vendor/doctrine/orm/src/Query/AST/Functions/IdentityFunction.php b/vendor/doctrine/orm/src/Query/AST/Functions/IdentityFunction.php deleted file mode 100644 index 1dd1bf5..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Functions/IdentityFunction.php +++ /dev/null @@ -1,90 +0,0 @@ -pathExpression->field !== null); - $entityManager = $sqlWalker->getEntityManager(); - $platform = $entityManager->getConnection()->getDatabasePlatform(); - $quoteStrategy = $entityManager->getConfiguration()->getQuoteStrategy(); - $dqlAlias = $this->pathExpression->identificationVariable; - $assocField = $this->pathExpression->field; - $assoc = $sqlWalker->getMetadataForDqlAlias($dqlAlias)->associationMappings[$assocField]; - $targetEntity = $entityManager->getClassMetadata($assoc->targetEntity); - - assert($assoc->isToOneOwningSide()); - $joinColumn = reset($assoc->joinColumns); - - if ($this->fieldMapping !== null) { - if (! isset($targetEntity->fieldMappings[$this->fieldMapping])) { - throw new QueryException(sprintf('Undefined reference field mapping "%s"', $this->fieldMapping)); - } - - $field = $targetEntity->fieldMappings[$this->fieldMapping]; - $joinColumn = null; - - foreach ($assoc->joinColumns as $mapping) { - if ($mapping->referencedColumnName === $field->columnName) { - $joinColumn = $mapping; - - break; - } - } - - if ($joinColumn === null) { - throw new QueryException(sprintf('Unable to resolve the reference field mapping "%s"', $this->fieldMapping)); - } - } - - // The table with the relation may be a subclass, so get the table name from the association definition - $tableName = $entityManager->getClassMetadata($assoc->sourceEntity)->getTableName(); - - $tableAlias = $sqlWalker->getSQLTableAlias($tableName, $dqlAlias); - $columnName = $quoteStrategy->getJoinColumnName($joinColumn, $targetEntity, $platform); - - return $tableAlias . '.' . $columnName; - } - - public function parse(Parser $parser): void - { - $parser->match(TokenType::T_IDENTIFIER); - $parser->match(TokenType::T_OPEN_PARENTHESIS); - - $this->pathExpression = $parser->SingleValuedAssociationPathExpression(); - - if ($parser->getLexer()->isNextToken(TokenType::T_COMMA)) { - $parser->match(TokenType::T_COMMA); - $parser->match(TokenType::T_STRING); - - $token = $parser->getLexer()->token; - assert($token !== null); - $this->fieldMapping = $token->value; - } - - $parser->match(TokenType::T_CLOSE_PARENTHESIS); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Functions/LengthFunction.php b/vendor/doctrine/orm/src/Query/AST/Functions/LengthFunction.php deleted file mode 100644 index 3994918..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Functions/LengthFunction.php +++ /dev/null @@ -1,45 +0,0 @@ -getConnection()->getDatabasePlatform()->getLengthExpression( - $sqlWalker->walkSimpleArithmeticExpression($this->stringPrimary), - ); - } - - public function parse(Parser $parser): void - { - $parser->match(TokenType::T_IDENTIFIER); - $parser->match(TokenType::T_OPEN_PARENTHESIS); - - $this->stringPrimary = $parser->StringPrimary(); - - $parser->match(TokenType::T_CLOSE_PARENTHESIS); - } - - public function getReturnType(): Type - { - return Type::getType(Types::INTEGER); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Functions/LocateFunction.php b/vendor/doctrine/orm/src/Query/AST/Functions/LocateFunction.php deleted file mode 100644 index c0d3b4a..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Functions/LocateFunction.php +++ /dev/null @@ -1,62 +0,0 @@ -getConnection()->getDatabasePlatform(); - - $firstString = $sqlWalker->walkStringPrimary($this->firstStringPrimary); - $secondString = $sqlWalker->walkStringPrimary($this->secondStringPrimary); - - if ($this->simpleArithmeticExpression) { - return $platform->getLocateExpression( - $secondString, - $firstString, - $sqlWalker->walkSimpleArithmeticExpression($this->simpleArithmeticExpression), - ); - } - - return $platform->getLocateExpression($secondString, $firstString); - } - - public function parse(Parser $parser): void - { - $parser->match(TokenType::T_IDENTIFIER); - $parser->match(TokenType::T_OPEN_PARENTHESIS); - - $this->firstStringPrimary = $parser->StringPrimary(); - - $parser->match(TokenType::T_COMMA); - - $this->secondStringPrimary = $parser->StringPrimary(); - - $lexer = $parser->getLexer(); - if ($lexer->isNextToken(TokenType::T_COMMA)) { - $parser->match(TokenType::T_COMMA); - - $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression(); - } - - $parser->match(TokenType::T_CLOSE_PARENTHESIS); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Functions/LowerFunction.php b/vendor/doctrine/orm/src/Query/AST/Functions/LowerFunction.php deleted file mode 100644 index 8ae337a..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Functions/LowerFunction.php +++ /dev/null @@ -1,40 +0,0 @@ -walkSimpleArithmeticExpression($this->stringPrimary), - ); - } - - public function parse(Parser $parser): void - { - $parser->match(TokenType::T_IDENTIFIER); - $parser->match(TokenType::T_OPEN_PARENTHESIS); - - $this->stringPrimary = $parser->StringPrimary(); - - $parser->match(TokenType::T_CLOSE_PARENTHESIS); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Functions/MaxFunction.php b/vendor/doctrine/orm/src/Query/AST/Functions/MaxFunction.php deleted file mode 100644 index 8a6eecf..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Functions/MaxFunction.php +++ /dev/null @@ -1,27 +0,0 @@ -aggregateExpression->dispatch($sqlWalker); - } - - public function parse(Parser $parser): void - { - $this->aggregateExpression = $parser->AggregateExpression(); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Functions/MinFunction.php b/vendor/doctrine/orm/src/Query/AST/Functions/MinFunction.php deleted file mode 100644 index 98d73a2..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Functions/MinFunction.php +++ /dev/null @@ -1,27 +0,0 @@ -aggregateExpression->dispatch($sqlWalker); - } - - public function parse(Parser $parser): void - { - $this->aggregateExpression = $parser->AggregateExpression(); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Functions/ModFunction.php b/vendor/doctrine/orm/src/Query/AST/Functions/ModFunction.php deleted file mode 100644 index 7c1af0b..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Functions/ModFunction.php +++ /dev/null @@ -1,43 +0,0 @@ -getConnection()->getDatabasePlatform()->getModExpression( - $sqlWalker->walkSimpleArithmeticExpression($this->firstSimpleArithmeticExpression), - $sqlWalker->walkSimpleArithmeticExpression($this->secondSimpleArithmeticExpression), - ); - } - - public function parse(Parser $parser): void - { - $parser->match(TokenType::T_IDENTIFIER); - $parser->match(TokenType::T_OPEN_PARENTHESIS); - - $this->firstSimpleArithmeticExpression = $parser->SimpleArithmeticExpression(); - - $parser->match(TokenType::T_COMMA); - - $this->secondSimpleArithmeticExpression = $parser->SimpleArithmeticExpression(); - - $parser->match(TokenType::T_CLOSE_PARENTHESIS); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Functions/SizeFunction.php b/vendor/doctrine/orm/src/Query/AST/Functions/SizeFunction.php deleted file mode 100644 index 87ee713..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Functions/SizeFunction.php +++ /dev/null @@ -1,113 +0,0 @@ -collectionPathExpression->field !== null); - $entityManager = $sqlWalker->getEntityManager(); - $platform = $entityManager->getConnection()->getDatabasePlatform(); - $quoteStrategy = $entityManager->getConfiguration()->getQuoteStrategy(); - $dqlAlias = $this->collectionPathExpression->identificationVariable; - $assocField = $this->collectionPathExpression->field; - - $class = $sqlWalker->getMetadataForDqlAlias($dqlAlias); - $assoc = $class->associationMappings[$assocField]; - $sql = 'SELECT COUNT(*) FROM '; - - if ($assoc->isOneToMany()) { - $targetClass = $entityManager->getClassMetadata($assoc->targetEntity); - $targetTableAlias = $sqlWalker->getSQLTableAlias($targetClass->getTableName()); - $sourceTableAlias = $sqlWalker->getSQLTableAlias($class->getTableName(), $dqlAlias); - - $sql .= $quoteStrategy->getTableName($targetClass, $platform) . ' ' . $targetTableAlias . ' WHERE '; - - $owningAssoc = $targetClass->associationMappings[$assoc->mappedBy]; - assert($owningAssoc->isManyToOne()); - - $first = true; - - foreach ($owningAssoc->targetToSourceKeyColumns as $targetColumn => $sourceColumn) { - if ($first) { - $first = false; - } else { - $sql .= ' AND '; - } - - $sql .= $targetTableAlias . '.' . $sourceColumn - . ' = ' - . $sourceTableAlias . '.' . $quoteStrategy->getColumnName($class->fieldNames[$targetColumn], $class, $platform); - } - } else { // many-to-many - assert($assoc->isManyToMany()); - $owningAssoc = $entityManager->getMetadataFactory()->getOwningSide($assoc); - $joinTable = $owningAssoc->joinTable; - - // SQL table aliases - $joinTableAlias = $sqlWalker->getSQLTableAlias($joinTable->name); - $sourceTableAlias = $sqlWalker->getSQLTableAlias($class->getTableName(), $dqlAlias); - - // join to target table - $targetClass = $entityManager->getClassMetadata($assoc->targetEntity); - $sql .= $quoteStrategy->getJoinTableName($owningAssoc, $targetClass, $platform) . ' ' . $joinTableAlias . ' WHERE '; - - $joinColumns = $assoc->isOwningSide() - ? $joinTable->joinColumns - : $joinTable->inverseJoinColumns; - - $first = true; - - foreach ($joinColumns as $joinColumn) { - if ($first) { - $first = false; - } else { - $sql .= ' AND '; - } - - $sourceColumnName = $quoteStrategy->getColumnName( - $class->fieldNames[$joinColumn->referencedColumnName], - $class, - $platform, - ); - - $sql .= $joinTableAlias . '.' . $joinColumn->name - . ' = ' - . $sourceTableAlias . '.' . $sourceColumnName; - } - } - - return '(' . $sql . ')'; - } - - public function parse(Parser $parser): void - { - $parser->match(TokenType::T_IDENTIFIER); - $parser->match(TokenType::T_OPEN_PARENTHESIS); - - $this->collectionPathExpression = $parser->CollectionValuedPathExpression(); - - $parser->match(TokenType::T_CLOSE_PARENTHESIS); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Functions/SqrtFunction.php b/vendor/doctrine/orm/src/Query/AST/Functions/SqrtFunction.php deleted file mode 100644 index e643663..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Functions/SqrtFunction.php +++ /dev/null @@ -1,40 +0,0 @@ -walkSimpleArithmeticExpression($this->simpleArithmeticExpression), - ); - } - - public function parse(Parser $parser): void - { - $parser->match(TokenType::T_IDENTIFIER); - $parser->match(TokenType::T_OPEN_PARENTHESIS); - - $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression(); - - $parser->match(TokenType::T_CLOSE_PARENTHESIS); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Functions/SubstringFunction.php b/vendor/doctrine/orm/src/Query/AST/Functions/SubstringFunction.php deleted file mode 100644 index 5744f08..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Functions/SubstringFunction.php +++ /dev/null @@ -1,58 +0,0 @@ -secondSimpleArithmeticExpression !== null) { - $optionalSecondSimpleArithmeticExpression = $sqlWalker->walkSimpleArithmeticExpression($this->secondSimpleArithmeticExpression); - } - - return $sqlWalker->getConnection()->getDatabasePlatform()->getSubstringExpression( - $sqlWalker->walkStringPrimary($this->stringPrimary), - $sqlWalker->walkSimpleArithmeticExpression($this->firstSimpleArithmeticExpression), - $optionalSecondSimpleArithmeticExpression, - ); - } - - public function parse(Parser $parser): void - { - $parser->match(TokenType::T_IDENTIFIER); - $parser->match(TokenType::T_OPEN_PARENTHESIS); - - $this->stringPrimary = $parser->StringPrimary(); - - $parser->match(TokenType::T_COMMA); - - $this->firstSimpleArithmeticExpression = $parser->SimpleArithmeticExpression(); - - $lexer = $parser->getLexer(); - if ($lexer->isNextToken(TokenType::T_COMMA)) { - $parser->match(TokenType::T_COMMA); - - $this->secondSimpleArithmeticExpression = $parser->SimpleArithmeticExpression(); - } - - $parser->match(TokenType::T_CLOSE_PARENTHESIS); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Functions/SumFunction.php b/vendor/doctrine/orm/src/Query/AST/Functions/SumFunction.php deleted file mode 100644 index 588dce9..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Functions/SumFunction.php +++ /dev/null @@ -1,27 +0,0 @@ -aggregateExpression->dispatch($sqlWalker); - } - - public function parse(Parser $parser): void - { - $this->aggregateExpression = $parser->AggregateExpression(); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Functions/TrimFunction.php b/vendor/doctrine/orm/src/Query/AST/Functions/TrimFunction.php deleted file mode 100644 index e0a3e99..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Functions/TrimFunction.php +++ /dev/null @@ -1,119 +0,0 @@ -walkStringPrimary($this->stringPrimary); - $platform = $sqlWalker->getConnection()->getDatabasePlatform(); - $trimMode = $this->getTrimMode(); - - if ($this->trimChar !== false) { - return $platform->getTrimExpression( - $stringPrimary, - $trimMode, - $platform->quoteStringLiteral($this->trimChar), - ); - } - - return $platform->getTrimExpression($stringPrimary, $trimMode); - } - - public function parse(Parser $parser): void - { - $lexer = $parser->getLexer(); - - $parser->match(TokenType::T_IDENTIFIER); - $parser->match(TokenType::T_OPEN_PARENTHESIS); - - $this->parseTrimMode($parser); - - if ($lexer->isNextToken(TokenType::T_STRING)) { - $parser->match(TokenType::T_STRING); - - assert($lexer->token !== null); - $this->trimChar = $lexer->token->value; - } - - if ($this->leading || $this->trailing || $this->both || ($this->trimChar !== false)) { - $parser->match(TokenType::T_FROM); - } - - $this->stringPrimary = $parser->StringPrimary(); - - $parser->match(TokenType::T_CLOSE_PARENTHESIS); - } - - /** @psalm-return TrimMode::* */ - private function getTrimMode(): TrimMode|int - { - if ($this->leading) { - return TrimMode::LEADING; - } - - if ($this->trailing) { - return TrimMode::TRAILING; - } - - if ($this->both) { - return TrimMode::BOTH; - } - - return TrimMode::UNSPECIFIED; - } - - private function parseTrimMode(Parser $parser): void - { - $lexer = $parser->getLexer(); - assert($lexer->lookahead !== null); - $value = $lexer->lookahead->value; - - if (strcasecmp('leading', $value) === 0) { - $parser->match(TokenType::T_LEADING); - - $this->leading = true; - - return; - } - - if (strcasecmp('trailing', $value) === 0) { - $parser->match(TokenType::T_TRAILING); - - $this->trailing = true; - - return; - } - - if (strcasecmp('both', $value) === 0) { - $parser->match(TokenType::T_BOTH); - - $this->both = true; - - return; - } - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Functions/UpperFunction.php b/vendor/doctrine/orm/src/Query/AST/Functions/UpperFunction.php deleted file mode 100644 index 1ecef66..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Functions/UpperFunction.php +++ /dev/null @@ -1,40 +0,0 @@ -walkSimpleArithmeticExpression($this->stringPrimary), - ); - } - - public function parse(Parser $parser): void - { - $parser->match(TokenType::T_IDENTIFIER); - $parser->match(TokenType::T_OPEN_PARENTHESIS); - - $this->stringPrimary = $parser->StringPrimary(); - - $parser->match(TokenType::T_CLOSE_PARENTHESIS); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/GeneralCaseExpression.php b/vendor/doctrine/orm/src/Query/AST/GeneralCaseExpression.php deleted file mode 100644 index 39d760a..0000000 --- a/vendor/doctrine/orm/src/Query/AST/GeneralCaseExpression.php +++ /dev/null @@ -1,27 +0,0 @@ -walkGeneralCaseExpression($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/GroupByClause.php b/vendor/doctrine/orm/src/Query/AST/GroupByClause.php deleted file mode 100644 index eb0f1b9..0000000 --- a/vendor/doctrine/orm/src/Query/AST/GroupByClause.php +++ /dev/null @@ -1,20 +0,0 @@ -walkGroupByClause($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/HavingClause.php b/vendor/doctrine/orm/src/Query/AST/HavingClause.php deleted file mode 100644 index 0d4d821..0000000 --- a/vendor/doctrine/orm/src/Query/AST/HavingClause.php +++ /dev/null @@ -1,19 +0,0 @@ -walkHavingClause($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/IdentificationVariableDeclaration.php b/vendor/doctrine/orm/src/Query/AST/IdentificationVariableDeclaration.php deleted file mode 100644 index c4c7cca..0000000 --- a/vendor/doctrine/orm/src/Query/AST/IdentificationVariableDeclaration.php +++ /dev/null @@ -1,28 +0,0 @@ -walkIdentificationVariableDeclaration($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/InListExpression.php b/vendor/doctrine/orm/src/Query/AST/InListExpression.php deleted file mode 100644 index dc0f32b..0000000 --- a/vendor/doctrine/orm/src/Query/AST/InListExpression.php +++ /dev/null @@ -1,23 +0,0 @@ - $literals */ - public function __construct( - public ArithmeticExpression $expression, - public array $literals, - public bool $not = false, - ) { - } - - public function dispatch(SqlWalker $walker): string - { - return $walker->walkInListExpression($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/InSubselectExpression.php b/vendor/doctrine/orm/src/Query/AST/InSubselectExpression.php deleted file mode 100644 index 1128285..0000000 --- a/vendor/doctrine/orm/src/Query/AST/InSubselectExpression.php +++ /dev/null @@ -1,22 +0,0 @@ -walkInSubselectExpression($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/IndexBy.php b/vendor/doctrine/orm/src/Query/AST/IndexBy.php deleted file mode 100644 index 3d90265..0000000 --- a/vendor/doctrine/orm/src/Query/AST/IndexBy.php +++ /dev/null @@ -1,26 +0,0 @@ -walkIndexBy($this); - - return ''; - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/InputParameter.php b/vendor/doctrine/orm/src/Query/AST/InputParameter.php deleted file mode 100644 index a8e0a3b..0000000 --- a/vendor/doctrine/orm/src/Query/AST/InputParameter.php +++ /dev/null @@ -1,35 +0,0 @@ -isNamed = ! is_numeric($param); - $this->name = $param; - } - - public function dispatch(SqlWalker $walker): string - { - return $walker->walkInputParameter($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/InstanceOfExpression.php b/vendor/doctrine/orm/src/Query/AST/InstanceOfExpression.php deleted file mode 100644 index 3a4e75f..0000000 --- a/vendor/doctrine/orm/src/Query/AST/InstanceOfExpression.php +++ /dev/null @@ -1,29 +0,0 @@ - $value */ - public function __construct( - public string $identificationVariable, - public array $value, - public bool $not = false, - ) { - } - - public function dispatch(SqlWalker $walker): string - { - return $walker->walkInstanceOfExpression($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Join.php b/vendor/doctrine/orm/src/Query/AST/Join.php deleted file mode 100644 index 34ce830..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Join.php +++ /dev/null @@ -1,34 +0,0 @@ -walkJoin($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/JoinAssociationDeclaration.php b/vendor/doctrine/orm/src/Query/AST/JoinAssociationDeclaration.php deleted file mode 100644 index e08d7f5..0000000 --- a/vendor/doctrine/orm/src/Query/AST/JoinAssociationDeclaration.php +++ /dev/null @@ -1,27 +0,0 @@ -walkJoinAssociationDeclaration($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/JoinAssociationPathExpression.php b/vendor/doctrine/orm/src/Query/AST/JoinAssociationPathExpression.php deleted file mode 100644 index 230be36..0000000 --- a/vendor/doctrine/orm/src/Query/AST/JoinAssociationPathExpression.php +++ /dev/null @@ -1,19 +0,0 @@ -walkJoinPathExpression($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/JoinVariableDeclaration.php b/vendor/doctrine/orm/src/Query/AST/JoinVariableDeclaration.php deleted file mode 100644 index bf76695..0000000 --- a/vendor/doctrine/orm/src/Query/AST/JoinVariableDeclaration.php +++ /dev/null @@ -1,24 +0,0 @@ -walkJoinVariableDeclaration($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/LikeExpression.php b/vendor/doctrine/orm/src/Query/AST/LikeExpression.php deleted file mode 100644 index e3f67f8..0000000 --- a/vendor/doctrine/orm/src/Query/AST/LikeExpression.php +++ /dev/null @@ -1,29 +0,0 @@ -walkLikeExpression($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Literal.php b/vendor/doctrine/orm/src/Query/AST/Literal.php deleted file mode 100644 index 9ec2036..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Literal.php +++ /dev/null @@ -1,26 +0,0 @@ -walkLiteral($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/NewObjectExpression.php b/vendor/doctrine/orm/src/Query/AST/NewObjectExpression.php deleted file mode 100644 index 7383c48..0000000 --- a/vendor/doctrine/orm/src/Query/AST/NewObjectExpression.php +++ /dev/null @@ -1,25 +0,0 @@ -walkNewObject($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Node.php b/vendor/doctrine/orm/src/Query/AST/Node.php deleted file mode 100644 index cdb5855..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Node.php +++ /dev/null @@ -1,85 +0,0 @@ -dump($this); - } - - public function dump(mixed $value): string - { - static $ident = 0; - - $str = ''; - - if ($value instanceof Node) { - $str .= get_debug_type($value) . '(' . PHP_EOL; - $props = get_object_vars($value); - - foreach ($props as $name => $prop) { - $ident += 4; - $str .= str_repeat(' ', $ident) . '"' . $name . '": ' - . $this->dump($prop) . ',' . PHP_EOL; - $ident -= 4; - } - - $str .= str_repeat(' ', $ident) . ')'; - } elseif (is_array($value)) { - $ident += 4; - $str .= 'array('; - $some = false; - - foreach ($value as $k => $v) { - $str .= PHP_EOL . str_repeat(' ', $ident) . '"' - . $k . '" => ' . $this->dump($v) . ','; - $some = true; - } - - $ident -= 4; - $str .= ($some ? PHP_EOL . str_repeat(' ', $ident) : '') . ')'; - } elseif (is_object($value)) { - $str .= 'instanceof(' . get_debug_type($value) . ')'; - } else { - $str .= var_export($value, true); - } - - return $str; - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/NullComparisonExpression.php b/vendor/doctrine/orm/src/Query/AST/NullComparisonExpression.php deleted file mode 100644 index e60cb04..0000000 --- a/vendor/doctrine/orm/src/Query/AST/NullComparisonExpression.php +++ /dev/null @@ -1,26 +0,0 @@ -walkNullComparisonExpression($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/NullIfExpression.php b/vendor/doctrine/orm/src/Query/AST/NullIfExpression.php deleted file mode 100644 index 6fffeeb..0000000 --- a/vendor/doctrine/orm/src/Query/AST/NullIfExpression.php +++ /dev/null @@ -1,24 +0,0 @@ -walkNullIfExpression($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/OrderByClause.php b/vendor/doctrine/orm/src/Query/AST/OrderByClause.php deleted file mode 100644 index f6d7a67..0000000 --- a/vendor/doctrine/orm/src/Query/AST/OrderByClause.php +++ /dev/null @@ -1,25 +0,0 @@ -walkOrderByClause($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/OrderByItem.php b/vendor/doctrine/orm/src/Query/AST/OrderByItem.php deleted file mode 100644 index 64b3f40..0000000 --- a/vendor/doctrine/orm/src/Query/AST/OrderByItem.php +++ /dev/null @@ -1,38 +0,0 @@ -type) === 'ASC'; - } - - public function isDesc(): bool - { - return strtoupper($this->type) === 'DESC'; - } - - public function dispatch(SqlWalker $walker): string - { - return $walker->walkOrderByItem($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/ParenthesisExpression.php b/vendor/doctrine/orm/src/Query/AST/ParenthesisExpression.php deleted file mode 100644 index cda6d19..0000000 --- a/vendor/doctrine/orm/src/Query/AST/ParenthesisExpression.php +++ /dev/null @@ -1,22 +0,0 @@ -walkParenthesisExpression($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/PathExpression.php b/vendor/doctrine/orm/src/Query/AST/PathExpression.php deleted file mode 100644 index 4a56fcd..0000000 --- a/vendor/doctrine/orm/src/Query/AST/PathExpression.php +++ /dev/null @@ -1,39 +0,0 @@ - $expectedType */ - public function __construct( - public int $expectedType, - public string $identificationVariable, - public string|null $field = null, - ) { - } - - public function dispatch(SqlWalker $walker): string - { - return $walker->walkPathExpression($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Phase2OptimizableConditional.php b/vendor/doctrine/orm/src/Query/AST/Phase2OptimizableConditional.php deleted file mode 100644 index 276f8f8..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Phase2OptimizableConditional.php +++ /dev/null @@ -1,17 +0,0 @@ -type) === 'ALL'; - } - - public function isAny(): bool - { - return strtoupper($this->type) === 'ANY'; - } - - public function isSome(): bool - { - return strtoupper($this->type) === 'SOME'; - } - - public function dispatch(SqlWalker $walker): string - { - return $walker->walkQuantifiedExpression($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/RangeVariableDeclaration.php b/vendor/doctrine/orm/src/Query/AST/RangeVariableDeclaration.php deleted file mode 100644 index 59bd5c8..0000000 --- a/vendor/doctrine/orm/src/Query/AST/RangeVariableDeclaration.php +++ /dev/null @@ -1,27 +0,0 @@ -walkRangeVariableDeclaration($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/SelectClause.php b/vendor/doctrine/orm/src/Query/AST/SelectClause.php deleted file mode 100644 index ad50e67..0000000 --- a/vendor/doctrine/orm/src/Query/AST/SelectClause.php +++ /dev/null @@ -1,27 +0,0 @@ -walkSelectClause($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/SelectExpression.php b/vendor/doctrine/orm/src/Query/AST/SelectExpression.php deleted file mode 100644 index f09f3cd..0000000 --- a/vendor/doctrine/orm/src/Query/AST/SelectExpression.php +++ /dev/null @@ -1,28 +0,0 @@ -walkSelectExpression($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/SelectStatement.php b/vendor/doctrine/orm/src/Query/AST/SelectStatement.php deleted file mode 100644 index 399462f..0000000 --- a/vendor/doctrine/orm/src/Query/AST/SelectStatement.php +++ /dev/null @@ -1,32 +0,0 @@ -walkSelectStatement($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/SimpleArithmeticExpression.php b/vendor/doctrine/orm/src/Query/AST/SimpleArithmeticExpression.php deleted file mode 100644 index ae7ca44..0000000 --- a/vendor/doctrine/orm/src/Query/AST/SimpleArithmeticExpression.php +++ /dev/null @@ -1,25 +0,0 @@ -walkSimpleArithmeticExpression($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/SimpleCaseExpression.php b/vendor/doctrine/orm/src/Query/AST/SimpleCaseExpression.php deleted file mode 100644 index b3764ba..0000000 --- a/vendor/doctrine/orm/src/Query/AST/SimpleCaseExpression.php +++ /dev/null @@ -1,28 +0,0 @@ -walkSimpleCaseExpression($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/SimpleSelectClause.php b/vendor/doctrine/orm/src/Query/AST/SimpleSelectClause.php deleted file mode 100644 index 0259e3b..0000000 --- a/vendor/doctrine/orm/src/Query/AST/SimpleSelectClause.php +++ /dev/null @@ -1,26 +0,0 @@ -walkSimpleSelectClause($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/SimpleSelectExpression.php b/vendor/doctrine/orm/src/Query/AST/SimpleSelectExpression.php deleted file mode 100644 index 97e8f08..0000000 --- a/vendor/doctrine/orm/src/Query/AST/SimpleSelectExpression.php +++ /dev/null @@ -1,27 +0,0 @@ -walkSimpleSelectExpression($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/SimpleWhenClause.php b/vendor/doctrine/orm/src/Query/AST/SimpleWhenClause.php deleted file mode 100644 index 892165a..0000000 --- a/vendor/doctrine/orm/src/Query/AST/SimpleWhenClause.php +++ /dev/null @@ -1,26 +0,0 @@ -walkWhenClauseExpression($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/Subselect.php b/vendor/doctrine/orm/src/Query/AST/Subselect.php deleted file mode 100644 index 8ff8595..0000000 --- a/vendor/doctrine/orm/src/Query/AST/Subselect.php +++ /dev/null @@ -1,32 +0,0 @@ -walkSubselect($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/SubselectFromClause.php b/vendor/doctrine/orm/src/Query/AST/SubselectFromClause.php deleted file mode 100644 index 7cf01e2..0000000 --- a/vendor/doctrine/orm/src/Query/AST/SubselectFromClause.php +++ /dev/null @@ -1,25 +0,0 @@ -walkSubselectFromClause($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/SubselectIdentificationVariableDeclaration.php b/vendor/doctrine/orm/src/Query/AST/SubselectIdentificationVariableDeclaration.php deleted file mode 100644 index eadf6bc..0000000 --- a/vendor/doctrine/orm/src/Query/AST/SubselectIdentificationVariableDeclaration.php +++ /dev/null @@ -1,19 +0,0 @@ -walkUpdateClause($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/UpdateItem.php b/vendor/doctrine/orm/src/Query/AST/UpdateItem.php deleted file mode 100644 index b540593..0000000 --- a/vendor/doctrine/orm/src/Query/AST/UpdateItem.php +++ /dev/null @@ -1,26 +0,0 @@ -walkUpdateItem($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/UpdateStatement.php b/vendor/doctrine/orm/src/Query/AST/UpdateStatement.php deleted file mode 100644 index 7ea5076..0000000 --- a/vendor/doctrine/orm/src/Query/AST/UpdateStatement.php +++ /dev/null @@ -1,26 +0,0 @@ -walkUpdateStatement($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/WhenClause.php b/vendor/doctrine/orm/src/Query/AST/WhenClause.php deleted file mode 100644 index 9bf194e..0000000 --- a/vendor/doctrine/orm/src/Query/AST/WhenClause.php +++ /dev/null @@ -1,26 +0,0 @@ -walkWhenClauseExpression($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/AST/WhereClause.php b/vendor/doctrine/orm/src/Query/AST/WhereClause.php deleted file mode 100644 index e4d7b66..0000000 --- a/vendor/doctrine/orm/src/Query/AST/WhereClause.php +++ /dev/null @@ -1,24 +0,0 @@ -walkWhereClause($this); - } -} diff --git a/vendor/doctrine/orm/src/Query/Exec/AbstractSqlExecutor.php b/vendor/doctrine/orm/src/Query/Exec/AbstractSqlExecutor.php deleted file mode 100644 index 101bf26..0000000 --- a/vendor/doctrine/orm/src/Query/Exec/AbstractSqlExecutor.php +++ /dev/null @@ -1,61 +0,0 @@ -, WrapperParameterType>|array - */ -abstract class AbstractSqlExecutor -{ - /** @var list|string */ - protected array|string $sqlStatements; - - protected QueryCacheProfile|null $queryCacheProfile = null; - - /** - * Gets the SQL statements that are executed by the executor. - * - * @return list|string All the SQL update statements. - */ - public function getSqlStatements(): array|string - { - return $this->sqlStatements; - } - - public function setQueryCacheProfile(QueryCacheProfile $qcp): void - { - $this->queryCacheProfile = $qcp; - } - - /** - * Do not use query cache - */ - public function removeQueryCacheProfile(): void - { - $this->queryCacheProfile = null; - } - - /** - * Executes all sql statements. - * - * @param Connection $conn The database connection that is used to execute the queries. - * @param list|array $params The parameters. - * @psalm-param WrapperParameterTypeArray $types The parameter types. - */ - abstract public function execute(Connection $conn, array $params, array $types): Result|int; -} diff --git a/vendor/doctrine/orm/src/Query/Exec/MultiTableDeleteExecutor.php b/vendor/doctrine/orm/src/Query/Exec/MultiTableDeleteExecutor.php deleted file mode 100644 index 6096462..0000000 --- a/vendor/doctrine/orm/src/Query/Exec/MultiTableDeleteExecutor.php +++ /dev/null @@ -1,131 +0,0 @@ -MultiTableDeleteExecutor. - * - * Internal note: Any SQL construction and preparation takes place in the constructor for - * best performance. With a query cache the executor will be cached. - * - * @param DeleteStatement $AST The root AST node of the DQL query. - * @param SqlWalker $sqlWalker The walker used for SQL generation from the AST. - */ - public function __construct(AST\Node $AST, SqlWalker $sqlWalker) - { - $em = $sqlWalker->getEntityManager(); - $conn = $em->getConnection(); - $platform = $conn->getDatabasePlatform(); - $quoteStrategy = $em->getConfiguration()->getQuoteStrategy(); - - if ($conn instanceof PrimaryReadReplicaConnection) { - $conn->ensureConnectedToPrimary(); - } - - $primaryClass = $em->getClassMetadata($AST->deleteClause->abstractSchemaName); - $primaryDqlAlias = $AST->deleteClause->aliasIdentificationVariable; - $rootClass = $em->getClassMetadata($primaryClass->rootEntityName); - - $tempTable = $platform->getTemporaryTableName($rootClass->getTemporaryIdTableName()); - $idColumnNames = $rootClass->getIdentifierColumnNames(); - $idColumnList = implode(', ', $idColumnNames); - - // 1. Create an INSERT INTO temptable ... SELECT identifiers WHERE $AST->getWhereClause() - $sqlWalker->setSQLTableAlias($primaryClass->getTableName(), 't0', $primaryDqlAlias); - - $insertSql = 'INSERT INTO ' . $tempTable . ' (' . $idColumnList . ')' - . ' SELECT t0.' . implode(', t0.', $idColumnNames); - - $rangeDecl = new AST\RangeVariableDeclaration($primaryClass->name, $primaryDqlAlias); - $fromClause = new AST\FromClause([new AST\IdentificationVariableDeclaration($rangeDecl, null, [])]); - $insertSql .= $sqlWalker->walkFromClause($fromClause); - - // Append WHERE clause, if there is one. - if ($AST->whereClause) { - $insertSql .= $sqlWalker->walkWhereClause($AST->whereClause); - } - - $this->insertSql = $insertSql; - - // 2. Create ID subselect statement used in DELETE ... WHERE ... IN (subselect) - $idSubselect = 'SELECT ' . $idColumnList . ' FROM ' . $tempTable; - - // 3. Create and store DELETE statements - $classNames = [...$primaryClass->parentClasses, ...[$primaryClass->name], ...$primaryClass->subClasses]; - foreach (array_reverse($classNames) as $className) { - $tableName = $quoteStrategy->getTableName($em->getClassMetadata($className), $platform); - $this->sqlStatements[] = 'DELETE FROM ' . $tableName - . ' WHERE (' . $idColumnList . ') IN (' . $idSubselect . ')'; - } - - // 4. Store DDL for temporary identifier table. - $columnDefinitions = []; - foreach ($idColumnNames as $idColumnName) { - $columnDefinitions[$idColumnName] = [ - 'name' => $idColumnName, - 'notnull' => true, - 'type' => Type::getType(PersisterHelper::getTypeOfColumn($idColumnName, $rootClass, $em)), - ]; - } - - $this->createTempTableSql = $platform->getCreateTemporaryTableSnippetSQL() . ' ' . $tempTable . ' (' - . $platform->getColumnDeclarationListSQL($columnDefinitions) . ', PRIMARY KEY(' . implode(',', $idColumnNames) . '))'; - $this->dropTempTableSql = $platform->getDropTemporaryTableSQL($tempTable); - } - - /** - * {@inheritDoc} - */ - public function execute(Connection $conn, array $params, array $types): int - { - // Create temporary id table - $conn->executeStatement($this->createTempTableSql); - - try { - // Insert identifiers - $numDeleted = $conn->executeStatement($this->insertSql, $params, $types); - - // Execute DELETE statements - foreach ($this->sqlStatements as $sql) { - $conn->executeStatement($sql); - } - } catch (Throwable $exception) { - // FAILURE! Drop temporary table to avoid possible collisions - $conn->executeStatement($this->dropTempTableSql); - - // Re-throw exception - throw $exception; - } - - // Drop temporary table - $conn->executeStatement($this->dropTempTableSql); - - return $numDeleted; - } -} diff --git a/vendor/doctrine/orm/src/Query/Exec/MultiTableUpdateExecutor.php b/vendor/doctrine/orm/src/Query/Exec/MultiTableUpdateExecutor.php deleted file mode 100644 index dab1b61..0000000 --- a/vendor/doctrine/orm/src/Query/Exec/MultiTableUpdateExecutor.php +++ /dev/null @@ -1,180 +0,0 @@ -MultiTableUpdateExecutor. - * - * Internal note: Any SQL construction and preparation takes place in the constructor for - * best performance. With a query cache the executor will be cached. - * - * @param UpdateStatement $AST The root AST node of the DQL query. - * @param SqlWalker $sqlWalker The walker used for SQL generation from the AST. - */ - public function __construct(AST\Node $AST, SqlWalker $sqlWalker) - { - $em = $sqlWalker->getEntityManager(); - $conn = $em->getConnection(); - $platform = $conn->getDatabasePlatform(); - $quoteStrategy = $em->getConfiguration()->getQuoteStrategy(); - $this->sqlStatements = []; - - if ($conn instanceof PrimaryReadReplicaConnection) { - $conn->ensureConnectedToPrimary(); - } - - $updateClause = $AST->updateClause; - $primaryClass = $sqlWalker->getEntityManager()->getClassMetadata($updateClause->abstractSchemaName); - $rootClass = $em->getClassMetadata($primaryClass->rootEntityName); - - $updateItems = $updateClause->updateItems; - - $tempTable = $platform->getTemporaryTableName($rootClass->getTemporaryIdTableName()); - $idColumnNames = $rootClass->getIdentifierColumnNames(); - $idColumnList = implode(', ', $idColumnNames); - - // 1. Create an INSERT INTO temptable ... SELECT identifiers WHERE $AST->getWhereClause() - $sqlWalker->setSQLTableAlias($primaryClass->getTableName(), 't0', $updateClause->aliasIdentificationVariable); - - $insertSql = 'INSERT INTO ' . $tempTable . ' (' . $idColumnList . ')' - . ' SELECT t0.' . implode(', t0.', $idColumnNames); - - $rangeDecl = new AST\RangeVariableDeclaration($primaryClass->name, $updateClause->aliasIdentificationVariable); - $fromClause = new AST\FromClause([new AST\IdentificationVariableDeclaration($rangeDecl, null, [])]); - - $insertSql .= $sqlWalker->walkFromClause($fromClause); - - // 2. Create ID subselect statement used in UPDATE ... WHERE ... IN (subselect) - $idSubselect = 'SELECT ' . $idColumnList . ' FROM ' . $tempTable; - - // 3. Create and store UPDATE statements - $classNames = [...$primaryClass->parentClasses, ...[$primaryClass->name], ...$primaryClass->subClasses]; - - foreach (array_reverse($classNames) as $className) { - $affected = false; - $class = $em->getClassMetadata($className); - $updateSql = 'UPDATE ' . $quoteStrategy->getTableName($class, $platform) . ' SET '; - - $sqlParameters = []; - foreach ($updateItems as $updateItem) { - $field = $updateItem->pathExpression->field; - - if ( - (isset($class->fieldMappings[$field]) && ! isset($class->fieldMappings[$field]->inherited)) || - (isset($class->associationMappings[$field]) && ! isset($class->associationMappings[$field]->inherited)) - ) { - $newValue = $updateItem->newValue; - - if (! $affected) { - $affected = true; - } else { - $updateSql .= ', '; - } - - $updateSql .= $sqlWalker->walkUpdateItem($updateItem); - - if ($newValue instanceof AST\InputParameter) { - $sqlParameters[] = $newValue->name; - - ++$this->numParametersInUpdateClause; - } - } - } - - if ($affected) { - $this->sqlParameters[] = $sqlParameters; - $this->sqlStatements[] = $updateSql . ' WHERE (' . $idColumnList . ') IN (' . $idSubselect . ')'; - } - } - - // Append WHERE clause to insertSql, if there is one. - if ($AST->whereClause) { - $insertSql .= $sqlWalker->walkWhereClause($AST->whereClause); - } - - $this->insertSql = $insertSql; - - // 4. Store DDL for temporary identifier table. - $columnDefinitions = []; - - foreach ($idColumnNames as $idColumnName) { - $columnDefinitions[$idColumnName] = [ - 'name' => $idColumnName, - 'notnull' => true, - 'type' => Type::getType(PersisterHelper::getTypeOfColumn($idColumnName, $rootClass, $em)), - ]; - } - - $this->createTempTableSql = $platform->getCreateTemporaryTableSnippetSQL() . ' ' . $tempTable . ' (' - . $platform->getColumnDeclarationListSQL($columnDefinitions) . ', PRIMARY KEY(' . implode(',', $idColumnNames) . '))'; - - $this->dropTempTableSql = $platform->getDropTemporaryTableSQL($tempTable); - } - - /** - * {@inheritDoc} - */ - public function execute(Connection $conn, array $params, array $types): int - { - // Create temporary id table - $conn->executeStatement($this->createTempTableSql); - - try { - // Insert identifiers. Parameters from the update clause are cut off. - $numUpdated = $conn->executeStatement( - $this->insertSql, - array_slice($params, $this->numParametersInUpdateClause), - array_slice($types, $this->numParametersInUpdateClause), - ); - - // Execute UPDATE statements - foreach ($this->sqlStatements as $key => $statement) { - $paramValues = []; - $paramTypes = []; - - if (isset($this->sqlParameters[$key])) { - foreach ($this->sqlParameters[$key] as $parameterKey => $parameterName) { - $paramValues[] = $params[$parameterKey]; - $paramTypes[] = $types[$parameterKey] ?? ParameterTypeInferer::inferType($params[$parameterKey]); - } - } - - $conn->executeStatement($statement, $paramValues, $paramTypes); - } - } finally { - // Drop temporary table - $conn->executeStatement($this->dropTempTableSql); - } - - return $numUpdated; - } -} diff --git a/vendor/doctrine/orm/src/Query/Exec/SingleSelectExecutor.php b/vendor/doctrine/orm/src/Query/Exec/SingleSelectExecutor.php deleted file mode 100644 index 5445edb..0000000 --- a/vendor/doctrine/orm/src/Query/Exec/SingleSelectExecutor.php +++ /dev/null @@ -1,31 +0,0 @@ -sqlStatements = $sqlWalker->walkSelectStatement($AST); - } - - /** - * {@inheritDoc} - */ - public function execute(Connection $conn, array $params, array $types): Result - { - return $conn->executeQuery($this->sqlStatements, $params, $types, $this->queryCacheProfile); - } -} diff --git a/vendor/doctrine/orm/src/Query/Exec/SingleTableDeleteUpdateExecutor.php b/vendor/doctrine/orm/src/Query/Exec/SingleTableDeleteUpdateExecutor.php deleted file mode 100644 index 66696db..0000000 --- a/vendor/doctrine/orm/src/Query/Exec/SingleTableDeleteUpdateExecutor.php +++ /dev/null @@ -1,42 +0,0 @@ -sqlStatements = $sqlWalker->walkUpdateStatement($AST); - } elseif ($AST instanceof AST\DeleteStatement) { - $this->sqlStatements = $sqlWalker->walkDeleteStatement($AST); - } - } - - /** - * {@inheritDoc} - */ - public function execute(Connection $conn, array $params, array $types): int - { - if ($conn instanceof PrimaryReadReplicaConnection) { - $conn->ensureConnectedToPrimary(); - } - - return $conn->executeStatement($this->sqlStatements, $params, $types); - } -} diff --git a/vendor/doctrine/orm/src/Query/Expr.php b/vendor/doctrine/orm/src/Query/Expr.php deleted file mode 100644 index 65f3082..0000000 --- a/vendor/doctrine/orm/src/Query/Expr.php +++ /dev/null @@ -1,615 +0,0 @@ -andX($expr->eq('u.type', ':1'), $expr->eq('u.role', ':2')); - * - * @param Expr\Comparison|Expr\Func|Expr\Andx|Expr\Orx|string ...$x Optional clause. Defaults to null, - * but requires at least one defined - * when converting to string. - */ - public function andX(Expr\Comparison|Expr\Func|Expr\Andx|Expr\Orx|string ...$x): Expr\Andx - { - self::validateVariadicParameter($x); - - return new Expr\Andx($x); - } - - /** - * Creates a disjunction of the given boolean expressions. - * - * Example: - * - * [php] - * // (u.type = ?1) OR (u.role = ?2) - * $q->where($q->expr()->orX('u.type = ?1', 'u.role = ?2')); - * - * @param Expr\Comparison|Expr\Func|Expr\Andx|Expr\Orx|string ...$x Optional clause. Defaults to null, - * but requires at least one defined - * when converting to string. - */ - public function orX(Expr\Comparison|Expr\Func|Expr\Andx|Expr\Orx|string ...$x): Expr\Orx - { - self::validateVariadicParameter($x); - - return new Expr\Orx($x); - } - - /** - * Creates an ASCending order expression. - */ - public function asc(mixed $expr): Expr\OrderBy - { - return new Expr\OrderBy($expr, 'ASC'); - } - - /** - * Creates a DESCending order expression. - */ - public function desc(mixed $expr): Expr\OrderBy - { - return new Expr\OrderBy($expr, 'DESC'); - } - - /** - * Creates an equality comparison expression with the given arguments. - * - * First argument is considered the left expression and the second is the right expression. - * When converted to string, it will generated a = . Example: - * - * [php] - * // u.id = ?1 - * $expr->eq('u.id', '?1'); - * - * @param mixed $x Left expression. - * @param mixed $y Right expression. - */ - public function eq(mixed $x, mixed $y): Expr\Comparison - { - return new Expr\Comparison($x, Expr\Comparison::EQ, $y); - } - - /** - * Creates an instance of Expr\Comparison, with the given arguments. - * First argument is considered the left expression and the second is the right expression. - * When converted to string, it will generated a <> . Example: - * - * [php] - * // u.id <> ?1 - * $q->where($q->expr()->neq('u.id', '?1')); - * - * @param mixed $x Left expression. - * @param mixed $y Right expression. - */ - public function neq(mixed $x, mixed $y): Expr\Comparison - { - return new Expr\Comparison($x, Expr\Comparison::NEQ, $y); - } - - /** - * Creates an instance of Expr\Comparison, with the given arguments. - * First argument is considered the left expression and the second is the right expression. - * When converted to string, it will generated a < . Example: - * - * [php] - * // u.id < ?1 - * $q->where($q->expr()->lt('u.id', '?1')); - * - * @param mixed $x Left expression. - * @param mixed $y Right expression. - */ - public function lt(mixed $x, mixed $y): Expr\Comparison - { - return new Expr\Comparison($x, Expr\Comparison::LT, $y); - } - - /** - * Creates an instance of Expr\Comparison, with the given arguments. - * First argument is considered the left expression and the second is the right expression. - * When converted to string, it will generated a <= . Example: - * - * [php] - * // u.id <= ?1 - * $q->where($q->expr()->lte('u.id', '?1')); - * - * @param mixed $x Left expression. - * @param mixed $y Right expression. - */ - public function lte(mixed $x, mixed $y): Expr\Comparison - { - return new Expr\Comparison($x, Expr\Comparison::LTE, $y); - } - - /** - * Creates an instance of Expr\Comparison, with the given arguments. - * First argument is considered the left expression and the second is the right expression. - * When converted to string, it will generated a > . Example: - * - * [php] - * // u.id > ?1 - * $q->where($q->expr()->gt('u.id', '?1')); - * - * @param mixed $x Left expression. - * @param mixed $y Right expression. - */ - public function gt(mixed $x, mixed $y): Expr\Comparison - { - return new Expr\Comparison($x, Expr\Comparison::GT, $y); - } - - /** - * Creates an instance of Expr\Comparison, with the given arguments. - * First argument is considered the left expression and the second is the right expression. - * When converted to string, it will generated a >= . Example: - * - * [php] - * // u.id >= ?1 - * $q->where($q->expr()->gte('u.id', '?1')); - * - * @param mixed $x Left expression. - * @param mixed $y Right expression. - */ - public function gte(mixed $x, mixed $y): Expr\Comparison - { - return new Expr\Comparison($x, Expr\Comparison::GTE, $y); - } - - /** - * Creates an instance of AVG() function, with the given argument. - * - * @param mixed $x Argument to be used in AVG() function. - */ - public function avg(mixed $x): Expr\Func - { - return new Expr\Func('AVG', [$x]); - } - - /** - * Creates an instance of MAX() function, with the given argument. - * - * @param mixed $x Argument to be used in MAX() function. - */ - public function max(mixed $x): Expr\Func - { - return new Expr\Func('MAX', [$x]); - } - - /** - * Creates an instance of MIN() function, with the given argument. - * - * @param mixed $x Argument to be used in MIN() function. - */ - public function min(mixed $x): Expr\Func - { - return new Expr\Func('MIN', [$x]); - } - - /** - * Creates an instance of COUNT() function, with the given argument. - * - * @param mixed $x Argument to be used in COUNT() function. - */ - public function count(mixed $x): Expr\Func - { - return new Expr\Func('COUNT', [$x]); - } - - /** - * Creates an instance of COUNT(DISTINCT) function, with the given argument. - * - * @param mixed ...$x Argument to be used in COUNT(DISTINCT) function. - */ - public function countDistinct(mixed ...$x): string - { - self::validateVariadicParameter($x); - - return 'COUNT(DISTINCT ' . implode(', ', $x) . ')'; - } - - /** - * Creates an instance of EXISTS() function, with the given DQL Subquery. - * - * @param mixed $subquery DQL Subquery to be used in EXISTS() function. - */ - public function exists(mixed $subquery): Expr\Func - { - return new Expr\Func('EXISTS', [$subquery]); - } - - /** - * Creates an instance of ALL() function, with the given DQL Subquery. - * - * @param mixed $subquery DQL Subquery to be used in ALL() function. - */ - public function all(mixed $subquery): Expr\Func - { - return new Expr\Func('ALL', [$subquery]); - } - - /** - * Creates a SOME() function expression with the given DQL subquery. - * - * @param mixed $subquery DQL Subquery to be used in SOME() function. - */ - public function some(mixed $subquery): Expr\Func - { - return new Expr\Func('SOME', [$subquery]); - } - - /** - * Creates an ANY() function expression with the given DQL subquery. - * - * @param mixed $subquery DQL Subquery to be used in ANY() function. - */ - public function any(mixed $subquery): Expr\Func - { - return new Expr\Func('ANY', [$subquery]); - } - - /** - * Creates a negation expression of the given restriction. - * - * @param mixed $restriction Restriction to be used in NOT() function. - */ - public function not(mixed $restriction): Expr\Func - { - return new Expr\Func('NOT', [$restriction]); - } - - /** - * Creates an ABS() function expression with the given argument. - * - * @param mixed $x Argument to be used in ABS() function. - */ - public function abs(mixed $x): Expr\Func - { - return new Expr\Func('ABS', [$x]); - } - - /** - * Creates a MOD($x, $y) function expression to return the remainder of $x divided by $y. - */ - public function mod(mixed $x, mixed $y): Expr\Func - { - return new Expr\Func('MOD', [$x, $y]); - } - - /** - * Creates a product mathematical expression with the given arguments. - * - * First argument is considered the left expression and the second is the right expression. - * When converted to string, it will generated a * . Example: - * - * [php] - * // u.salary * u.percentAnnualSalaryIncrease - * $q->expr()->prod('u.salary', 'u.percentAnnualSalaryIncrease') - * - * @param mixed $x Left expression. - * @param mixed $y Right expression. - */ - public function prod(mixed $x, mixed $y): Expr\Math - { - return new Expr\Math($x, '*', $y); - } - - /** - * Creates a difference mathematical expression with the given arguments. - * First argument is considered the left expression and the second is the right expression. - * When converted to string, it will generated a - . Example: - * - * [php] - * // u.monthlySubscriptionCount - 1 - * $q->expr()->diff('u.monthlySubscriptionCount', '1') - * - * @param mixed $x Left expression. - * @param mixed $y Right expression. - */ - public function diff(mixed $x, mixed $y): Expr\Math - { - return new Expr\Math($x, '-', $y); - } - - /** - * Creates a sum mathematical expression with the given arguments. - * First argument is considered the left expression and the second is the right expression. - * When converted to string, it will generated a + . Example: - * - * [php] - * // u.numChildren + 1 - * $q->expr()->sum('u.numChildren', '1') - * - * @param mixed $x Left expression. - * @param mixed $y Right expression. - */ - public function sum(mixed $x, mixed $y): Expr\Math - { - return new Expr\Math($x, '+', $y); - } - - /** - * Creates a quotient mathematical expression with the given arguments. - * First argument is considered the left expression and the second is the right expression. - * When converted to string, it will generated a / . Example: - * - * [php] - * // u.total / u.period - * $expr->quot('u.total', 'u.period') - * - * @param mixed $x Left expression. - * @param mixed $y Right expression. - */ - public function quot(mixed $x, mixed $y): Expr\Math - { - return new Expr\Math($x, '/', $y); - } - - /** - * Creates a SQRT() function expression with the given argument. - * - * @param mixed $x Argument to be used in SQRT() function. - */ - public function sqrt(mixed $x): Expr\Func - { - return new Expr\Func('SQRT', [$x]); - } - - /** - * Creates an IN() expression with the given arguments. - * - * @param string $x Field in string format to be restricted by IN() function. - * @param mixed $y Argument to be used in IN() function. - */ - public function in(string $x, mixed $y): Expr\Func - { - if (is_iterable($y)) { - if ($y instanceof Traversable) { - $y = iterator_to_array($y); - } - - foreach ($y as &$literal) { - if (! ($literal instanceof Expr\Literal)) { - $literal = $this->quoteLiteral($literal); - } - } - } - - return new Expr\Func($x . ' IN', (array) $y); - } - - /** - * Creates a NOT IN() expression with the given arguments. - * - * @param string $x Field in string format to be restricted by NOT IN() function. - * @param mixed $y Argument to be used in NOT IN() function. - */ - public function notIn(string $x, mixed $y): Expr\Func - { - if (is_iterable($y)) { - if ($y instanceof Traversable) { - $y = iterator_to_array($y); - } - - foreach ($y as &$literal) { - if (! ($literal instanceof Expr\Literal)) { - $literal = $this->quoteLiteral($literal); - } - } - } - - return new Expr\Func($x . ' NOT IN', (array) $y); - } - - /** - * Creates an IS NULL expression with the given arguments. - * - * @param string $x Field in string format to be restricted by IS NULL. - */ - public function isNull(string $x): string - { - return $x . ' IS NULL'; - } - - /** - * Creates an IS NOT NULL expression with the given arguments. - * - * @param string $x Field in string format to be restricted by IS NOT NULL. - */ - public function isNotNull(string $x): string - { - return $x . ' IS NOT NULL'; - } - - /** - * Creates a LIKE() comparison expression with the given arguments. - * - * @param string $x Field in string format to be inspected by LIKE() comparison. - * @param mixed $y Argument to be used in LIKE() comparison. - */ - public function like(string $x, mixed $y): Expr\Comparison - { - return new Expr\Comparison($x, 'LIKE', $y); - } - - /** - * Creates a NOT LIKE() comparison expression with the given arguments. - * - * @param string $x Field in string format to be inspected by LIKE() comparison. - * @param mixed $y Argument to be used in LIKE() comparison. - */ - public function notLike(string $x, mixed $y): Expr\Comparison - { - return new Expr\Comparison($x, 'NOT LIKE', $y); - } - - /** - * Creates a CONCAT() function expression with the given arguments. - * - * @param mixed ...$x Arguments to be used in CONCAT() function. - */ - public function concat(mixed ...$x): Expr\Func - { - self::validateVariadicParameter($x); - - return new Expr\Func('CONCAT', $x); - } - - /** - * Creates a SUBSTRING() function expression with the given arguments. - * - * @param mixed $x Argument to be used as string to be cropped by SUBSTRING() function. - * @param int $from Initial offset to start cropping string. May accept negative values. - * @param int|null $len Length of crop. May accept negative values. - */ - public function substring(mixed $x, int $from, int|null $len = null): Expr\Func - { - $args = [$x, $from]; - if ($len !== null) { - $args[] = $len; - } - - return new Expr\Func('SUBSTRING', $args); - } - - /** - * Creates a LOWER() function expression with the given argument. - * - * @param mixed $x Argument to be used in LOWER() function. - * - * @return Expr\Func A LOWER function expression. - */ - public function lower(mixed $x): Expr\Func - { - return new Expr\Func('LOWER', [$x]); - } - - /** - * Creates an UPPER() function expression with the given argument. - * - * @param mixed $x Argument to be used in UPPER() function. - * - * @return Expr\Func An UPPER function expression. - */ - public function upper(mixed $x): Expr\Func - { - return new Expr\Func('UPPER', [$x]); - } - - /** - * Creates a LENGTH() function expression with the given argument. - * - * @param mixed $x Argument to be used as argument of LENGTH() function. - * - * @return Expr\Func A LENGTH function expression. - */ - public function length(mixed $x): Expr\Func - { - return new Expr\Func('LENGTH', [$x]); - } - - /** - * Creates a literal expression of the given argument. - * - * @param scalar $literal Argument to be converted to literal. - */ - public function literal(bool|string|int|float $literal): Expr\Literal - { - return new Expr\Literal($this->quoteLiteral($literal)); - } - - /** - * Quotes a literal value, if necessary, according to the DQL syntax. - * - * @param scalar $literal The literal value. - */ - private function quoteLiteral(bool|string|int|float $literal): string - { - if (is_int($literal) || is_float($literal)) { - return (string) $literal; - } - - if (is_bool($literal)) { - return $literal ? 'true' : 'false'; - } - - return "'" . str_replace("'", "''", $literal) . "'"; - } - - /** - * Creates an instance of BETWEEN() function, with the given argument. - * - * @param mixed $val Valued to be inspected by range values. - * @param int|string $x Starting range value to be used in BETWEEN() function. - * @param int|string $y End point value to be used in BETWEEN() function. - * - * @return string A BETWEEN expression. - */ - public function between(mixed $val, int|string $x, int|string $y): string - { - return $val . ' BETWEEN ' . $x . ' AND ' . $y; - } - - /** - * Creates an instance of TRIM() function, with the given argument. - * - * @param mixed $x Argument to be used as argument of TRIM() function. - * - * @return Expr\Func a TRIM expression. - */ - public function trim(mixed $x): Expr\Func - { - return new Expr\Func('TRIM', $x); - } - - /** - * Creates an instance of MEMBER OF function, with the given arguments. - * - * @param string $x Value to be checked - * @param string $y Value to be checked against - */ - public function isMemberOf(string $x, string $y): Expr\Comparison - { - return new Expr\Comparison($x, 'MEMBER OF', $y); - } - - /** - * Creates an instance of INSTANCE OF function, with the given arguments. - * - * @param string $x Value to be checked - * @param string $y Value to be checked against - */ - public function isInstanceOf(string $x, string $y): Expr\Comparison - { - return new Expr\Comparison($x, 'INSTANCE OF', $y); - } -} diff --git a/vendor/doctrine/orm/src/Query/Expr/Andx.php b/vendor/doctrine/orm/src/Query/Expr/Andx.php deleted file mode 100644 index a20bcef..0000000 --- a/vendor/doctrine/orm/src/Query/Expr/Andx.php +++ /dev/null @@ -1,32 +0,0 @@ - */ - protected array $parts = []; - - /** @psalm-return list */ - public function getParts(): array - { - return $this->parts; - } -} diff --git a/vendor/doctrine/orm/src/Query/Expr/Base.php b/vendor/doctrine/orm/src/Query/Expr/Base.php deleted file mode 100644 index e0f2572..0000000 --- a/vendor/doctrine/orm/src/Query/Expr/Base.php +++ /dev/null @@ -1,96 +0,0 @@ - */ - protected array $allowedClasses = []; - - /** @var list */ - protected array $parts = []; - - public function __construct(mixed $args = []) - { - if (is_array($args) && array_key_exists(0, $args) && is_array($args[0])) { - $args = $args[0]; - } - - $this->addMultiple($args); - } - - /** - * @param string[]|object[]|string|object $args - * @psalm-param list|string|object $args - * - * @return $this - */ - public function addMultiple(array|string|object $args = []): static - { - foreach ((array) $args as $arg) { - $this->add($arg); - } - - return $this; - } - - /** - * @return $this - * - * @throws InvalidArgumentException - */ - public function add(mixed $arg): static - { - if ($arg !== null && (! $arg instanceof self || $arg->count() > 0)) { - // If we decide to keep Expr\Base instances, we can use this check - if (! is_string($arg) && ! in_array($arg::class, $this->allowedClasses, true)) { - throw new InvalidArgumentException(sprintf( - "Expression of type '%s' not allowed in this context.", - get_debug_type($arg), - )); - } - - $this->parts[] = $arg; - } - - return $this; - } - - /** @psalm-return 0|positive-int */ - public function count(): int - { - return count($this->parts); - } - - public function __toString(): string - { - if ($this->count() === 1) { - return (string) $this->parts[0]; - } - - return $this->preSeparator . implode($this->separator, $this->parts) . $this->postSeparator; - } -} diff --git a/vendor/doctrine/orm/src/Query/Expr/Comparison.php b/vendor/doctrine/orm/src/Query/Expr/Comparison.php deleted file mode 100644 index ec8ef21..0000000 --- a/vendor/doctrine/orm/src/Query/Expr/Comparison.php +++ /dev/null @@ -1,47 +0,0 @@ -'; - final public const LT = '<'; - final public const LTE = '<='; - final public const GT = '>'; - final public const GTE = '>='; - - /** Creates a comparison expression with the given arguments. */ - public function __construct(protected mixed $leftExpr, protected string $operator, protected mixed $rightExpr) - { - } - - public function getLeftExpr(): mixed - { - return $this->leftExpr; - } - - public function getOperator(): string - { - return $this->operator; - } - - public function getRightExpr(): mixed - { - return $this->rightExpr; - } - - public function __toString(): string - { - return $this->leftExpr . ' ' . $this->operator . ' ' . $this->rightExpr; - } -} diff --git a/vendor/doctrine/orm/src/Query/Expr/Composite.php b/vendor/doctrine/orm/src/Query/Expr/Composite.php deleted file mode 100644 index f3007a7..0000000 --- a/vendor/doctrine/orm/src/Query/Expr/Composite.php +++ /dev/null @@ -1,50 +0,0 @@ -count() === 1) { - return (string) $this->parts[0]; - } - - $components = []; - - foreach ($this->parts as $part) { - $components[] = $this->processQueryPart($part); - } - - return implode($this->separator, $components); - } - - private function processQueryPart(string|Stringable $part): string - { - $queryPart = (string) $part; - - if (is_object($part) && $part instanceof self && $part->count() > 1) { - return $this->preSeparator . $queryPart . $this->postSeparator; - } - - // Fixes DDC-1237: User may have added a where item containing nested expression (with "OR" or "AND") - if (preg_match('/\s(OR|AND)\s/i', $queryPart)) { - return $this->preSeparator . $queryPart . $this->postSeparator; - } - - return $queryPart; - } -} diff --git a/vendor/doctrine/orm/src/Query/Expr/From.php b/vendor/doctrine/orm/src/Query/Expr/From.php deleted file mode 100644 index 21af078..0000000 --- a/vendor/doctrine/orm/src/Query/Expr/From.php +++ /dev/null @@ -1,48 +0,0 @@ -from; - } - - public function getAlias(): string - { - return $this->alias; - } - - public function getIndexBy(): string|null - { - return $this->indexBy; - } - - public function __toString(): string - { - return $this->from . ' ' . $this->alias . - ($this->indexBy ? ' INDEX BY ' . $this->indexBy : ''); - } -} diff --git a/vendor/doctrine/orm/src/Query/Expr/Func.php b/vendor/doctrine/orm/src/Query/Expr/Func.php deleted file mode 100644 index cd9e8e0..0000000 --- a/vendor/doctrine/orm/src/Query/Expr/Func.php +++ /dev/null @@ -1,48 +0,0 @@ -|mixed $arguments - */ - public function __construct( - protected string $name, - mixed $arguments, - ) { - $this->arguments = (array) $arguments; - } - - public function getName(): string - { - return $this->name; - } - - /** @psalm-return list */ - public function getArguments(): array - { - return $this->arguments; - } - - public function __toString(): string - { - return $this->name . '(' . implode(', ', $this->arguments) . ')'; - } -} diff --git a/vendor/doctrine/orm/src/Query/Expr/GroupBy.php b/vendor/doctrine/orm/src/Query/Expr/GroupBy.php deleted file mode 100644 index fa4625a..0000000 --- a/vendor/doctrine/orm/src/Query/Expr/GroupBy.php +++ /dev/null @@ -1,25 +0,0 @@ - */ - protected array $parts = []; - - /** @psalm-return list */ - public function getParts(): array - { - return $this->parts; - } -} diff --git a/vendor/doctrine/orm/src/Query/Expr/Join.php b/vendor/doctrine/orm/src/Query/Expr/Join.php deleted file mode 100644 index c3b6dc9..0000000 --- a/vendor/doctrine/orm/src/Query/Expr/Join.php +++ /dev/null @@ -1,77 +0,0 @@ -joinType; - } - - public function getJoin(): string - { - return $this->join; - } - - public function getAlias(): string|null - { - return $this->alias; - } - - /** @psalm-return self::ON|self::WITH|null */ - public function getConditionType(): string|null - { - return $this->conditionType; - } - - public function getCondition(): string|Comparison|Composite|Func|null - { - return $this->condition; - } - - public function getIndexBy(): string|null - { - return $this->indexBy; - } - - public function __toString(): string - { - return strtoupper($this->joinType) . ' JOIN ' . $this->join - . ($this->alias ? ' ' . $this->alias : '') - . ($this->indexBy ? ' INDEX BY ' . $this->indexBy : '') - . ($this->condition ? ' ' . strtoupper($this->conditionType) . ' ' . $this->condition : ''); - } -} diff --git a/vendor/doctrine/orm/src/Query/Expr/Literal.php b/vendor/doctrine/orm/src/Query/Expr/Literal.php deleted file mode 100644 index 0c13030..0000000 --- a/vendor/doctrine/orm/src/Query/Expr/Literal.php +++ /dev/null @@ -1,25 +0,0 @@ - */ - protected array $parts = []; - - /** @psalm-return list */ - public function getParts(): array - { - return $this->parts; - } -} diff --git a/vendor/doctrine/orm/src/Query/Expr/Math.php b/vendor/doctrine/orm/src/Query/Expr/Math.php deleted file mode 100644 index 05e0b39..0000000 --- a/vendor/doctrine/orm/src/Query/Expr/Math.php +++ /dev/null @@ -1,59 +0,0 @@ -leftExpr; - } - - public function getOperator(): string - { - return $this->operator; - } - - public function getRightExpr(): mixed - { - return $this->rightExpr; - } - - public function __toString(): string - { - // Adjusting Left Expression - $leftExpr = (string) $this->leftExpr; - - if ($this->leftExpr instanceof Math) { - $leftExpr = '(' . $leftExpr . ')'; - } - - // Adjusting Right Expression - $rightExpr = (string) $this->rightExpr; - - if ($this->rightExpr instanceof Math) { - $rightExpr = '(' . $rightExpr . ')'; - } - - return $leftExpr . ' ' . $this->operator . ' ' . $rightExpr; - } -} diff --git a/vendor/doctrine/orm/src/Query/Expr/OrderBy.php b/vendor/doctrine/orm/src/Query/Expr/OrderBy.php deleted file mode 100644 index ac9e160..0000000 --- a/vendor/doctrine/orm/src/Query/Expr/OrderBy.php +++ /dev/null @@ -1,60 +0,0 @@ - */ - protected array $parts = []; - - public function __construct( - string|null $sort = null, - string|null $order = null, - ) { - if ($sort) { - $this->add($sort, $order); - } - } - - public function add(string $sort, string|null $order = null): void - { - $order = ! $order ? 'ASC' : $order; - $this->parts[] = $sort . ' ' . $order; - } - - /** @psalm-return 0|positive-int */ - public function count(): int - { - return count($this->parts); - } - - /** @psalm-return list */ - public function getParts(): array - { - return $this->parts; - } - - public function __toString(): string - { - return $this->preSeparator . implode($this->separator, $this->parts) . $this->postSeparator; - } -} diff --git a/vendor/doctrine/orm/src/Query/Expr/Orx.php b/vendor/doctrine/orm/src/Query/Expr/Orx.php deleted file mode 100644 index 2ae2332..0000000 --- a/vendor/doctrine/orm/src/Query/Expr/Orx.php +++ /dev/null @@ -1,32 +0,0 @@ - */ - protected array $parts = []; - - /** @psalm-return list */ - public function getParts(): array - { - return $this->parts; - } -} diff --git a/vendor/doctrine/orm/src/Query/Expr/Select.php b/vendor/doctrine/orm/src/Query/Expr/Select.php deleted file mode 100644 index 91b0b60..0000000 --- a/vendor/doctrine/orm/src/Query/Expr/Select.php +++ /dev/null @@ -1,28 +0,0 @@ - */ - protected array $parts = []; - - /** @psalm-return list */ - public function getParts(): array - { - return $this->parts; - } -} diff --git a/vendor/doctrine/orm/src/Query/Filter/FilterException.php b/vendor/doctrine/orm/src/Query/Filter/FilterException.php deleted file mode 100644 index 37f12bc..0000000 --- a/vendor/doctrine/orm/src/Query/Filter/FilterException.php +++ /dev/null @@ -1,23 +0,0 @@ - - */ - private array $parameters = []; - - final public function __construct( - private readonly EntityManagerInterface $em, - ) { - } - - /** - * Sets a parameter list that can be used by the filter. - * - * @param array $values List of parameter values. - * @param string $type The parameter type. If specified, the given value will be run through - * the type conversion of this type. - * - * @return $this - */ - final public function setParameterList(string $name, array $values, string $type = Types::STRING): static - { - $this->parameters[$name] = ['value' => $values, 'type' => $type, 'is_list' => true]; - - // Keep the parameters sorted for the hash - ksort($this->parameters); - - // The filter collection of the EM is now dirty - $this->em->getFilters()->setFiltersStateDirty(); - - return $this; - } - - /** - * Sets a parameter that can be used by the filter. - * - * @param string|null $type The parameter type. If specified, the given value will be run through - * the type conversion of this type. This is usually not needed for - * strings and numeric types. - * - * @return $this - */ - final public function setParameter(string $name, mixed $value, string|null $type = null): static - { - if ($type === null) { - $type = ParameterTypeInferer::inferType($value); - } - - $this->parameters[$name] = ['value' => $value, 'type' => $type, 'is_list' => false]; - - // Keep the parameters sorted for the hash - ksort($this->parameters); - - // The filter collection of the EM is now dirty - $this->em->getFilters()->setFiltersStateDirty(); - - return $this; - } - - /** - * Gets a parameter to use in a query. - * - * The function is responsible for the right output escaping to use the - * value in a query. - * - * @return string The SQL escaped parameter to use in a query. - * - * @throws InvalidArgumentException - */ - final public function getParameter(string $name): string - { - if (! isset($this->parameters[$name])) { - throw new InvalidArgumentException("Parameter '" . $name . "' does not exist."); - } - - if ($this->parameters[$name]['is_list']) { - throw FilterException::cannotConvertListParameterIntoSingleValue($name); - } - - return $this->em->getConnection()->quote((string) $this->parameters[$name]['value']); - } - - /** - * Gets a parameter to use in a query assuming it's a list of entries. - * - * The function is responsible for the right output escaping to use the - * value in a query, separating each entry by comma to inline it into - * an IN() query part. - * - * @throws InvalidArgumentException - */ - final public function getParameterList(string $name): string - { - if (! isset($this->parameters[$name])) { - throw new InvalidArgumentException("Parameter '" . $name . "' does not exist."); - } - - if ($this->parameters[$name]['is_list'] === false) { - throw FilterException::cannotConvertSingleParameterIntoListValue($name); - } - - $param = $this->parameters[$name]; - $connection = $this->em->getConnection(); - - $quoted = array_map( - static fn (mixed $value): string => $connection->quote((string) $value), - $param['value'], - ); - - return implode(',', $quoted); - } - - /** - * Checks if a parameter was set for the filter. - */ - final public function hasParameter(string $name): bool - { - return isset($this->parameters[$name]); - } - - /** - * Returns as string representation of the SQLFilter parameters (the state). - */ - final public function __toString(): string - { - return serialize($this->parameters); - } - - /** - * Returns the database connection used by the entity manager - */ - final protected function getConnection(): Connection - { - return $this->em->getConnection(); - } - - /** - * Gets the SQL query part to add to a query. - * - * @psalm-param ClassMetadata $targetEntity - * - * @return string The constraint SQL if there is available, empty string otherwise. - */ - abstract public function addFilterConstraint(ClassMetadata $targetEntity, string $targetTableAlias): string; -} diff --git a/vendor/doctrine/orm/src/Query/FilterCollection.php b/vendor/doctrine/orm/src/Query/FilterCollection.php deleted file mode 100644 index 3d3c576..0000000 --- a/vendor/doctrine/orm/src/Query/FilterCollection.php +++ /dev/null @@ -1,260 +0,0 @@ - - */ - private array $enabledFilters = []; - - /** The filter hash from the last time the query was parsed. */ - private string $filterHash = ''; - - /** - * Instances of suspended filters. - * - * @var SQLFilter[] - * @psalm-var array - */ - private array $suspendedFilters = []; - - /** - * The current state of this filter. - * - * @psalm-var self::FILTERS_STATE_* - */ - private int $filtersState = self::FILTERS_STATE_CLEAN; - - public function __construct( - private readonly EntityManagerInterface $em, - ) { - $this->config = $em->getConfiguration(); - } - - /** - * Gets all the enabled filters. - * - * @return array The enabled filters. - */ - public function getEnabledFilters(): array - { - return $this->enabledFilters; - } - - /** - * Gets all the suspended filters. - * - * @return SQLFilter[] The suspended filters. - * @psalm-return array - */ - public function getSuspendedFilters(): array - { - return $this->suspendedFilters; - } - - /** - * Enables a filter from the collection. - * - * @throws InvalidArgumentException If the filter does not exist. - */ - public function enable(string $name): SQLFilter - { - if (! $this->has($name)) { - throw new InvalidArgumentException("Filter '" . $name . "' does not exist."); - } - - if (! $this->isEnabled($name)) { - $filterClass = $this->config->getFilterClassName($name); - - assert($filterClass !== null); - - $this->enabledFilters[$name] = new $filterClass($this->em); - - // In case a suspended filter with the same name was forgotten - unset($this->suspendedFilters[$name]); - - // Keep the enabled filters sorted for the hash - ksort($this->enabledFilters); - - $this->setFiltersStateDirty(); - } - - return $this->enabledFilters[$name]; - } - - /** - * Disables a filter. - * - * @throws InvalidArgumentException If the filter does not exist. - */ - public function disable(string $name): SQLFilter - { - // Get the filter to return it - $filter = $this->getFilter($name); - - unset($this->enabledFilters[$name]); - - $this->setFiltersStateDirty(); - - return $filter; - } - - /** - * Suspend a filter. - * - * @param string $name Name of the filter. - * - * @return SQLFilter The suspended filter. - * - * @throws InvalidArgumentException If the filter does not exist. - */ - public function suspend(string $name): SQLFilter - { - // Get the filter to return it - $filter = $this->getFilter($name); - - $this->suspendedFilters[$name] = $filter; - unset($this->enabledFilters[$name]); - - $this->setFiltersStateDirty(); - - return $filter; - } - - /** - * Restore a disabled filter from the collection. - * - * @param string $name Name of the filter. - * - * @return SQLFilter The restored filter. - * - * @throws InvalidArgumentException If the filter does not exist. - */ - public function restore(string $name): SQLFilter - { - if (! $this->isSuspended($name)) { - throw new InvalidArgumentException("Filter '" . $name . "' is not suspended."); - } - - $this->enabledFilters[$name] = $this->suspendedFilters[$name]; - unset($this->suspendedFilters[$name]); - - // Keep the enabled filters sorted for the hash - ksort($this->enabledFilters); - - $this->setFiltersStateDirty(); - - return $this->enabledFilters[$name]; - } - - /** - * Gets an enabled filter from the collection. - * - * @throws InvalidArgumentException If the filter is not enabled. - */ - public function getFilter(string $name): SQLFilter - { - if (! $this->isEnabled($name)) { - throw new InvalidArgumentException("Filter '" . $name . "' is not enabled."); - } - - return $this->enabledFilters[$name]; - } - - /** - * Checks whether filter with given name is defined. - */ - public function has(string $name): bool - { - return $this->config->getFilterClassName($name) !== null; - } - - /** - * Checks if a filter is enabled. - */ - public function isEnabled(string $name): bool - { - return isset($this->enabledFilters[$name]); - } - - /** - * Checks if a filter is suspended. - * - * @param string $name Name of the filter. - * - * @return bool True if the filter is suspended, false otherwise. - */ - public function isSuspended(string $name): bool - { - return isset($this->suspendedFilters[$name]); - } - - /** - * Checks if the filter collection is clean. - */ - public function isClean(): bool - { - return $this->filtersState === self::FILTERS_STATE_CLEAN; - } - - /** - * Generates a string of currently enabled filters to use for the cache id. - */ - public function getHash(): string - { - // If there are only clean filters, the previous hash can be returned - if ($this->filtersState === self::FILTERS_STATE_CLEAN) { - return $this->filterHash; - } - - $filterHash = ''; - - foreach ($this->enabledFilters as $name => $filter) { - $filterHash .= $name . $filter; - } - - $this->filterHash = $filterHash; - $this->filtersState = self::FILTERS_STATE_CLEAN; - - return $filterHash; - } - - /** - * Sets the filter state to dirty. - */ - public function setFiltersStateDirty(): void - { - $this->filtersState = self::FILTERS_STATE_DIRTY; - } -} diff --git a/vendor/doctrine/orm/src/Query/Lexer.php b/vendor/doctrine/orm/src/Query/Lexer.php deleted file mode 100644 index c446675..0000000 --- a/vendor/doctrine/orm/src/Query/Lexer.php +++ /dev/null @@ -1,150 +0,0 @@ - - */ -class Lexer extends AbstractLexer -{ - /** - * Creates a new query scanner object. - * - * @param string $input A query string. - */ - public function __construct(string $input) - { - $this->setInput($input); - } - - /** - * {@inheritDoc} - */ - protected function getCatchablePatterns(): array - { - return [ - '[a-z_][a-z0-9_]*\:[a-z_][a-z0-9_]*(?:\\\[a-z_][a-z0-9_]*)*', // aliased name - '[a-z_\\\][a-z0-9_]*(?:\\\[a-z_][a-z0-9_]*)*', // identifier or qualified name - '(?:[0-9]+(?:[\.][0-9]+)*)(?:e[+-]?[0-9]+)?', // numbers - "'(?:[^']|'')*'", // quoted strings - '\?[0-9]*|:[a-z_][a-z0-9_]*', // parameters - ]; - } - - /** - * {@inheritDoc} - */ - protected function getNonCatchablePatterns(): array - { - return ['\s+', '--.*', '(.)']; - } - - protected function getType(string &$value): TokenType - { - $type = TokenType::T_NONE; - - switch (true) { - // Recognize numeric values - case is_numeric($value): - if (str_contains($value, '.') || stripos($value, 'e') !== false) { - return TokenType::T_FLOAT; - } - - return TokenType::T_INTEGER; - - // Recognize quoted strings - case $value[0] === "'": - $value = str_replace("''", "'", substr($value, 1, strlen($value) - 2)); - - return TokenType::T_STRING; - - // Recognize identifiers, aliased or qualified names - case ctype_alpha($value[0]) || $value[0] === '_' || $value[0] === '\\': - $name = 'Doctrine\ORM\Query\TokenType::T_' . strtoupper($value); - - if (defined($name)) { - $type = constant($name); - - if ($type->value > 100) { - return $type; - } - } - - if (str_contains($value, '\\')) { - return TokenType::T_FULLY_QUALIFIED_NAME; - } - - return TokenType::T_IDENTIFIER; - - // Recognize input parameters - case $value[0] === '?' || $value[0] === ':': - return TokenType::T_INPUT_PARAMETER; - - // Recognize symbols - case $value === '.': - return TokenType::T_DOT; - - case $value === ',': - return TokenType::T_COMMA; - - case $value === '(': - return TokenType::T_OPEN_PARENTHESIS; - - case $value === ')': - return TokenType::T_CLOSE_PARENTHESIS; - - case $value === '=': - return TokenType::T_EQUALS; - - case $value === '>': - return TokenType::T_GREATER_THAN; - - case $value === '<': - return TokenType::T_LOWER_THAN; - - case $value === '+': - return TokenType::T_PLUS; - - case $value === '-': - return TokenType::T_MINUS; - - case $value === '*': - return TokenType::T_MULTIPLY; - - case $value === '/': - return TokenType::T_DIVIDE; - - case $value === '!': - return TokenType::T_NEGATE; - - case $value === '{': - return TokenType::T_OPEN_CURLY_BRACE; - - case $value === '}': - return TokenType::T_CLOSE_CURLY_BRACE; - - // Default - default: - // Do nothing - } - - return $type; - } -} diff --git a/vendor/doctrine/orm/src/Query/Parameter.php b/vendor/doctrine/orm/src/Query/Parameter.php deleted file mode 100644 index 43eb7a4..0000000 --- a/vendor/doctrine/orm/src/Query/Parameter.php +++ /dev/null @@ -1,89 +0,0 @@ -name = self::normalizeName($name); - $this->typeSpecified = $type !== null; - - $this->setValue($value, $type); - } - - /** - * Retrieves the Parameter name. - */ - public function getName(): string - { - return $this->name; - } - - /** - * Retrieves the Parameter value. - */ - public function getValue(): mixed - { - return $this->value; - } - - /** - * Retrieves the Parameter type. - */ - public function getType(): mixed - { - return $this->type; - } - - /** - * Defines the Parameter value. - */ - public function setValue(mixed $value, mixed $type = null): void - { - $this->value = $value; - $this->type = $type ?: ParameterTypeInferer::inferType($value); - } - - public function typeWasSpecified(): bool - { - return $this->typeSpecified; - } -} diff --git a/vendor/doctrine/orm/src/Query/ParameterTypeInferer.php b/vendor/doctrine/orm/src/Query/ParameterTypeInferer.php deleted file mode 100644 index dae28fa..0000000 --- a/vendor/doctrine/orm/src/Query/ParameterTypeInferer.php +++ /dev/null @@ -1,77 +0,0 @@ -value) - ? Types::INTEGER - : Types::STRING; - } - - if (is_array($value)) { - $firstValue = current($value); - if ($firstValue instanceof BackedEnum) { - $firstValue = $firstValue->value; - } - - return is_int($firstValue) - ? ArrayParameterType::INTEGER - : ArrayParameterType::STRING; - } - - return ParameterType::STRING; - } - - private function __construct() - { - } -} diff --git a/vendor/doctrine/orm/src/Query/Parser.php b/vendor/doctrine/orm/src/Query/Parser.php deleted file mode 100644 index e948f2c..0000000 --- a/vendor/doctrine/orm/src/Query/Parser.php +++ /dev/null @@ -1,3269 +0,0 @@ - - * @psalm-type QueryComponent = array{ - * metadata?: ClassMetadata, - * parent?: string|null, - * relation?: AssociationMapping|null, - * map?: string|null, - * resultVariable?: AST\Node|string, - * nestingLevel: int, - * token: DqlToken, - * } - */ -final class Parser -{ - /** - * @readonly Maps BUILT-IN string function names to AST class names. - * @psalm-var array> - */ - private static array $stringFunctions = [ - 'concat' => Functions\ConcatFunction::class, - 'substring' => Functions\SubstringFunction::class, - 'trim' => Functions\TrimFunction::class, - 'lower' => Functions\LowerFunction::class, - 'upper' => Functions\UpperFunction::class, - 'identity' => Functions\IdentityFunction::class, - ]; - - /** - * @readonly Maps BUILT-IN numeric function names to AST class names. - * @psalm-var array> - */ - private static array $numericFunctions = [ - 'length' => Functions\LengthFunction::class, - 'locate' => Functions\LocateFunction::class, - 'abs' => Functions\AbsFunction::class, - 'sqrt' => Functions\SqrtFunction::class, - 'mod' => Functions\ModFunction::class, - 'size' => Functions\SizeFunction::class, - 'date_diff' => Functions\DateDiffFunction::class, - 'bit_and' => Functions\BitAndFunction::class, - 'bit_or' => Functions\BitOrFunction::class, - - // Aggregate functions - 'min' => Functions\MinFunction::class, - 'max' => Functions\MaxFunction::class, - 'avg' => Functions\AvgFunction::class, - 'sum' => Functions\SumFunction::class, - 'count' => Functions\CountFunction::class, - ]; - - /** - * @readonly Maps BUILT-IN datetime function names to AST class names. - * @psalm-var array> - */ - private static array $datetimeFunctions = [ - 'current_date' => Functions\CurrentDateFunction::class, - 'current_time' => Functions\CurrentTimeFunction::class, - 'current_timestamp' => Functions\CurrentTimestampFunction::class, - 'date_add' => Functions\DateAddFunction::class, - 'date_sub' => Functions\DateSubFunction::class, - ]; - - /* - * Expressions that were encountered during parsing of identifiers and expressions - * and still need to be validated. - */ - - /** @psalm-var list */ - private array $deferredIdentificationVariables = []; - - /** @psalm-var list */ - private array $deferredPathExpressions = []; - - /** @psalm-var list */ - private array $deferredResultVariables = []; - - /** @psalm-var list */ - private array $deferredNewObjectExpressions = []; - - /** - * The lexer. - */ - private readonly Lexer $lexer; - - /** - * The parser result. - */ - private readonly ParserResult $parserResult; - - /** - * The EntityManager. - */ - private readonly EntityManagerInterface $em; - - /** - * Map of declared query components in the parsed query. - * - * @psalm-var array - */ - private array $queryComponents = []; - - /** - * Keeps the nesting level of defined ResultVariables. - */ - private int $nestingLevel = 0; - - /** - * Any additional custom tree walkers that modify the AST. - * - * @psalm-var list> - */ - private array $customTreeWalkers = []; - - /** - * The custom last tree walker, if any, that is responsible for producing the output. - * - * @var class-string|null - */ - private $customOutputWalker; - - /** @psalm-var array */ - private array $identVariableExpressions = []; - - /** - * Creates a new query parser object. - * - * @param Query $query The Query to parse. - */ - public function __construct(private readonly Query $query) - { - $this->em = $query->getEntityManager(); - $this->lexer = new Lexer((string) $query->getDQL()); - $this->parserResult = new ParserResult(); - } - - /** - * Sets a custom tree walker that produces output. - * This tree walker will be run last over the AST, after any other walkers. - * - * @psalm-param class-string $className - */ - public function setCustomOutputTreeWalker(string $className): void - { - $this->customOutputWalker = $className; - } - - /** - * Adds a custom tree walker for modifying the AST. - * - * @psalm-param class-string $className - */ - public function addCustomTreeWalker(string $className): void - { - $this->customTreeWalkers[] = $className; - } - - /** - * Gets the lexer used by the parser. - */ - public function getLexer(): Lexer - { - return $this->lexer; - } - - /** - * Gets the ParserResult that is being filled with information during parsing. - */ - public function getParserResult(): ParserResult - { - return $this->parserResult; - } - - /** - * Gets the EntityManager used by the parser. - */ - public function getEntityManager(): EntityManagerInterface - { - return $this->em; - } - - /** - * Parses and builds AST for the given Query. - */ - public function getAST(): AST\SelectStatement|AST\UpdateStatement|AST\DeleteStatement - { - // Parse & build AST - $AST = $this->QueryLanguage(); - - // Process any deferred validations of some nodes in the AST. - // This also allows post-processing of the AST for modification purposes. - $this->processDeferredIdentificationVariables(); - - if ($this->deferredPathExpressions) { - $this->processDeferredPathExpressions(); - } - - if ($this->deferredResultVariables) { - $this->processDeferredResultVariables(); - } - - if ($this->deferredNewObjectExpressions) { - $this->processDeferredNewObjectExpressions($AST); - } - - $this->processRootEntityAliasSelected(); - - // TODO: Is there a way to remove this? It may impact the mixed hydration resultset a lot! - $this->fixIdentificationVariableOrder($AST); - - return $AST; - } - - /** - * Attempts to match the given token with the current lookahead token. - * - * If they match, updates the lookahead token; otherwise raises a syntax - * error. - * - * @throws QueryException If the tokens don't match. - */ - public function match(TokenType $token): void - { - $lookaheadType = $this->lexer->lookahead->type ?? null; - - // Short-circuit on first condition, usually types match - if ($lookaheadType === $token) { - $this->lexer->moveNext(); - - return; - } - - // If parameter is not identifier (1-99) must be exact match - if ($token->value < TokenType::T_IDENTIFIER->value) { - $this->syntaxError($this->lexer->getLiteral($token)); - } - - // If parameter is keyword (200+) must be exact match - if ($token->value > TokenType::T_IDENTIFIER->value) { - $this->syntaxError($this->lexer->getLiteral($token)); - } - - // If parameter is T_IDENTIFIER, then matches T_IDENTIFIER (100) and keywords (200+) - if ($token->value === TokenType::T_IDENTIFIER->value && $lookaheadType->value < TokenType::T_IDENTIFIER->value) { - $this->syntaxError($this->lexer->getLiteral($token)); - } - - $this->lexer->moveNext(); - } - - /** - * Frees this parser, enabling it to be reused. - * - * @param bool $deep Whether to clean peek and reset errors. - * @param int $position Position to reset. - */ - public function free(bool $deep = false, int $position = 0): void - { - // WARNING! Use this method with care. It resets the scanner! - $this->lexer->resetPosition($position); - - // Deep = true cleans peek and also any previously defined errors - if ($deep) { - $this->lexer->resetPeek(); - } - - $this->lexer->token = null; - $this->lexer->lookahead = null; - } - - /** - * Parses a query string. - */ - public function parse(): ParserResult - { - $AST = $this->getAST(); - - $customWalkers = $this->query->getHint(Query::HINT_CUSTOM_TREE_WALKERS); - if ($customWalkers !== false) { - $this->customTreeWalkers = $customWalkers; - } - - $customOutputWalker = $this->query->getHint(Query::HINT_CUSTOM_OUTPUT_WALKER); - if ($customOutputWalker !== false) { - $this->customOutputWalker = $customOutputWalker; - } - - // Run any custom tree walkers over the AST - if ($this->customTreeWalkers) { - $treeWalkerChain = new TreeWalkerChain($this->query, $this->parserResult, $this->queryComponents); - - foreach ($this->customTreeWalkers as $walker) { - $treeWalkerChain->addTreeWalker($walker); - } - - match (true) { - $AST instanceof AST\UpdateStatement => $treeWalkerChain->walkUpdateStatement($AST), - $AST instanceof AST\DeleteStatement => $treeWalkerChain->walkDeleteStatement($AST), - $AST instanceof AST\SelectStatement => $treeWalkerChain->walkSelectStatement($AST), - }; - - $this->queryComponents = $treeWalkerChain->getQueryComponents(); - } - - $outputWalkerClass = $this->customOutputWalker ?: SqlWalker::class; - $outputWalker = new $outputWalkerClass($this->query, $this->parserResult, $this->queryComponents); - - // Assign an SQL executor to the parser result - $this->parserResult->setSqlExecutor($outputWalker->getExecutor($AST)); - - return $this->parserResult; - } - - /** - * Fixes order of identification variables. - * - * They have to appear in the select clause in the same order as the - * declarations (from ... x join ... y join ... z ...) appear in the query - * as the hydration process relies on that order for proper operation. - */ - private function fixIdentificationVariableOrder(AST\SelectStatement|AST\DeleteStatement|AST\UpdateStatement $AST): void - { - if (count($this->identVariableExpressions) <= 1) { - return; - } - - assert($AST instanceof AST\SelectStatement); - - foreach ($this->queryComponents as $dqlAlias => $qComp) { - if (! isset($this->identVariableExpressions[$dqlAlias])) { - continue; - } - - $expr = $this->identVariableExpressions[$dqlAlias]; - $key = array_search($expr, $AST->selectClause->selectExpressions, true); - - unset($AST->selectClause->selectExpressions[$key]); - - $AST->selectClause->selectExpressions[] = $expr; - } - } - - /** - * Generates a new syntax error. - * - * @param string $expected Expected string. - * @param DqlToken|null $token Got token. - * - * @throws QueryException - */ - public function syntaxError(string $expected = '', Token|null $token = null): never - { - if ($token === null) { - $token = $this->lexer->lookahead; - } - - $tokenPos = $token->position ?? '-1'; - - $message = sprintf('line 0, col %d: Error: ', $tokenPos); - $message .= $expected !== '' ? sprintf('Expected %s, got ', $expected) : 'Unexpected '; - $message .= $this->lexer->lookahead === null ? 'end of string.' : sprintf("'%s'", $token->value); - - throw QueryException::syntaxError($message, QueryException::dqlError($this->query->getDQL() ?? '')); - } - - /** - * Generates a new semantical error. - * - * @param string $message Optional message. - * @psalm-param DqlToken|null $token - * - * @throws QueryException - */ - public function semanticalError(string $message = '', Token|null $token = null): never - { - if ($token === null) { - $token = $this->lexer->lookahead ?? new Token('fake token', 42, 0); - } - - // Minimum exposed chars ahead of token - $distance = 12; - - // Find a position of a final word to display in error string - $dql = $this->query->getDQL(); - $length = strlen($dql); - $pos = $token->position + $distance; - $pos = strpos($dql, ' ', $length > $pos ? $pos : $length); - $length = $pos !== false ? $pos - $token->position : $distance; - - $tokenPos = $token->position > 0 ? $token->position : '-1'; - $tokenStr = substr($dql, $token->position, $length); - - // Building informative message - $message = 'line 0, col ' . $tokenPos . " near '" . $tokenStr . "': Error: " . $message; - - throw QueryException::semanticalError($message, QueryException::dqlError($this->query->getDQL())); - } - - /** - * Peeks beyond the matched closing parenthesis and returns the first token after that one. - * - * @param bool $resetPeek Reset peek after finding the closing parenthesis. - * - * @psalm-return DqlToken|null - */ - private function peekBeyondClosingParenthesis(bool $resetPeek = true): Token|null - { - $token = $this->lexer->peek(); - $numUnmatched = 1; - - while ($numUnmatched > 0 && $token !== null) { - switch ($token->type) { - case TokenType::T_OPEN_PARENTHESIS: - ++$numUnmatched; - break; - - case TokenType::T_CLOSE_PARENTHESIS: - --$numUnmatched; - break; - - default: - // Do nothing - } - - $token = $this->lexer->peek(); - } - - if ($resetPeek) { - $this->lexer->resetPeek(); - } - - return $token; - } - - /** - * Checks if the given token indicates a mathematical operator. - * - * @psalm-param DqlToken|null $token - */ - private function isMathOperator(Token|null $token): bool - { - return $token !== null && in_array($token->type, [TokenType::T_PLUS, TokenType::T_MINUS, TokenType::T_DIVIDE, TokenType::T_MULTIPLY], true); - } - - /** - * Checks if the next-next (after lookahead) token starts a function. - * - * @return bool TRUE if the next-next tokens start a function, FALSE otherwise. - */ - private function isFunction(): bool - { - assert($this->lexer->lookahead !== null); - $lookaheadType = $this->lexer->lookahead->type; - $peek = $this->lexer->peek(); - - $this->lexer->resetPeek(); - - return $lookaheadType->value >= TokenType::T_IDENTIFIER->value && $peek !== null && $peek->type === TokenType::T_OPEN_PARENTHESIS; - } - - /** - * Checks whether the given token type indicates an aggregate function. - * - * @return bool TRUE if the token type is an aggregate function, FALSE otherwise. - */ - private function isAggregateFunction(TokenType $tokenType): bool - { - return in_array( - $tokenType, - [TokenType::T_AVG, TokenType::T_MIN, TokenType::T_MAX, TokenType::T_SUM, TokenType::T_COUNT], - true, - ); - } - - /** - * Checks whether the current lookahead token of the lexer has the type T_ALL, T_ANY or T_SOME. - */ - private function isNextAllAnySome(): bool - { - assert($this->lexer->lookahead !== null); - - return in_array( - $this->lexer->lookahead->type, - [TokenType::T_ALL, TokenType::T_ANY, TokenType::T_SOME], - true, - ); - } - - /** - * Validates that the given IdentificationVariable is semantically correct. - * It must exist in query components list. - */ - private function processDeferredIdentificationVariables(): void - { - foreach ($this->deferredIdentificationVariables as $deferredItem) { - $identVariable = $deferredItem['expression']; - - // Check if IdentificationVariable exists in queryComponents - if (! isset($this->queryComponents[$identVariable])) { - $this->semanticalError( - sprintf("'%s' is not defined.", $identVariable), - $deferredItem['token'], - ); - } - - $qComp = $this->queryComponents[$identVariable]; - - // Check if queryComponent points to an AbstractSchemaName or a ResultVariable - if (! isset($qComp['metadata'])) { - $this->semanticalError( - sprintf("'%s' does not point to a Class.", $identVariable), - $deferredItem['token'], - ); - } - - // Validate if identification variable nesting level is lower or equal than the current one - if ($qComp['nestingLevel'] > $deferredItem['nestingLevel']) { - $this->semanticalError( - sprintf("'%s' is used outside the scope of its declaration.", $identVariable), - $deferredItem['token'], - ); - } - } - } - - /** - * Validates that the given NewObjectExpression. - */ - private function processDeferredNewObjectExpressions(AST\SelectStatement $AST): void - { - foreach ($this->deferredNewObjectExpressions as $deferredItem) { - $expression = $deferredItem['expression']; - $token = $deferredItem['token']; - $className = $expression->className; - $args = $expression->args; - $fromClassName = $AST->fromClause->identificationVariableDeclarations[0]->rangeVariableDeclaration->abstractSchemaName ?? null; - - // If the namespace is not given then assumes the first FROM entity namespace - if (! str_contains($className, '\\') && ! class_exists($className) && is_string($fromClassName) && str_contains($fromClassName, '\\')) { - $namespace = substr($fromClassName, 0, strrpos($fromClassName, '\\')); - $fqcn = $namespace . '\\' . $className; - - if (class_exists($fqcn)) { - $expression->className = $fqcn; - $className = $fqcn; - } - } - - if (! class_exists($className)) { - $this->semanticalError(sprintf('Class "%s" is not defined.', $className), $token); - } - - $class = new ReflectionClass($className); - - if (! $class->isInstantiable()) { - $this->semanticalError(sprintf('Class "%s" can not be instantiated.', $className), $token); - } - - if ($class->getConstructor() === null) { - $this->semanticalError(sprintf('Class "%s" has not a valid constructor.', $className), $token); - } - - if ($class->getConstructor()->getNumberOfRequiredParameters() > count($args)) { - $this->semanticalError(sprintf('Number of arguments does not match with "%s" constructor declaration.', $className), $token); - } - } - } - - /** - * Validates that the given ResultVariable is semantically correct. - * It must exist in query components list. - */ - private function processDeferredResultVariables(): void - { - foreach ($this->deferredResultVariables as $deferredItem) { - $resultVariable = $deferredItem['expression']; - - // Check if ResultVariable exists in queryComponents - if (! isset($this->queryComponents[$resultVariable])) { - $this->semanticalError( - sprintf("'%s' is not defined.", $resultVariable), - $deferredItem['token'], - ); - } - - $qComp = $this->queryComponents[$resultVariable]; - - // Check if queryComponent points to an AbstractSchemaName or a ResultVariable - if (! isset($qComp['resultVariable'])) { - $this->semanticalError( - sprintf("'%s' does not point to a ResultVariable.", $resultVariable), - $deferredItem['token'], - ); - } - - // Validate if identification variable nesting level is lower or equal than the current one - if ($qComp['nestingLevel'] > $deferredItem['nestingLevel']) { - $this->semanticalError( - sprintf("'%s' is used outside the scope of its declaration.", $resultVariable), - $deferredItem['token'], - ); - } - } - } - - /** - * Validates that the given PathExpression is semantically correct for grammar rules: - * - * AssociationPathExpression ::= CollectionValuedPathExpression | SingleValuedAssociationPathExpression - * SingleValuedPathExpression ::= StateFieldPathExpression | SingleValuedAssociationPathExpression - * StateFieldPathExpression ::= IdentificationVariable "." StateField - * SingleValuedAssociationPathExpression ::= IdentificationVariable "." SingleValuedAssociationField - * CollectionValuedPathExpression ::= IdentificationVariable "." CollectionValuedAssociationField - */ - private function processDeferredPathExpressions(): void - { - foreach ($this->deferredPathExpressions as $deferredItem) { - $pathExpression = $deferredItem['expression']; - - $class = $this->getMetadataForDqlAlias($pathExpression->identificationVariable); - - $field = $pathExpression->field; - if ($field === null) { - $field = $pathExpression->field = $class->identifier[0]; - } - - // Check if field or association exists - if (! isset($class->associationMappings[$field]) && ! isset($class->fieldMappings[$field])) { - $this->semanticalError( - 'Class ' . $class->name . ' has no field or association named ' . $field, - $deferredItem['token'], - ); - } - - $fieldType = AST\PathExpression::TYPE_STATE_FIELD; - - if (isset($class->associationMappings[$field])) { - $assoc = $class->associationMappings[$field]; - - $fieldType = $assoc->isToOne() - ? AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION - : AST\PathExpression::TYPE_COLLECTION_VALUED_ASSOCIATION; - } - - // Validate if PathExpression is one of the expected types - $expectedType = $pathExpression->expectedType; - - if (! ($expectedType & $fieldType)) { - // We need to recognize which was expected type(s) - $expectedStringTypes = []; - - // Validate state field type - if ($expectedType & AST\PathExpression::TYPE_STATE_FIELD) { - $expectedStringTypes[] = 'StateFieldPathExpression'; - } - - // Validate single valued association (*-to-one) - if ($expectedType & AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION) { - $expectedStringTypes[] = 'SingleValuedAssociationField'; - } - - // Validate single valued association (*-to-many) - if ($expectedType & AST\PathExpression::TYPE_COLLECTION_VALUED_ASSOCIATION) { - $expectedStringTypes[] = 'CollectionValuedAssociationField'; - } - - // Build the error message - $semanticalError = 'Invalid PathExpression. '; - $semanticalError .= count($expectedStringTypes) === 1 - ? 'Must be a ' . $expectedStringTypes[0] . '.' - : implode(' or ', $expectedStringTypes) . ' expected.'; - - $this->semanticalError($semanticalError, $deferredItem['token']); - } - - // We need to force the type in PathExpression - $pathExpression->type = $fieldType; - } - } - - private function processRootEntityAliasSelected(): void - { - if (! count($this->identVariableExpressions)) { - return; - } - - foreach ($this->identVariableExpressions as $dqlAlias => $expr) { - if (isset($this->queryComponents[$dqlAlias]) && ! isset($this->queryComponents[$dqlAlias]['parent'])) { - return; - } - } - - $this->semanticalError('Cannot select entity through identification variables without choosing at least one root entity alias.'); - } - - /** - * QueryLanguage ::= SelectStatement | UpdateStatement | DeleteStatement - */ - public function QueryLanguage(): AST\SelectStatement|AST\UpdateStatement|AST\DeleteStatement - { - $statement = null; - - $this->lexer->moveNext(); - - switch ($this->lexer->lookahead->type ?? null) { - case TokenType::T_SELECT: - $statement = $this->SelectStatement(); - break; - - case TokenType::T_UPDATE: - $statement = $this->UpdateStatement(); - break; - - case TokenType::T_DELETE: - $statement = $this->DeleteStatement(); - break; - - default: - $this->syntaxError('SELECT, UPDATE or DELETE'); - break; - } - - // Check for end of string - if ($this->lexer->lookahead !== null) { - $this->syntaxError('end of string'); - } - - return $statement; - } - - /** - * SelectStatement ::= SelectClause FromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause] - */ - public function SelectStatement(): AST\SelectStatement - { - $selectStatement = new AST\SelectStatement($this->SelectClause(), $this->FromClause()); - - $selectStatement->whereClause = $this->lexer->isNextToken(TokenType::T_WHERE) ? $this->WhereClause() : null; - $selectStatement->groupByClause = $this->lexer->isNextToken(TokenType::T_GROUP) ? $this->GroupByClause() : null; - $selectStatement->havingClause = $this->lexer->isNextToken(TokenType::T_HAVING) ? $this->HavingClause() : null; - $selectStatement->orderByClause = $this->lexer->isNextToken(TokenType::T_ORDER) ? $this->OrderByClause() : null; - - return $selectStatement; - } - - /** - * UpdateStatement ::= UpdateClause [WhereClause] - */ - public function UpdateStatement(): AST\UpdateStatement - { - $updateStatement = new AST\UpdateStatement($this->UpdateClause()); - - $updateStatement->whereClause = $this->lexer->isNextToken(TokenType::T_WHERE) ? $this->WhereClause() : null; - - return $updateStatement; - } - - /** - * DeleteStatement ::= DeleteClause [WhereClause] - */ - public function DeleteStatement(): AST\DeleteStatement - { - $deleteStatement = new AST\DeleteStatement($this->DeleteClause()); - - $deleteStatement->whereClause = $this->lexer->isNextToken(TokenType::T_WHERE) ? $this->WhereClause() : null; - - return $deleteStatement; - } - - /** - * IdentificationVariable ::= identifier - */ - public function IdentificationVariable(): string - { - $this->match(TokenType::T_IDENTIFIER); - - assert($this->lexer->token !== null); - $identVariable = $this->lexer->token->value; - - $this->deferredIdentificationVariables[] = [ - 'expression' => $identVariable, - 'nestingLevel' => $this->nestingLevel, - 'token' => $this->lexer->token, - ]; - - return $identVariable; - } - - /** - * AliasIdentificationVariable = identifier - */ - public function AliasIdentificationVariable(): string - { - $this->match(TokenType::T_IDENTIFIER); - - assert($this->lexer->token !== null); - $aliasIdentVariable = $this->lexer->token->value; - $exists = isset($this->queryComponents[$aliasIdentVariable]); - - if ($exists) { - $this->semanticalError( - sprintf("'%s' is already defined.", $aliasIdentVariable), - $this->lexer->token, - ); - } - - return $aliasIdentVariable; - } - - /** - * AbstractSchemaName ::= fully_qualified_name | identifier - */ - public function AbstractSchemaName(): string - { - if ($this->lexer->isNextToken(TokenType::T_FULLY_QUALIFIED_NAME)) { - $this->match(TokenType::T_FULLY_QUALIFIED_NAME); - assert($this->lexer->token !== null); - - return $this->lexer->token->value; - } - - $this->match(TokenType::T_IDENTIFIER); - assert($this->lexer->token !== null); - - return $this->lexer->token->value; - } - - /** - * Validates an AbstractSchemaName, making sure the class exists. - * - * @param string $schemaName The name to validate. - * - * @throws QueryException if the name does not exist. - */ - private function validateAbstractSchemaName(string $schemaName): void - { - assert($this->lexer->token !== null); - if (! (class_exists($schemaName, true) || interface_exists($schemaName, true))) { - $this->semanticalError( - sprintf("Class '%s' is not defined.", $schemaName), - $this->lexer->token, - ); - } - } - - /** - * AliasResultVariable ::= identifier - */ - public function AliasResultVariable(): string - { - $this->match(TokenType::T_IDENTIFIER); - - assert($this->lexer->token !== null); - $resultVariable = $this->lexer->token->value; - $exists = isset($this->queryComponents[$resultVariable]); - - if ($exists) { - $this->semanticalError( - sprintf("'%s' is already defined.", $resultVariable), - $this->lexer->token, - ); - } - - return $resultVariable; - } - - /** - * ResultVariable ::= identifier - */ - public function ResultVariable(): string - { - $this->match(TokenType::T_IDENTIFIER); - - assert($this->lexer->token !== null); - $resultVariable = $this->lexer->token->value; - - // Defer ResultVariable validation - $this->deferredResultVariables[] = [ - 'expression' => $resultVariable, - 'nestingLevel' => $this->nestingLevel, - 'token' => $this->lexer->token, - ]; - - return $resultVariable; - } - - /** - * JoinAssociationPathExpression ::= IdentificationVariable "." (CollectionValuedAssociationField | SingleValuedAssociationField) - */ - public function JoinAssociationPathExpression(): AST\JoinAssociationPathExpression - { - $identVariable = $this->IdentificationVariable(); - - if (! isset($this->queryComponents[$identVariable])) { - $this->semanticalError( - 'Identification Variable ' . $identVariable . ' used in join path expression but was not defined before.', - ); - } - - $this->match(TokenType::T_DOT); - $this->match(TokenType::T_IDENTIFIER); - - assert($this->lexer->token !== null); - $field = $this->lexer->token->value; - - // Validate association field - $class = $this->getMetadataForDqlAlias($identVariable); - - if (! $class->hasAssociation($field)) { - $this->semanticalError('Class ' . $class->name . ' has no association named ' . $field); - } - - return new AST\JoinAssociationPathExpression($identVariable, $field); - } - - /** - * Parses an arbitrary path expression and defers semantical validation - * based on expected types. - * - * PathExpression ::= IdentificationVariable {"." identifier}* - * - * @psalm-param int-mask-of $expectedTypes - */ - public function PathExpression(int $expectedTypes): AST\PathExpression - { - $identVariable = $this->IdentificationVariable(); - $field = null; - - assert($this->lexer->token !== null); - if ($this->lexer->isNextToken(TokenType::T_DOT)) { - $this->match(TokenType::T_DOT); - $this->match(TokenType::T_IDENTIFIER); - - $field = $this->lexer->token->value; - - while ($this->lexer->isNextToken(TokenType::T_DOT)) { - $this->match(TokenType::T_DOT); - $this->match(TokenType::T_IDENTIFIER); - $field .= '.' . $this->lexer->token->value; - } - } - - // Creating AST node - $pathExpr = new AST\PathExpression($expectedTypes, $identVariable, $field); - - // Defer PathExpression validation if requested to be deferred - $this->deferredPathExpressions[] = [ - 'expression' => $pathExpr, - 'nestingLevel' => $this->nestingLevel, - 'token' => $this->lexer->token, - ]; - - return $pathExpr; - } - - /** - * AssociationPathExpression ::= CollectionValuedPathExpression | SingleValuedAssociationPathExpression - */ - public function AssociationPathExpression(): AST\PathExpression - { - return $this->PathExpression( - AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION | - AST\PathExpression::TYPE_COLLECTION_VALUED_ASSOCIATION, - ); - } - - /** - * SingleValuedPathExpression ::= StateFieldPathExpression | SingleValuedAssociationPathExpression - */ - public function SingleValuedPathExpression(): AST\PathExpression - { - return $this->PathExpression( - AST\PathExpression::TYPE_STATE_FIELD | - AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION, - ); - } - - /** - * StateFieldPathExpression ::= IdentificationVariable "." StateField - */ - public function StateFieldPathExpression(): AST\PathExpression - { - return $this->PathExpression(AST\PathExpression::TYPE_STATE_FIELD); - } - - /** - * SingleValuedAssociationPathExpression ::= IdentificationVariable "." SingleValuedAssociationField - */ - public function SingleValuedAssociationPathExpression(): AST\PathExpression - { - return $this->PathExpression(AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION); - } - - /** - * CollectionValuedPathExpression ::= IdentificationVariable "." CollectionValuedAssociationField - */ - public function CollectionValuedPathExpression(): AST\PathExpression - { - return $this->PathExpression(AST\PathExpression::TYPE_COLLECTION_VALUED_ASSOCIATION); - } - - /** - * SelectClause ::= "SELECT" ["DISTINCT"] SelectExpression {"," SelectExpression} - */ - public function SelectClause(): AST\SelectClause - { - $isDistinct = false; - $this->match(TokenType::T_SELECT); - - // Check for DISTINCT - if ($this->lexer->isNextToken(TokenType::T_DISTINCT)) { - $this->match(TokenType::T_DISTINCT); - - $isDistinct = true; - } - - // Process SelectExpressions (1..N) - $selectExpressions = []; - $selectExpressions[] = $this->SelectExpression(); - - while ($this->lexer->isNextToken(TokenType::T_COMMA)) { - $this->match(TokenType::T_COMMA); - - $selectExpressions[] = $this->SelectExpression(); - } - - return new AST\SelectClause($selectExpressions, $isDistinct); - } - - /** - * SimpleSelectClause ::= "SELECT" ["DISTINCT"] SimpleSelectExpression - */ - public function SimpleSelectClause(): AST\SimpleSelectClause - { - $isDistinct = false; - $this->match(TokenType::T_SELECT); - - if ($this->lexer->isNextToken(TokenType::T_DISTINCT)) { - $this->match(TokenType::T_DISTINCT); - - $isDistinct = true; - } - - return new AST\SimpleSelectClause($this->SimpleSelectExpression(), $isDistinct); - } - - /** - * UpdateClause ::= "UPDATE" AbstractSchemaName ["AS"] AliasIdentificationVariable "SET" UpdateItem {"," UpdateItem}* - */ - public function UpdateClause(): AST\UpdateClause - { - $this->match(TokenType::T_UPDATE); - assert($this->lexer->lookahead !== null); - - $token = $this->lexer->lookahead; - $abstractSchemaName = $this->AbstractSchemaName(); - - $this->validateAbstractSchemaName($abstractSchemaName); - - if ($this->lexer->isNextToken(TokenType::T_AS)) { - $this->match(TokenType::T_AS); - } - - $aliasIdentificationVariable = $this->AliasIdentificationVariable(); - - $class = $this->em->getClassMetadata($abstractSchemaName); - - // Building queryComponent - $queryComponent = [ - 'metadata' => $class, - 'parent' => null, - 'relation' => null, - 'map' => null, - 'nestingLevel' => $this->nestingLevel, - 'token' => $token, - ]; - - $this->queryComponents[$aliasIdentificationVariable] = $queryComponent; - - $this->match(TokenType::T_SET); - - $updateItems = []; - $updateItems[] = $this->UpdateItem(); - - while ($this->lexer->isNextToken(TokenType::T_COMMA)) { - $this->match(TokenType::T_COMMA); - - $updateItems[] = $this->UpdateItem(); - } - - $updateClause = new AST\UpdateClause($abstractSchemaName, $updateItems); - $updateClause->aliasIdentificationVariable = $aliasIdentificationVariable; - - return $updateClause; - } - - /** - * DeleteClause ::= "DELETE" ["FROM"] AbstractSchemaName ["AS"] AliasIdentificationVariable - */ - public function DeleteClause(): AST\DeleteClause - { - $this->match(TokenType::T_DELETE); - - if ($this->lexer->isNextToken(TokenType::T_FROM)) { - $this->match(TokenType::T_FROM); - } - - assert($this->lexer->lookahead !== null); - $token = $this->lexer->lookahead; - $abstractSchemaName = $this->AbstractSchemaName(); - - $this->validateAbstractSchemaName($abstractSchemaName); - - $deleteClause = new AST\DeleteClause($abstractSchemaName); - - if ($this->lexer->isNextToken(TokenType::T_AS)) { - $this->match(TokenType::T_AS); - } - - $aliasIdentificationVariable = $this->lexer->isNextToken(TokenType::T_IDENTIFIER) - ? $this->AliasIdentificationVariable() - : 'alias_should_have_been_set'; - - $deleteClause->aliasIdentificationVariable = $aliasIdentificationVariable; - $class = $this->em->getClassMetadata($deleteClause->abstractSchemaName); - - // Building queryComponent - $queryComponent = [ - 'metadata' => $class, - 'parent' => null, - 'relation' => null, - 'map' => null, - 'nestingLevel' => $this->nestingLevel, - 'token' => $token, - ]; - - $this->queryComponents[$aliasIdentificationVariable] = $queryComponent; - - return $deleteClause; - } - - /** - * FromClause ::= "FROM" IdentificationVariableDeclaration {"," IdentificationVariableDeclaration}* - */ - public function FromClause(): AST\FromClause - { - $this->match(TokenType::T_FROM); - - $identificationVariableDeclarations = []; - $identificationVariableDeclarations[] = $this->IdentificationVariableDeclaration(); - - while ($this->lexer->isNextToken(TokenType::T_COMMA)) { - $this->match(TokenType::T_COMMA); - - $identificationVariableDeclarations[] = $this->IdentificationVariableDeclaration(); - } - - return new AST\FromClause($identificationVariableDeclarations); - } - - /** - * SubselectFromClause ::= "FROM" SubselectIdentificationVariableDeclaration {"," SubselectIdentificationVariableDeclaration}* - */ - public function SubselectFromClause(): AST\SubselectFromClause - { - $this->match(TokenType::T_FROM); - - $identificationVariables = []; - $identificationVariables[] = $this->SubselectIdentificationVariableDeclaration(); - - while ($this->lexer->isNextToken(TokenType::T_COMMA)) { - $this->match(TokenType::T_COMMA); - - $identificationVariables[] = $this->SubselectIdentificationVariableDeclaration(); - } - - return new AST\SubselectFromClause($identificationVariables); - } - - /** - * WhereClause ::= "WHERE" ConditionalExpression - */ - public function WhereClause(): AST\WhereClause - { - $this->match(TokenType::T_WHERE); - - return new AST\WhereClause($this->ConditionalExpression()); - } - - /** - * HavingClause ::= "HAVING" ConditionalExpression - */ - public function HavingClause(): AST\HavingClause - { - $this->match(TokenType::T_HAVING); - - return new AST\HavingClause($this->ConditionalExpression()); - } - - /** - * GroupByClause ::= "GROUP" "BY" GroupByItem {"," GroupByItem}* - */ - public function GroupByClause(): AST\GroupByClause - { - $this->match(TokenType::T_GROUP); - $this->match(TokenType::T_BY); - - $groupByItems = [$this->GroupByItem()]; - - while ($this->lexer->isNextToken(TokenType::T_COMMA)) { - $this->match(TokenType::T_COMMA); - - $groupByItems[] = $this->GroupByItem(); - } - - return new AST\GroupByClause($groupByItems); - } - - /** - * OrderByClause ::= "ORDER" "BY" OrderByItem {"," OrderByItem}* - */ - public function OrderByClause(): AST\OrderByClause - { - $this->match(TokenType::T_ORDER); - $this->match(TokenType::T_BY); - - $orderByItems = []; - $orderByItems[] = $this->OrderByItem(); - - while ($this->lexer->isNextToken(TokenType::T_COMMA)) { - $this->match(TokenType::T_COMMA); - - $orderByItems[] = $this->OrderByItem(); - } - - return new AST\OrderByClause($orderByItems); - } - - /** - * Subselect ::= SimpleSelectClause SubselectFromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause] - */ - public function Subselect(): AST\Subselect - { - // Increase query nesting level - $this->nestingLevel++; - - $subselect = new AST\Subselect($this->SimpleSelectClause(), $this->SubselectFromClause()); - - $subselect->whereClause = $this->lexer->isNextToken(TokenType::T_WHERE) ? $this->WhereClause() : null; - $subselect->groupByClause = $this->lexer->isNextToken(TokenType::T_GROUP) ? $this->GroupByClause() : null; - $subselect->havingClause = $this->lexer->isNextToken(TokenType::T_HAVING) ? $this->HavingClause() : null; - $subselect->orderByClause = $this->lexer->isNextToken(TokenType::T_ORDER) ? $this->OrderByClause() : null; - - // Decrease query nesting level - $this->nestingLevel--; - - return $subselect; - } - - /** - * UpdateItem ::= SingleValuedPathExpression "=" NewValue - */ - public function UpdateItem(): AST\UpdateItem - { - $pathExpr = $this->SingleValuedPathExpression(); - - $this->match(TokenType::T_EQUALS); - - return new AST\UpdateItem($pathExpr, $this->NewValue()); - } - - /** - * GroupByItem ::= IdentificationVariable | ResultVariable | SingleValuedPathExpression - */ - public function GroupByItem(): string|AST\PathExpression - { - // We need to check if we are in a IdentificationVariable or SingleValuedPathExpression - $glimpse = $this->lexer->glimpse(); - - if ($glimpse !== null && $glimpse->type === TokenType::T_DOT) { - return $this->SingleValuedPathExpression(); - } - - assert($this->lexer->lookahead !== null); - // Still need to decide between IdentificationVariable or ResultVariable - $lookaheadValue = $this->lexer->lookahead->value; - - if (! isset($this->queryComponents[$lookaheadValue])) { - $this->semanticalError('Cannot group by undefined identification or result variable.'); - } - - return isset($this->queryComponents[$lookaheadValue]['metadata']) - ? $this->IdentificationVariable() - : $this->ResultVariable(); - } - - /** - * OrderByItem ::= ( - * SimpleArithmeticExpression | SingleValuedPathExpression | CaseExpression | - * ScalarExpression | ResultVariable | FunctionDeclaration - * ) ["ASC" | "DESC"] - */ - public function OrderByItem(): AST\OrderByItem - { - $this->lexer->peek(); // lookahead => '.' - $this->lexer->peek(); // lookahead => token after '.' - - $peek = $this->lexer->peek(); // lookahead => token after the token after the '.' - - $this->lexer->resetPeek(); - - $glimpse = $this->lexer->glimpse(); - - assert($this->lexer->lookahead !== null); - $expr = match (true) { - $this->isMathOperator($peek) => $this->SimpleArithmeticExpression(), - $glimpse !== null && $glimpse->type === TokenType::T_DOT => $this->SingleValuedPathExpression(), - $this->lexer->peek() && $this->isMathOperator($this->peekBeyondClosingParenthesis()) => $this->ScalarExpression(), - $this->lexer->lookahead->type === TokenType::T_CASE => $this->CaseExpression(), - $this->isFunction() => $this->FunctionDeclaration(), - default => $this->ResultVariable(), - }; - - $type = 'ASC'; - $item = new AST\OrderByItem($expr); - - switch (true) { - case $this->lexer->isNextToken(TokenType::T_DESC): - $this->match(TokenType::T_DESC); - $type = 'DESC'; - break; - - case $this->lexer->isNextToken(TokenType::T_ASC): - $this->match(TokenType::T_ASC); - break; - - default: - // Do nothing - } - - $item->type = $type; - - return $item; - } - - /** - * NewValue ::= SimpleArithmeticExpression | StringPrimary | DatetimePrimary | BooleanPrimary | - * EnumPrimary | SimpleEntityExpression | "NULL" - * - * NOTE: Since it is not possible to correctly recognize individual types, here is the full - * grammar that needs to be supported: - * - * NewValue ::= SimpleArithmeticExpression | "NULL" - * - * SimpleArithmeticExpression covers all *Primary grammar rules and also SimpleEntityExpression - */ - public function NewValue(): AST\ArithmeticExpression|AST\InputParameter|null - { - if ($this->lexer->isNextToken(TokenType::T_NULL)) { - $this->match(TokenType::T_NULL); - - return null; - } - - if ($this->lexer->isNextToken(TokenType::T_INPUT_PARAMETER)) { - $this->match(TokenType::T_INPUT_PARAMETER); - assert($this->lexer->token !== null); - - return new AST\InputParameter($this->lexer->token->value); - } - - return $this->ArithmeticExpression(); - } - - /** - * IdentificationVariableDeclaration ::= RangeVariableDeclaration [IndexBy] {Join}* - */ - public function IdentificationVariableDeclaration(): AST\IdentificationVariableDeclaration - { - $joins = []; - $rangeVariableDeclaration = $this->RangeVariableDeclaration(); - $indexBy = $this->lexer->isNextToken(TokenType::T_INDEX) - ? $this->IndexBy() - : null; - - $rangeVariableDeclaration->isRoot = true; - - while ( - $this->lexer->isNextToken(TokenType::T_LEFT) || - $this->lexer->isNextToken(TokenType::T_INNER) || - $this->lexer->isNextToken(TokenType::T_JOIN) - ) { - $joins[] = $this->Join(); - } - - return new AST\IdentificationVariableDeclaration( - $rangeVariableDeclaration, - $indexBy, - $joins, - ); - } - - /** - * SubselectIdentificationVariableDeclaration ::= IdentificationVariableDeclaration - * - * {Internal note: WARNING: Solution is harder than a bare implementation. - * Desired EBNF support: - * - * SubselectIdentificationVariableDeclaration ::= IdentificationVariableDeclaration | (AssociationPathExpression ["AS"] AliasIdentificationVariable) - * - * It demands that entire SQL generation to become programmatical. This is - * needed because association based subselect requires "WHERE" conditional - * expressions to be injected, but there is no scope to do that. Only scope - * accessible is "FROM", prohibiting an easy implementation without larger - * changes.} - */ - public function SubselectIdentificationVariableDeclaration(): AST\IdentificationVariableDeclaration - { - /* - NOT YET IMPLEMENTED! - - $glimpse = $this->lexer->glimpse(); - - if ($glimpse->type == TokenType::T_DOT) { - $associationPathExpression = $this->AssociationPathExpression(); - - if ($this->lexer->isNextToken(TokenType::T_AS)) { - $this->match(TokenType::T_AS); - } - - $aliasIdentificationVariable = $this->AliasIdentificationVariable(); - $identificationVariable = $associationPathExpression->identificationVariable; - $field = $associationPathExpression->associationField; - - $class = $this->queryComponents[$identificationVariable]['metadata']; - $targetClass = $this->em->getClassMetadata($class->associationMappings[$field]['targetEntity']); - - // Building queryComponent - $joinQueryComponent = array( - 'metadata' => $targetClass, - 'parent' => $identificationVariable, - 'relation' => $class->getAssociationMapping($field), - 'map' => null, - 'nestingLevel' => $this->nestingLevel, - 'token' => $this->lexer->lookahead - ); - - $this->queryComponents[$aliasIdentificationVariable] = $joinQueryComponent; - - return new AST\SubselectIdentificationVariableDeclaration( - $associationPathExpression, $aliasIdentificationVariable - ); - } - */ - - return $this->IdentificationVariableDeclaration(); - } - - /** - * Join ::= ["LEFT" ["OUTER"] | "INNER"] "JOIN" - * (JoinAssociationDeclaration | RangeVariableDeclaration) - * ["WITH" ConditionalExpression] - */ - public function Join(): AST\Join - { - // Check Join type - $joinType = AST\Join::JOIN_TYPE_INNER; - - switch (true) { - case $this->lexer->isNextToken(TokenType::T_LEFT): - $this->match(TokenType::T_LEFT); - - $joinType = AST\Join::JOIN_TYPE_LEFT; - - // Possible LEFT OUTER join - if ($this->lexer->isNextToken(TokenType::T_OUTER)) { - $this->match(TokenType::T_OUTER); - - $joinType = AST\Join::JOIN_TYPE_LEFTOUTER; - } - - break; - - case $this->lexer->isNextToken(TokenType::T_INNER): - $this->match(TokenType::T_INNER); - break; - - default: - // Do nothing - } - - $this->match(TokenType::T_JOIN); - - $next = $this->lexer->glimpse(); - assert($next !== null); - $joinDeclaration = $next->type === TokenType::T_DOT ? $this->JoinAssociationDeclaration() : $this->RangeVariableDeclaration(); - $adhocConditions = $this->lexer->isNextToken(TokenType::T_WITH); - $join = new AST\Join($joinType, $joinDeclaration); - - // Describe non-root join declaration - if ($joinDeclaration instanceof AST\RangeVariableDeclaration) { - $joinDeclaration->isRoot = false; - } - - // Check for ad-hoc Join conditions - if ($adhocConditions) { - $this->match(TokenType::T_WITH); - - $join->conditionalExpression = $this->ConditionalExpression(); - } - - return $join; - } - - /** - * RangeVariableDeclaration ::= AbstractSchemaName ["AS"] AliasIdentificationVariable - * - * @throws QueryException - */ - public function RangeVariableDeclaration(): AST\RangeVariableDeclaration - { - if ($this->lexer->isNextToken(TokenType::T_OPEN_PARENTHESIS) && $this->lexer->glimpse()->type === TokenType::T_SELECT) { - $this->semanticalError('Subquery is not supported here', $this->lexer->token); - } - - $abstractSchemaName = $this->AbstractSchemaName(); - - $this->validateAbstractSchemaName($abstractSchemaName); - - if ($this->lexer->isNextToken(TokenType::T_AS)) { - $this->match(TokenType::T_AS); - } - - assert($this->lexer->lookahead !== null); - $token = $this->lexer->lookahead; - $aliasIdentificationVariable = $this->AliasIdentificationVariable(); - $classMetadata = $this->em->getClassMetadata($abstractSchemaName); - - // Building queryComponent - $queryComponent = [ - 'metadata' => $classMetadata, - 'parent' => null, - 'relation' => null, - 'map' => null, - 'nestingLevel' => $this->nestingLevel, - 'token' => $token, - ]; - - $this->queryComponents[$aliasIdentificationVariable] = $queryComponent; - - return new AST\RangeVariableDeclaration($abstractSchemaName, $aliasIdentificationVariable); - } - - /** - * JoinAssociationDeclaration ::= JoinAssociationPathExpression ["AS"] AliasIdentificationVariable [IndexBy] - */ - public function JoinAssociationDeclaration(): AST\JoinAssociationDeclaration - { - $joinAssociationPathExpression = $this->JoinAssociationPathExpression(); - - if ($this->lexer->isNextToken(TokenType::T_AS)) { - $this->match(TokenType::T_AS); - } - - assert($this->lexer->lookahead !== null); - - $aliasIdentificationVariable = $this->AliasIdentificationVariable(); - $indexBy = $this->lexer->isNextToken(TokenType::T_INDEX) ? $this->IndexBy() : null; - - $identificationVariable = $joinAssociationPathExpression->identificationVariable; - $field = $joinAssociationPathExpression->associationField; - - $class = $this->getMetadataForDqlAlias($identificationVariable); - $targetClass = $this->em->getClassMetadata($class->associationMappings[$field]->targetEntity); - - // Building queryComponent - $joinQueryComponent = [ - 'metadata' => $targetClass, - 'parent' => $joinAssociationPathExpression->identificationVariable, - 'relation' => $class->getAssociationMapping($field), - 'map' => null, - 'nestingLevel' => $this->nestingLevel, - 'token' => $this->lexer->lookahead, - ]; - - $this->queryComponents[$aliasIdentificationVariable] = $joinQueryComponent; - - return new AST\JoinAssociationDeclaration($joinAssociationPathExpression, $aliasIdentificationVariable, $indexBy); - } - - /** - * NewObjectExpression ::= "NEW" AbstractSchemaName "(" NewObjectArg {"," NewObjectArg}* ")" - */ - public function NewObjectExpression(): AST\NewObjectExpression - { - $args = []; - $this->match(TokenType::T_NEW); - - $className = $this->AbstractSchemaName(); // note that this is not yet validated - $token = $this->lexer->token; - - $this->match(TokenType::T_OPEN_PARENTHESIS); - - $args[] = $this->NewObjectArg(); - - while ($this->lexer->isNextToken(TokenType::T_COMMA)) { - $this->match(TokenType::T_COMMA); - - $args[] = $this->NewObjectArg(); - } - - $this->match(TokenType::T_CLOSE_PARENTHESIS); - - $expression = new AST\NewObjectExpression($className, $args); - - // Defer NewObjectExpression validation - $this->deferredNewObjectExpressions[] = [ - 'token' => $token, - 'expression' => $expression, - 'nestingLevel' => $this->nestingLevel, - ]; - - return $expression; - } - - /** - * NewObjectArg ::= ScalarExpression | "(" Subselect ")" - */ - public function NewObjectArg(): mixed - { - assert($this->lexer->lookahead !== null); - $token = $this->lexer->lookahead; - $peek = $this->lexer->glimpse(); - - assert($peek !== null); - if ($token->type === TokenType::T_OPEN_PARENTHESIS && $peek->type === TokenType::T_SELECT) { - $this->match(TokenType::T_OPEN_PARENTHESIS); - $expression = $this->Subselect(); - $this->match(TokenType::T_CLOSE_PARENTHESIS); - - return $expression; - } - - return $this->ScalarExpression(); - } - - /** - * IndexBy ::= "INDEX" "BY" SingleValuedPathExpression - */ - public function IndexBy(): AST\IndexBy - { - $this->match(TokenType::T_INDEX); - $this->match(TokenType::T_BY); - $pathExpr = $this->SingleValuedPathExpression(); - - // Add the INDEX BY info to the query component - $this->queryComponents[$pathExpr->identificationVariable]['map'] = $pathExpr->field; - - return new AST\IndexBy($pathExpr); - } - - /** - * ScalarExpression ::= SimpleArithmeticExpression | StringPrimary | DateTimePrimary | - * StateFieldPathExpression | BooleanPrimary | CaseExpression | - * InstanceOfExpression - * - * @return mixed One of the possible expressions or subexpressions. - */ - public function ScalarExpression(): mixed - { - assert($this->lexer->token !== null); - assert($this->lexer->lookahead !== null); - $lookahead = $this->lexer->lookahead->type; - $peek = $this->lexer->glimpse(); - - switch (true) { - case $lookahead === TokenType::T_INTEGER: - case $lookahead === TokenType::T_FLOAT: - // SimpleArithmeticExpression : (- u.value ) or ( + u.value ) or ( - 1 ) or ( + 1 ) - case $lookahead === TokenType::T_MINUS: - case $lookahead === TokenType::T_PLUS: - return $this->SimpleArithmeticExpression(); - - case $lookahead === TokenType::T_STRING: - return $this->StringPrimary(); - - case $lookahead === TokenType::T_TRUE: - case $lookahead === TokenType::T_FALSE: - $this->match($lookahead); - - return new AST\Literal(AST\Literal::BOOLEAN, $this->lexer->token->value); - - case $lookahead === TokenType::T_INPUT_PARAMETER: - return match (true) { - $this->isMathOperator($peek) => $this->SimpleArithmeticExpression(), - default => $this->InputParameter(), - }; - - case $lookahead === TokenType::T_CASE: - case $lookahead === TokenType::T_COALESCE: - case $lookahead === TokenType::T_NULLIF: - // Since NULLIF and COALESCE can be identified as a function, - // we need to check these before checking for FunctionDeclaration - return $this->CaseExpression(); - - case $lookahead === TokenType::T_OPEN_PARENTHESIS: - return $this->SimpleArithmeticExpression(); - - // this check must be done before checking for a filed path expression - case $this->isFunction(): - $this->lexer->peek(); - - return match (true) { - $this->isMathOperator($this->peekBeyondClosingParenthesis()) => $this->SimpleArithmeticExpression(), - default => $this->FunctionDeclaration(), - }; - - // it is no function, so it must be a field path - case $lookahead === TokenType::T_IDENTIFIER: - $this->lexer->peek(); // lookahead => '.' - $this->lexer->peek(); // lookahead => token after '.' - $peek = $this->lexer->peek(); // lookahead => token after the token after the '.' - $this->lexer->resetPeek(); - - if ($this->isMathOperator($peek)) { - return $this->SimpleArithmeticExpression(); - } - - return $this->StateFieldPathExpression(); - - default: - $this->syntaxError(); - } - } - - /** - * CaseExpression ::= GeneralCaseExpression | SimpleCaseExpression | CoalesceExpression | NullifExpression - * GeneralCaseExpression ::= "CASE" WhenClause {WhenClause}* "ELSE" ScalarExpression "END" - * WhenClause ::= "WHEN" ConditionalExpression "THEN" ScalarExpression - * SimpleCaseExpression ::= "CASE" CaseOperand SimpleWhenClause {SimpleWhenClause}* "ELSE" ScalarExpression "END" - * CaseOperand ::= StateFieldPathExpression | TypeDiscriminator - * SimpleWhenClause ::= "WHEN" ScalarExpression "THEN" ScalarExpression - * CoalesceExpression ::= "COALESCE" "(" ScalarExpression {"," ScalarExpression}* ")" - * NullifExpression ::= "NULLIF" "(" ScalarExpression "," ScalarExpression ")" - * - * @return mixed One of the possible expressions or subexpressions. - */ - public function CaseExpression(): mixed - { - assert($this->lexer->lookahead !== null); - $lookahead = $this->lexer->lookahead->type; - - switch ($lookahead) { - case TokenType::T_NULLIF: - return $this->NullIfExpression(); - - case TokenType::T_COALESCE: - return $this->CoalesceExpression(); - - case TokenType::T_CASE: - $this->lexer->resetPeek(); - $peek = $this->lexer->peek(); - - assert($peek !== null); - if ($peek->type === TokenType::T_WHEN) { - return $this->GeneralCaseExpression(); - } - - return $this->SimpleCaseExpression(); - - default: - // Do nothing - break; - } - - $this->syntaxError(); - } - - /** - * CoalesceExpression ::= "COALESCE" "(" ScalarExpression {"," ScalarExpression}* ")" - */ - public function CoalesceExpression(): AST\CoalesceExpression - { - $this->match(TokenType::T_COALESCE); - $this->match(TokenType::T_OPEN_PARENTHESIS); - - // Process ScalarExpressions (1..N) - $scalarExpressions = []; - $scalarExpressions[] = $this->ScalarExpression(); - - while ($this->lexer->isNextToken(TokenType::T_COMMA)) { - $this->match(TokenType::T_COMMA); - - $scalarExpressions[] = $this->ScalarExpression(); - } - - $this->match(TokenType::T_CLOSE_PARENTHESIS); - - return new AST\CoalesceExpression($scalarExpressions); - } - - /** - * NullIfExpression ::= "NULLIF" "(" ScalarExpression "," ScalarExpression ")" - */ - public function NullIfExpression(): AST\NullIfExpression - { - $this->match(TokenType::T_NULLIF); - $this->match(TokenType::T_OPEN_PARENTHESIS); - - $firstExpression = $this->ScalarExpression(); - $this->match(TokenType::T_COMMA); - $secondExpression = $this->ScalarExpression(); - - $this->match(TokenType::T_CLOSE_PARENTHESIS); - - return new AST\NullIfExpression($firstExpression, $secondExpression); - } - - /** - * GeneralCaseExpression ::= "CASE" WhenClause {WhenClause}* "ELSE" ScalarExpression "END" - */ - public function GeneralCaseExpression(): AST\GeneralCaseExpression - { - $this->match(TokenType::T_CASE); - - // Process WhenClause (1..N) - $whenClauses = []; - - do { - $whenClauses[] = $this->WhenClause(); - } while ($this->lexer->isNextToken(TokenType::T_WHEN)); - - $this->match(TokenType::T_ELSE); - $scalarExpression = $this->ScalarExpression(); - $this->match(TokenType::T_END); - - return new AST\GeneralCaseExpression($whenClauses, $scalarExpression); - } - - /** - * SimpleCaseExpression ::= "CASE" CaseOperand SimpleWhenClause {SimpleWhenClause}* "ELSE" ScalarExpression "END" - * CaseOperand ::= StateFieldPathExpression | TypeDiscriminator - */ - public function SimpleCaseExpression(): AST\SimpleCaseExpression - { - $this->match(TokenType::T_CASE); - $caseOperand = $this->StateFieldPathExpression(); - - // Process SimpleWhenClause (1..N) - $simpleWhenClauses = []; - - do { - $simpleWhenClauses[] = $this->SimpleWhenClause(); - } while ($this->lexer->isNextToken(TokenType::T_WHEN)); - - $this->match(TokenType::T_ELSE); - $scalarExpression = $this->ScalarExpression(); - $this->match(TokenType::T_END); - - return new AST\SimpleCaseExpression($caseOperand, $simpleWhenClauses, $scalarExpression); - } - - /** - * WhenClause ::= "WHEN" ConditionalExpression "THEN" ScalarExpression - */ - public function WhenClause(): AST\WhenClause - { - $this->match(TokenType::T_WHEN); - $conditionalExpression = $this->ConditionalExpression(); - $this->match(TokenType::T_THEN); - - return new AST\WhenClause($conditionalExpression, $this->ScalarExpression()); - } - - /** - * SimpleWhenClause ::= "WHEN" ScalarExpression "THEN" ScalarExpression - */ - public function SimpleWhenClause(): AST\SimpleWhenClause - { - $this->match(TokenType::T_WHEN); - $conditionalExpression = $this->ScalarExpression(); - $this->match(TokenType::T_THEN); - - return new AST\SimpleWhenClause($conditionalExpression, $this->ScalarExpression()); - } - - /** - * SelectExpression ::= ( - * IdentificationVariable | ScalarExpression | AggregateExpression | FunctionDeclaration | - * "(" Subselect ")" | CaseExpression | NewObjectExpression - * ) [["AS"] ["HIDDEN"] AliasResultVariable] - */ - public function SelectExpression(): AST\SelectExpression - { - assert($this->lexer->lookahead !== null); - $expression = null; - $identVariable = null; - $peek = $this->lexer->glimpse(); - $lookaheadType = $this->lexer->lookahead->type; - assert($peek !== null); - - switch (true) { - // ScalarExpression (u.name) - case $lookaheadType === TokenType::T_IDENTIFIER && $peek->type === TokenType::T_DOT: - $expression = $this->ScalarExpression(); - break; - - // IdentificationVariable (u) - case $lookaheadType === TokenType::T_IDENTIFIER && $peek->type !== TokenType::T_OPEN_PARENTHESIS: - $expression = $identVariable = $this->IdentificationVariable(); - break; - - // CaseExpression (CASE ... or NULLIF(...) or COALESCE(...)) - case $lookaheadType === TokenType::T_CASE: - case $lookaheadType === TokenType::T_COALESCE: - case $lookaheadType === TokenType::T_NULLIF: - $expression = $this->CaseExpression(); - break; - - // DQL Function (SUM(u.value) or SUM(u.value) + 1) - case $this->isFunction(): - $this->lexer->peek(); // "(" - - $expression = match (true) { - $this->isMathOperator($this->peekBeyondClosingParenthesis()) => $this->ScalarExpression(), - default => $this->FunctionDeclaration(), - }; - - break; - - // Subselect - case $lookaheadType === TokenType::T_OPEN_PARENTHESIS && $peek->type === TokenType::T_SELECT: - $this->match(TokenType::T_OPEN_PARENTHESIS); - $expression = $this->Subselect(); - $this->match(TokenType::T_CLOSE_PARENTHESIS); - break; - - // Shortcut: ScalarExpression => SimpleArithmeticExpression - case $lookaheadType === TokenType::T_OPEN_PARENTHESIS: - case $lookaheadType === TokenType::T_INTEGER: - case $lookaheadType === TokenType::T_STRING: - case $lookaheadType === TokenType::T_FLOAT: - // SimpleArithmeticExpression : (- u.value ) or ( + u.value ) - case $lookaheadType === TokenType::T_MINUS: - case $lookaheadType === TokenType::T_PLUS: - $expression = $this->SimpleArithmeticExpression(); - break; - - // NewObjectExpression (New ClassName(id, name)) - case $lookaheadType === TokenType::T_NEW: - $expression = $this->NewObjectExpression(); - break; - - default: - $this->syntaxError( - 'IdentificationVariable | ScalarExpression | AggregateExpression | FunctionDeclaration | "(" Subselect ")" | CaseExpression', - $this->lexer->lookahead, - ); - } - - // [["AS"] ["HIDDEN"] AliasResultVariable] - $mustHaveAliasResultVariable = false; - - if ($this->lexer->isNextToken(TokenType::T_AS)) { - $this->match(TokenType::T_AS); - - $mustHaveAliasResultVariable = true; - } - - $hiddenAliasResultVariable = false; - - if ($this->lexer->isNextToken(TokenType::T_HIDDEN)) { - $this->match(TokenType::T_HIDDEN); - - $hiddenAliasResultVariable = true; - } - - $aliasResultVariable = null; - - if ($mustHaveAliasResultVariable || $this->lexer->isNextToken(TokenType::T_IDENTIFIER)) { - assert($expression instanceof AST\Node || is_string($expression)); - $token = $this->lexer->lookahead; - $aliasResultVariable = $this->AliasResultVariable(); - - // Include AliasResultVariable in query components. - $this->queryComponents[$aliasResultVariable] = [ - 'resultVariable' => $expression, - 'nestingLevel' => $this->nestingLevel, - 'token' => $token, - ]; - } - - // AST - - $expr = new AST\SelectExpression($expression, $aliasResultVariable, $hiddenAliasResultVariable); - - if ($identVariable) { - $this->identVariableExpressions[$identVariable] = $expr; - } - - return $expr; - } - - /** - * SimpleSelectExpression ::= ( - * StateFieldPathExpression | IdentificationVariable | FunctionDeclaration | - * AggregateExpression | "(" Subselect ")" | ScalarExpression - * ) [["AS"] AliasResultVariable] - */ - public function SimpleSelectExpression(): AST\SimpleSelectExpression - { - assert($this->lexer->lookahead !== null); - $peek = $this->lexer->glimpse(); - assert($peek !== null); - - switch ($this->lexer->lookahead->type) { - case TokenType::T_IDENTIFIER: - switch (true) { - case $peek->type === TokenType::T_DOT: - $expression = $this->StateFieldPathExpression(); - - return new AST\SimpleSelectExpression($expression); - - case $peek->type !== TokenType::T_OPEN_PARENTHESIS: - $expression = $this->IdentificationVariable(); - - return new AST\SimpleSelectExpression($expression); - - case $this->isFunction(): - // SUM(u.id) + COUNT(u.id) - if ($this->isMathOperator($this->peekBeyondClosingParenthesis())) { - return new AST\SimpleSelectExpression($this->ScalarExpression()); - } - - // COUNT(u.id) - if ($this->isAggregateFunction($this->lexer->lookahead->type)) { - return new AST\SimpleSelectExpression($this->AggregateExpression()); - } - - // IDENTITY(u) - return new AST\SimpleSelectExpression($this->FunctionDeclaration()); - - default: - // Do nothing - } - - break; - - case TokenType::T_OPEN_PARENTHESIS: - if ($peek->type !== TokenType::T_SELECT) { - // Shortcut: ScalarExpression => SimpleArithmeticExpression - $expression = $this->SimpleArithmeticExpression(); - - return new AST\SimpleSelectExpression($expression); - } - - // Subselect - $this->match(TokenType::T_OPEN_PARENTHESIS); - $expression = $this->Subselect(); - $this->match(TokenType::T_CLOSE_PARENTHESIS); - - return new AST\SimpleSelectExpression($expression); - - default: - // Do nothing - } - - $this->lexer->peek(); - - $expression = $this->ScalarExpression(); - $expr = new AST\SimpleSelectExpression($expression); - - if ($this->lexer->isNextToken(TokenType::T_AS)) { - $this->match(TokenType::T_AS); - } - - if ($this->lexer->isNextToken(TokenType::T_IDENTIFIER)) { - $token = $this->lexer->lookahead; - $resultVariable = $this->AliasResultVariable(); - $expr->fieldIdentificationVariable = $resultVariable; - - // Include AliasResultVariable in query components. - $this->queryComponents[$resultVariable] = [ - 'resultvariable' => $expr, - 'nestingLevel' => $this->nestingLevel, - 'token' => $token, - ]; - } - - return $expr; - } - - /** - * ConditionalExpression ::= ConditionalTerm {"OR" ConditionalTerm}* - */ - public function ConditionalExpression(): AST\ConditionalExpression|AST\ConditionalFactor|AST\ConditionalPrimary|AST\ConditionalTerm - { - $conditionalTerms = []; - $conditionalTerms[] = $this->ConditionalTerm(); - - while ($this->lexer->isNextToken(TokenType::T_OR)) { - $this->match(TokenType::T_OR); - - $conditionalTerms[] = $this->ConditionalTerm(); - } - - // Phase 1 AST optimization: Prevent AST\ConditionalExpression - // if only one AST\ConditionalTerm is defined - if (count($conditionalTerms) === 1) { - return $conditionalTerms[0]; - } - - return new AST\ConditionalExpression($conditionalTerms); - } - - /** - * ConditionalTerm ::= ConditionalFactor {"AND" ConditionalFactor}* - */ - public function ConditionalTerm(): AST\ConditionalFactor|AST\ConditionalPrimary|AST\ConditionalTerm - { - $conditionalFactors = []; - $conditionalFactors[] = $this->ConditionalFactor(); - - while ($this->lexer->isNextToken(TokenType::T_AND)) { - $this->match(TokenType::T_AND); - - $conditionalFactors[] = $this->ConditionalFactor(); - } - - // Phase 1 AST optimization: Prevent AST\ConditionalTerm - // if only one AST\ConditionalFactor is defined - if (count($conditionalFactors) === 1) { - return $conditionalFactors[0]; - } - - return new AST\ConditionalTerm($conditionalFactors); - } - - /** - * ConditionalFactor ::= ["NOT"] ConditionalPrimary - */ - public function ConditionalFactor(): AST\ConditionalFactor|AST\ConditionalPrimary - { - $not = false; - - if ($this->lexer->isNextToken(TokenType::T_NOT)) { - $this->match(TokenType::T_NOT); - - $not = true; - } - - $conditionalPrimary = $this->ConditionalPrimary(); - - // Phase 1 AST optimization: Prevent AST\ConditionalFactor - // if only one AST\ConditionalPrimary is defined - if (! $not) { - return $conditionalPrimary; - } - - return new AST\ConditionalFactor($conditionalPrimary, $not); - } - - /** - * ConditionalPrimary ::= SimpleConditionalExpression | "(" ConditionalExpression ")" - */ - public function ConditionalPrimary(): AST\ConditionalPrimary - { - $condPrimary = new AST\ConditionalPrimary(); - - if (! $this->lexer->isNextToken(TokenType::T_OPEN_PARENTHESIS)) { - $condPrimary->simpleConditionalExpression = $this->SimpleConditionalExpression(); - - return $condPrimary; - } - - // Peek beyond the matching closing parenthesis ')' - $peek = $this->peekBeyondClosingParenthesis(); - - if ( - $peek !== null && ( - in_array($peek->value, ['=', '<', '<=', '<>', '>', '>=', '!='], true) || - in_array($peek->type, [TokenType::T_NOT, TokenType::T_BETWEEN, TokenType::T_LIKE, TokenType::T_IN, TokenType::T_IS, TokenType::T_EXISTS], true) || - $this->isMathOperator($peek) - ) - ) { - $condPrimary->simpleConditionalExpression = $this->SimpleConditionalExpression(); - - return $condPrimary; - } - - $this->match(TokenType::T_OPEN_PARENTHESIS); - $condPrimary->conditionalExpression = $this->ConditionalExpression(); - $this->match(TokenType::T_CLOSE_PARENTHESIS); - - return $condPrimary; - } - - /** - * SimpleConditionalExpression ::= - * ComparisonExpression | BetweenExpression | LikeExpression | - * InExpression | NullComparisonExpression | ExistsExpression | - * EmptyCollectionComparisonExpression | CollectionMemberExpression | - * InstanceOfExpression - */ - public function SimpleConditionalExpression(): AST\ExistsExpression|AST\BetweenExpression|AST\LikeExpression|AST\InListExpression|AST\InSubselectExpression|AST\InstanceOfExpression|AST\CollectionMemberExpression|AST\NullComparisonExpression|AST\EmptyCollectionComparisonExpression|AST\ComparisonExpression - { - assert($this->lexer->lookahead !== null); - if ($this->lexer->isNextToken(TokenType::T_EXISTS)) { - return $this->ExistsExpression(); - } - - $token = $this->lexer->lookahead; - $peek = $this->lexer->glimpse(); - $lookahead = $token; - - if ($this->lexer->isNextToken(TokenType::T_NOT)) { - $token = $this->lexer->glimpse(); - } - - assert($token !== null); - assert($peek !== null); - if ($token->type === TokenType::T_IDENTIFIER || $token->type === TokenType::T_INPUT_PARAMETER || $this->isFunction()) { - // Peek beyond the matching closing parenthesis. - $beyond = $this->lexer->peek(); - - switch ($peek->value) { - case '(': - // Peeks beyond the matched closing parenthesis. - $token = $this->peekBeyondClosingParenthesis(false); - assert($token !== null); - - if ($token->type === TokenType::T_NOT) { - $token = $this->lexer->peek(); - assert($token !== null); - } - - if ($token->type === TokenType::T_IS) { - $lookahead = $this->lexer->peek(); - } - - break; - - default: - // Peek beyond the PathExpression or InputParameter. - $token = $beyond; - - while ($token->value === '.') { - $this->lexer->peek(); - - $token = $this->lexer->peek(); - assert($token !== null); - } - - // Also peek beyond a NOT if there is one. - assert($token !== null); - if ($token->type === TokenType::T_NOT) { - $token = $this->lexer->peek(); - assert($token !== null); - } - - // We need to go even further in case of IS (differentiate between NULL and EMPTY) - $lookahead = $this->lexer->peek(); - } - - assert($lookahead !== null); - // Also peek beyond a NOT if there is one. - if ($lookahead->type === TokenType::T_NOT) { - $lookahead = $this->lexer->peek(); - } - - $this->lexer->resetPeek(); - } - - if ($token->type === TokenType::T_BETWEEN) { - return $this->BetweenExpression(); - } - - if ($token->type === TokenType::T_LIKE) { - return $this->LikeExpression(); - } - - if ($token->type === TokenType::T_IN) { - return $this->InExpression(); - } - - if ($token->type === TokenType::T_INSTANCE) { - return $this->InstanceOfExpression(); - } - - if ($token->type === TokenType::T_MEMBER) { - return $this->CollectionMemberExpression(); - } - - assert($lookahead !== null); - if ($token->type === TokenType::T_IS && $lookahead->type === TokenType::T_NULL) { - return $this->NullComparisonExpression(); - } - - if ($token->type === TokenType::T_IS && $lookahead->type === TokenType::T_EMPTY) { - return $this->EmptyCollectionComparisonExpression(); - } - - return $this->ComparisonExpression(); - } - - /** - * EmptyCollectionComparisonExpression ::= CollectionValuedPathExpression "IS" ["NOT"] "EMPTY" - */ - public function EmptyCollectionComparisonExpression(): AST\EmptyCollectionComparisonExpression - { - $pathExpression = $this->CollectionValuedPathExpression(); - $this->match(TokenType::T_IS); - - $not = false; - if ($this->lexer->isNextToken(TokenType::T_NOT)) { - $this->match(TokenType::T_NOT); - $not = true; - } - - $this->match(TokenType::T_EMPTY); - - return new AST\EmptyCollectionComparisonExpression( - $pathExpression, - $not, - ); - } - - /** - * CollectionMemberExpression ::= EntityExpression ["NOT"] "MEMBER" ["OF"] CollectionValuedPathExpression - * - * EntityExpression ::= SingleValuedAssociationPathExpression | SimpleEntityExpression - * SimpleEntityExpression ::= IdentificationVariable | InputParameter - */ - public function CollectionMemberExpression(): AST\CollectionMemberExpression - { - $not = false; - $entityExpr = $this->EntityExpression(); - - if ($this->lexer->isNextToken(TokenType::T_NOT)) { - $this->match(TokenType::T_NOT); - - $not = true; - } - - $this->match(TokenType::T_MEMBER); - - if ($this->lexer->isNextToken(TokenType::T_OF)) { - $this->match(TokenType::T_OF); - } - - return new AST\CollectionMemberExpression( - $entityExpr, - $this->CollectionValuedPathExpression(), - $not, - ); - } - - /** - * Literal ::= string | char | integer | float | boolean - */ - public function Literal(): AST\Literal - { - assert($this->lexer->lookahead !== null); - assert($this->lexer->token !== null); - switch ($this->lexer->lookahead->type) { - case TokenType::T_STRING: - $this->match(TokenType::T_STRING); - - return new AST\Literal(AST\Literal::STRING, $this->lexer->token->value); - - case TokenType::T_INTEGER: - case TokenType::T_FLOAT: - $this->match( - $this->lexer->isNextToken(TokenType::T_INTEGER) ? TokenType::T_INTEGER : TokenType::T_FLOAT, - ); - - return new AST\Literal(AST\Literal::NUMERIC, $this->lexer->token->value); - - case TokenType::T_TRUE: - case TokenType::T_FALSE: - $this->match( - $this->lexer->isNextToken(TokenType::T_TRUE) ? TokenType::T_TRUE : TokenType::T_FALSE, - ); - - return new AST\Literal(AST\Literal::BOOLEAN, $this->lexer->token->value); - - default: - $this->syntaxError('Literal'); - } - } - - /** - * InParameter ::= ArithmeticExpression | InputParameter - */ - public function InParameter(): AST\InputParameter|AST\ArithmeticExpression - { - assert($this->lexer->lookahead !== null); - if ($this->lexer->lookahead->type === TokenType::T_INPUT_PARAMETER) { - return $this->InputParameter(); - } - - return $this->ArithmeticExpression(); - } - - /** - * InputParameter ::= PositionalParameter | NamedParameter - */ - public function InputParameter(): AST\InputParameter - { - $this->match(TokenType::T_INPUT_PARAMETER); - assert($this->lexer->token !== null); - - return new AST\InputParameter($this->lexer->token->value); - } - - /** - * ArithmeticExpression ::= SimpleArithmeticExpression | "(" Subselect ")" - */ - public function ArithmeticExpression(): AST\ArithmeticExpression - { - $expr = new AST\ArithmeticExpression(); - - if ($this->lexer->isNextToken(TokenType::T_OPEN_PARENTHESIS)) { - $peek = $this->lexer->glimpse(); - assert($peek !== null); - - if ($peek->type === TokenType::T_SELECT) { - $this->match(TokenType::T_OPEN_PARENTHESIS); - $expr->subselect = $this->Subselect(); - $this->match(TokenType::T_CLOSE_PARENTHESIS); - - return $expr; - } - } - - $expr->simpleArithmeticExpression = $this->SimpleArithmeticExpression(); - - return $expr; - } - - /** - * SimpleArithmeticExpression ::= ArithmeticTerm {("+" | "-") ArithmeticTerm}* - */ - public function SimpleArithmeticExpression(): AST\Node|string - { - $terms = []; - $terms[] = $this->ArithmeticTerm(); - - while (($isPlus = $this->lexer->isNextToken(TokenType::T_PLUS)) || $this->lexer->isNextToken(TokenType::T_MINUS)) { - $this->match($isPlus ? TokenType::T_PLUS : TokenType::T_MINUS); - - assert($this->lexer->token !== null); - $terms[] = $this->lexer->token->value; - $terms[] = $this->ArithmeticTerm(); - } - - // Phase 1 AST optimization: Prevent AST\SimpleArithmeticExpression - // if only one AST\ArithmeticTerm is defined - if (count($terms) === 1) { - return $terms[0]; - } - - return new AST\SimpleArithmeticExpression($terms); - } - - /** - * ArithmeticTerm ::= ArithmeticFactor {("*" | "/") ArithmeticFactor}* - */ - public function ArithmeticTerm(): AST\Node|string - { - $factors = []; - $factors[] = $this->ArithmeticFactor(); - - while (($isMult = $this->lexer->isNextToken(TokenType::T_MULTIPLY)) || $this->lexer->isNextToken(TokenType::T_DIVIDE)) { - $this->match($isMult ? TokenType::T_MULTIPLY : TokenType::T_DIVIDE); - - assert($this->lexer->token !== null); - $factors[] = $this->lexer->token->value; - $factors[] = $this->ArithmeticFactor(); - } - - // Phase 1 AST optimization: Prevent AST\ArithmeticTerm - // if only one AST\ArithmeticFactor is defined - if (count($factors) === 1) { - return $factors[0]; - } - - return new AST\ArithmeticTerm($factors); - } - - /** - * ArithmeticFactor ::= [("+" | "-")] ArithmeticPrimary - */ - public function ArithmeticFactor(): AST\Node|string|AST\ArithmeticFactor - { - $sign = null; - - $isPlus = $this->lexer->isNextToken(TokenType::T_PLUS); - if ($isPlus || $this->lexer->isNextToken(TokenType::T_MINUS)) { - $this->match($isPlus ? TokenType::T_PLUS : TokenType::T_MINUS); - $sign = $isPlus; - } - - $primary = $this->ArithmeticPrimary(); - - // Phase 1 AST optimization: Prevent AST\ArithmeticFactor - // if only one AST\ArithmeticPrimary is defined - if ($sign === null) { - return $primary; - } - - return new AST\ArithmeticFactor($primary, $sign); - } - - /** - * ArithmeticPrimary ::= SingleValuedPathExpression | Literal | ParenthesisExpression - * | FunctionsReturningNumerics | AggregateExpression | FunctionsReturningStrings - * | FunctionsReturningDatetime | IdentificationVariable | ResultVariable - * | InputParameter | CaseExpression - */ - public function ArithmeticPrimary(): AST\Node|string - { - if ($this->lexer->isNextToken(TokenType::T_OPEN_PARENTHESIS)) { - $this->match(TokenType::T_OPEN_PARENTHESIS); - - $expr = $this->SimpleArithmeticExpression(); - - $this->match(TokenType::T_CLOSE_PARENTHESIS); - - return new AST\ParenthesisExpression($expr); - } - - if ($this->lexer->lookahead === null) { - $this->syntaxError('ArithmeticPrimary'); - } - - switch ($this->lexer->lookahead->type) { - case TokenType::T_COALESCE: - case TokenType::T_NULLIF: - case TokenType::T_CASE: - return $this->CaseExpression(); - - case TokenType::T_IDENTIFIER: - $peek = $this->lexer->glimpse(); - - if ($peek !== null && $peek->value === '(') { - return $this->FunctionDeclaration(); - } - - if ($peek !== null && $peek->value === '.') { - return $this->SingleValuedPathExpression(); - } - - if (isset($this->queryComponents[$this->lexer->lookahead->value]['resultVariable'])) { - return $this->ResultVariable(); - } - - return $this->StateFieldPathExpression(); - - case TokenType::T_INPUT_PARAMETER: - return $this->InputParameter(); - - default: - $peek = $this->lexer->glimpse(); - - if ($peek !== null && $peek->value === '(') { - return $this->FunctionDeclaration(); - } - - return $this->Literal(); - } - } - - /** - * StringExpression ::= StringPrimary | ResultVariable | "(" Subselect ")" - */ - public function StringExpression(): AST\Subselect|AST\Node|string - { - $peek = $this->lexer->glimpse(); - assert($peek !== null); - - // Subselect - if ($this->lexer->isNextToken(TokenType::T_OPEN_PARENTHESIS) && $peek->type === TokenType::T_SELECT) { - $this->match(TokenType::T_OPEN_PARENTHESIS); - $expr = $this->Subselect(); - $this->match(TokenType::T_CLOSE_PARENTHESIS); - - return $expr; - } - - assert($this->lexer->lookahead !== null); - // ResultVariable (string) - if ( - $this->lexer->isNextToken(TokenType::T_IDENTIFIER) && - isset($this->queryComponents[$this->lexer->lookahead->value]['resultVariable']) - ) { - return $this->ResultVariable(); - } - - return $this->StringPrimary(); - } - - /** - * StringPrimary ::= StateFieldPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression | CaseExpression - */ - public function StringPrimary(): AST\Node - { - assert($this->lexer->lookahead !== null); - $lookaheadType = $this->lexer->lookahead->type; - - switch ($lookaheadType) { - case TokenType::T_IDENTIFIER: - $peek = $this->lexer->glimpse(); - assert($peek !== null); - - if ($peek->value === '.') { - return $this->StateFieldPathExpression(); - } - - if ($peek->value === '(') { - // do NOT directly go to FunctionsReturningString() because it doesn't check for custom functions. - return $this->FunctionDeclaration(); - } - - $this->syntaxError("'.' or '('"); - break; - - case TokenType::T_STRING: - $this->match(TokenType::T_STRING); - assert($this->lexer->token !== null); - - return new AST\Literal(AST\Literal::STRING, $this->lexer->token->value); - - case TokenType::T_INPUT_PARAMETER: - return $this->InputParameter(); - - case TokenType::T_CASE: - case TokenType::T_COALESCE: - case TokenType::T_NULLIF: - return $this->CaseExpression(); - - default: - assert($lookaheadType !== null); - if ($this->isAggregateFunction($lookaheadType)) { - return $this->AggregateExpression(); - } - } - - $this->syntaxError( - 'StateFieldPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression', - ); - } - - /** - * EntityExpression ::= SingleValuedAssociationPathExpression | SimpleEntityExpression - */ - public function EntityExpression(): AST\InputParameter|AST\PathExpression - { - $glimpse = $this->lexer->glimpse(); - assert($glimpse !== null); - - if ($this->lexer->isNextToken(TokenType::T_IDENTIFIER) && $glimpse->value === '.') { - return $this->SingleValuedAssociationPathExpression(); - } - - return $this->SimpleEntityExpression(); - } - - /** - * SimpleEntityExpression ::= IdentificationVariable | InputParameter - */ - public function SimpleEntityExpression(): AST\InputParameter|AST\PathExpression - { - if ($this->lexer->isNextToken(TokenType::T_INPUT_PARAMETER)) { - return $this->InputParameter(); - } - - return $this->StateFieldPathExpression(); - } - - /** - * AggregateExpression ::= - * ("AVG" | "MAX" | "MIN" | "SUM" | "COUNT") "(" ["DISTINCT"] SimpleArithmeticExpression ")" - */ - public function AggregateExpression(): AST\AggregateExpression - { - assert($this->lexer->lookahead !== null); - $lookaheadType = $this->lexer->lookahead->type; - $isDistinct = false; - - if (! in_array($lookaheadType, [TokenType::T_COUNT, TokenType::T_AVG, TokenType::T_MAX, TokenType::T_MIN, TokenType::T_SUM], true)) { - $this->syntaxError('One of: MAX, MIN, AVG, SUM, COUNT'); - } - - $this->match($lookaheadType); - assert($this->lexer->token !== null); - $functionName = $this->lexer->token->value; - $this->match(TokenType::T_OPEN_PARENTHESIS); - - if ($this->lexer->isNextToken(TokenType::T_DISTINCT)) { - $this->match(TokenType::T_DISTINCT); - $isDistinct = true; - } - - $pathExp = $this->SimpleArithmeticExpression(); - - $this->match(TokenType::T_CLOSE_PARENTHESIS); - - return new AST\AggregateExpression($functionName, $pathExp, $isDistinct); - } - - /** - * QuantifiedExpression ::= ("ALL" | "ANY" | "SOME") "(" Subselect ")" - */ - public function QuantifiedExpression(): AST\QuantifiedExpression - { - assert($this->lexer->lookahead !== null); - $lookaheadType = $this->lexer->lookahead->type; - $value = $this->lexer->lookahead->value; - - if (! in_array($lookaheadType, [TokenType::T_ALL, TokenType::T_ANY, TokenType::T_SOME], true)) { - $this->syntaxError('ALL, ANY or SOME'); - } - - $this->match($lookaheadType); - $this->match(TokenType::T_OPEN_PARENTHESIS); - - $qExpr = new AST\QuantifiedExpression($this->Subselect()); - $qExpr->type = $value; - - $this->match(TokenType::T_CLOSE_PARENTHESIS); - - return $qExpr; - } - - /** - * BetweenExpression ::= ArithmeticExpression ["NOT"] "BETWEEN" ArithmeticExpression "AND" ArithmeticExpression - */ - public function BetweenExpression(): AST\BetweenExpression - { - $not = false; - $arithExpr1 = $this->ArithmeticExpression(); - - if ($this->lexer->isNextToken(TokenType::T_NOT)) { - $this->match(TokenType::T_NOT); - $not = true; - } - - $this->match(TokenType::T_BETWEEN); - $arithExpr2 = $this->ArithmeticExpression(); - $this->match(TokenType::T_AND); - $arithExpr3 = $this->ArithmeticExpression(); - - return new AST\BetweenExpression($arithExpr1, $arithExpr2, $arithExpr3, $not); - } - - /** - * ComparisonExpression ::= ArithmeticExpression ComparisonOperator ( QuantifiedExpression | ArithmeticExpression ) - */ - public function ComparisonExpression(): AST\ComparisonExpression - { - $this->lexer->glimpse(); - - $leftExpr = $this->ArithmeticExpression(); - $operator = $this->ComparisonOperator(); - $rightExpr = $this->isNextAllAnySome() - ? $this->QuantifiedExpression() - : $this->ArithmeticExpression(); - - return new AST\ComparisonExpression($leftExpr, $operator, $rightExpr); - } - - /** - * InExpression ::= SingleValuedPathExpression ["NOT"] "IN" "(" (InParameter {"," InParameter}* | Subselect) ")" - */ - public function InExpression(): AST\InListExpression|AST\InSubselectExpression - { - $expression = $this->ArithmeticExpression(); - - $not = false; - if ($this->lexer->isNextToken(TokenType::T_NOT)) { - $this->match(TokenType::T_NOT); - $not = true; - } - - $this->match(TokenType::T_IN); - $this->match(TokenType::T_OPEN_PARENTHESIS); - - if ($this->lexer->isNextToken(TokenType::T_SELECT)) { - $inExpression = new AST\InSubselectExpression( - $expression, - $this->Subselect(), - $not, - ); - } else { - $literals = [$this->InParameter()]; - - while ($this->lexer->isNextToken(TokenType::T_COMMA)) { - $this->match(TokenType::T_COMMA); - $literals[] = $this->InParameter(); - } - - $inExpression = new AST\InListExpression( - $expression, - $literals, - $not, - ); - } - - $this->match(TokenType::T_CLOSE_PARENTHESIS); - - return $inExpression; - } - - /** - * InstanceOfExpression ::= IdentificationVariable ["NOT"] "INSTANCE" ["OF"] (InstanceOfParameter | "(" InstanceOfParameter {"," InstanceOfParameter}* ")") - */ - public function InstanceOfExpression(): AST\InstanceOfExpression - { - $identificationVariable = $this->IdentificationVariable(); - - $not = false; - if ($this->lexer->isNextToken(TokenType::T_NOT)) { - $this->match(TokenType::T_NOT); - $not = true; - } - - $this->match(TokenType::T_INSTANCE); - $this->match(TokenType::T_OF); - - $exprValues = $this->lexer->isNextToken(TokenType::T_OPEN_PARENTHESIS) - ? $this->InstanceOfParameterList() - : [$this->InstanceOfParameter()]; - - return new AST\InstanceOfExpression( - $identificationVariable, - $exprValues, - $not, - ); - } - - /** @return non-empty-list */ - public function InstanceOfParameterList(): array - { - $this->match(TokenType::T_OPEN_PARENTHESIS); - - $exprValues = [$this->InstanceOfParameter()]; - - while ($this->lexer->isNextToken(TokenType::T_COMMA)) { - $this->match(TokenType::T_COMMA); - - $exprValues[] = $this->InstanceOfParameter(); - } - - $this->match(TokenType::T_CLOSE_PARENTHESIS); - - return $exprValues; - } - - /** - * InstanceOfParameter ::= AbstractSchemaName | InputParameter - */ - public function InstanceOfParameter(): AST\InputParameter|string - { - if ($this->lexer->isNextToken(TokenType::T_INPUT_PARAMETER)) { - $this->match(TokenType::T_INPUT_PARAMETER); - assert($this->lexer->token !== null); - - return new AST\InputParameter($this->lexer->token->value); - } - - $abstractSchemaName = $this->AbstractSchemaName(); - - $this->validateAbstractSchemaName($abstractSchemaName); - - return $abstractSchemaName; - } - - /** - * LikeExpression ::= StringExpression ["NOT"] "LIKE" StringPrimary ["ESCAPE" char] - */ - public function LikeExpression(): AST\LikeExpression - { - $stringExpr = $this->StringExpression(); - $not = false; - - if ($this->lexer->isNextToken(TokenType::T_NOT)) { - $this->match(TokenType::T_NOT); - $not = true; - } - - $this->match(TokenType::T_LIKE); - - if ($this->lexer->isNextToken(TokenType::T_INPUT_PARAMETER)) { - $this->match(TokenType::T_INPUT_PARAMETER); - assert($this->lexer->token !== null); - $stringPattern = new AST\InputParameter($this->lexer->token->value); - } else { - $stringPattern = $this->StringPrimary(); - } - - $escapeChar = null; - - if ($this->lexer->lookahead !== null && $this->lexer->lookahead->type === TokenType::T_ESCAPE) { - $this->match(TokenType::T_ESCAPE); - $this->match(TokenType::T_STRING); - assert($this->lexer->token !== null); - - $escapeChar = new AST\Literal(AST\Literal::STRING, $this->lexer->token->value); - } - - return new AST\LikeExpression($stringExpr, $stringPattern, $escapeChar, $not); - } - - /** - * NullComparisonExpression ::= (InputParameter | NullIfExpression | CoalesceExpression | AggregateExpression | FunctionDeclaration | IdentificationVariable | SingleValuedPathExpression | ResultVariable) "IS" ["NOT"] "NULL" - */ - public function NullComparisonExpression(): AST\NullComparisonExpression - { - switch (true) { - case $this->lexer->isNextToken(TokenType::T_INPUT_PARAMETER): - $this->match(TokenType::T_INPUT_PARAMETER); - assert($this->lexer->token !== null); - - $expr = new AST\InputParameter($this->lexer->token->value); - break; - - case $this->lexer->isNextToken(TokenType::T_NULLIF): - $expr = $this->NullIfExpression(); - break; - - case $this->lexer->isNextToken(TokenType::T_COALESCE): - $expr = $this->CoalesceExpression(); - break; - - case $this->isFunction(): - $expr = $this->FunctionDeclaration(); - break; - - default: - // We need to check if we are in a IdentificationVariable or SingleValuedPathExpression - $glimpse = $this->lexer->glimpse(); - assert($glimpse !== null); - - if ($glimpse->type === TokenType::T_DOT) { - $expr = $this->SingleValuedPathExpression(); - - // Leave switch statement - break; - } - - assert($this->lexer->lookahead !== null); - $lookaheadValue = $this->lexer->lookahead->value; - - // Validate existing component - if (! isset($this->queryComponents[$lookaheadValue])) { - $this->semanticalError('Cannot add having condition on undefined result variable.'); - } - - // Validate SingleValuedPathExpression (ie.: "product") - if (isset($this->queryComponents[$lookaheadValue]['metadata'])) { - $expr = $this->SingleValuedPathExpression(); - break; - } - - // Validating ResultVariable - if (! isset($this->queryComponents[$lookaheadValue]['resultVariable'])) { - $this->semanticalError('Cannot add having condition on a non result variable.'); - } - - $expr = $this->ResultVariable(); - break; - } - - $this->match(TokenType::T_IS); - - $not = false; - if ($this->lexer->isNextToken(TokenType::T_NOT)) { - $this->match(TokenType::T_NOT); - - $not = true; - } - - $this->match(TokenType::T_NULL); - - return new AST\NullComparisonExpression($expr, $not); - } - - /** - * ExistsExpression ::= ["NOT"] "EXISTS" "(" Subselect ")" - */ - public function ExistsExpression(): AST\ExistsExpression - { - $not = false; - - if ($this->lexer->isNextToken(TokenType::T_NOT)) { - $this->match(TokenType::T_NOT); - $not = true; - } - - $this->match(TokenType::T_EXISTS); - $this->match(TokenType::T_OPEN_PARENTHESIS); - - $subselect = $this->Subselect(); - - $this->match(TokenType::T_CLOSE_PARENTHESIS); - - return new AST\ExistsExpression($subselect, $not); - } - - /** - * ComparisonOperator ::= "=" | "<" | "<=" | "<>" | ">" | ">=" | "!=" - */ - public function ComparisonOperator(): string - { - assert($this->lexer->lookahead !== null); - switch ($this->lexer->lookahead->value) { - case '=': - $this->match(TokenType::T_EQUALS); - - return '='; - - case '<': - $this->match(TokenType::T_LOWER_THAN); - $operator = '<'; - - if ($this->lexer->isNextToken(TokenType::T_EQUALS)) { - $this->match(TokenType::T_EQUALS); - $operator .= '='; - } elseif ($this->lexer->isNextToken(TokenType::T_GREATER_THAN)) { - $this->match(TokenType::T_GREATER_THAN); - $operator .= '>'; - } - - return $operator; - - case '>': - $this->match(TokenType::T_GREATER_THAN); - $operator = '>'; - - if ($this->lexer->isNextToken(TokenType::T_EQUALS)) { - $this->match(TokenType::T_EQUALS); - $operator .= '='; - } - - return $operator; - - case '!': - $this->match(TokenType::T_NEGATE); - $this->match(TokenType::T_EQUALS); - - return '<>'; - - default: - $this->syntaxError('=, <, <=, <>, >, >=, !='); - } - } - - /** - * FunctionDeclaration ::= FunctionsReturningStrings | FunctionsReturningNumerics | FunctionsReturningDatetime - */ - public function FunctionDeclaration(): Functions\FunctionNode - { - assert($this->lexer->lookahead !== null); - $token = $this->lexer->lookahead; - $funcName = strtolower($token->value); - - $customFunctionDeclaration = $this->CustomFunctionDeclaration(); - - // Check for custom functions functions first! - switch (true) { - case $customFunctionDeclaration !== null: - return $customFunctionDeclaration; - - case isset(self::$stringFunctions[$funcName]): - return $this->FunctionsReturningStrings(); - - case isset(self::$numericFunctions[$funcName]): - return $this->FunctionsReturningNumerics(); - - case isset(self::$datetimeFunctions[$funcName]): - return $this->FunctionsReturningDatetime(); - - default: - $this->syntaxError('known function', $token); - } - } - - /** - * Helper function for FunctionDeclaration grammar rule. - */ - private function CustomFunctionDeclaration(): Functions\FunctionNode|null - { - assert($this->lexer->lookahead !== null); - $token = $this->lexer->lookahead; - $funcName = strtolower($token->value); - - // Check for custom functions afterwards - $config = $this->em->getConfiguration(); - - return match (true) { - $config->getCustomStringFunction($funcName) !== null => $this->CustomFunctionsReturningStrings(), - $config->getCustomNumericFunction($funcName) !== null => $this->CustomFunctionsReturningNumerics(), - $config->getCustomDatetimeFunction($funcName) !== null => $this->CustomFunctionsReturningDatetime(), - default => null, - }; - } - - /** - * FunctionsReturningNumerics ::= - * "LENGTH" "(" StringPrimary ")" | - * "LOCATE" "(" StringPrimary "," StringPrimary ["," SimpleArithmeticExpression]")" | - * "ABS" "(" SimpleArithmeticExpression ")" | - * "SQRT" "(" SimpleArithmeticExpression ")" | - * "MOD" "(" SimpleArithmeticExpression "," SimpleArithmeticExpression ")" | - * "SIZE" "(" CollectionValuedPathExpression ")" | - * "DATE_DIFF" "(" ArithmeticPrimary "," ArithmeticPrimary ")" | - * "BIT_AND" "(" ArithmeticPrimary "," ArithmeticPrimary ")" | - * "BIT_OR" "(" ArithmeticPrimary "," ArithmeticPrimary ")" - */ - public function FunctionsReturningNumerics(): AST\Functions\FunctionNode - { - assert($this->lexer->lookahead !== null); - $funcNameLower = strtolower($this->lexer->lookahead->value); - $funcClass = self::$numericFunctions[$funcNameLower]; - - $function = new $funcClass($funcNameLower); - $function->parse($this); - - return $function; - } - - public function CustomFunctionsReturningNumerics(): AST\Functions\FunctionNode - { - assert($this->lexer->lookahead !== null); - // getCustomNumericFunction is case-insensitive - $functionName = strtolower($this->lexer->lookahead->value); - $functionClass = $this->em->getConfiguration()->getCustomNumericFunction($functionName); - - assert($functionClass !== null); - - $function = is_string($functionClass) - ? new $functionClass($functionName) - : $functionClass($functionName); - - $function->parse($this); - - return $function; - } - - /** - * FunctionsReturningDateTime ::= - * "CURRENT_DATE" | - * "CURRENT_TIME" | - * "CURRENT_TIMESTAMP" | - * "DATE_ADD" "(" ArithmeticPrimary "," ArithmeticPrimary "," StringPrimary ")" | - * "DATE_SUB" "(" ArithmeticPrimary "," ArithmeticPrimary "," StringPrimary ")" - */ - public function FunctionsReturningDatetime(): AST\Functions\FunctionNode - { - assert($this->lexer->lookahead !== null); - $funcNameLower = strtolower($this->lexer->lookahead->value); - $funcClass = self::$datetimeFunctions[$funcNameLower]; - - $function = new $funcClass($funcNameLower); - $function->parse($this); - - return $function; - } - - public function CustomFunctionsReturningDatetime(): AST\Functions\FunctionNode - { - assert($this->lexer->lookahead !== null); - // getCustomDatetimeFunction is case-insensitive - $functionName = $this->lexer->lookahead->value; - $functionClass = $this->em->getConfiguration()->getCustomDatetimeFunction($functionName); - - assert($functionClass !== null); - - $function = is_string($functionClass) - ? new $functionClass($functionName) - : $functionClass($functionName); - - $function->parse($this); - - return $function; - } - - /** - * FunctionsReturningStrings ::= - * "CONCAT" "(" StringPrimary "," StringPrimary {"," StringPrimary}* ")" | - * "SUBSTRING" "(" StringPrimary "," SimpleArithmeticExpression "," SimpleArithmeticExpression ")" | - * "TRIM" "(" [["LEADING" | "TRAILING" | "BOTH"] [char] "FROM"] StringPrimary ")" | - * "LOWER" "(" StringPrimary ")" | - * "UPPER" "(" StringPrimary ")" | - * "IDENTITY" "(" SingleValuedAssociationPathExpression {"," string} ")" - */ - public function FunctionsReturningStrings(): AST\Functions\FunctionNode - { - assert($this->lexer->lookahead !== null); - $funcNameLower = strtolower($this->lexer->lookahead->value); - $funcClass = self::$stringFunctions[$funcNameLower]; - - $function = new $funcClass($funcNameLower); - $function->parse($this); - - return $function; - } - - public function CustomFunctionsReturningStrings(): Functions\FunctionNode - { - assert($this->lexer->lookahead !== null); - // getCustomStringFunction is case-insensitive - $functionName = $this->lexer->lookahead->value; - $functionClass = $this->em->getConfiguration()->getCustomStringFunction($functionName); - - assert($functionClass !== null); - - $function = is_string($functionClass) - ? new $functionClass($functionName) - : $functionClass($functionName); - - $function->parse($this); - - return $function; - } - - private function getMetadataForDqlAlias(string $dqlAlias): ClassMetadata - { - if (! isset($this->queryComponents[$dqlAlias]['metadata'])) { - throw new LogicException(sprintf('No metadata for DQL alias: %s', $dqlAlias)); - } - - return $this->queryComponents[$dqlAlias]['metadata']; - } -} diff --git a/vendor/doctrine/orm/src/Query/ParserResult.php b/vendor/doctrine/orm/src/Query/ParserResult.php deleted file mode 100644 index 8b5ee1f..0000000 --- a/vendor/doctrine/orm/src/Query/ParserResult.php +++ /dev/null @@ -1,118 +0,0 @@ -> - */ - private array $parameterMappings = []; - - /** - * Initializes a new instance of the ParserResult class. - * The new instance is initialized with an empty ResultSetMapping. - */ - public function __construct() - { - $this->resultSetMapping = new ResultSetMapping(); - } - - /** - * Gets the ResultSetMapping for the parsed query. - * - * @return ResultSetMapping The result set mapping of the parsed query - */ - public function getResultSetMapping(): ResultSetMapping - { - return $this->resultSetMapping; - } - - /** - * Sets the ResultSetMapping of the parsed query. - */ - public function setResultSetMapping(ResultSetMapping $rsm): void - { - $this->resultSetMapping = $rsm; - } - - /** - * Sets the SQL executor that should be used for this ParserResult. - */ - public function setSqlExecutor(AbstractSqlExecutor $executor): void - { - $this->sqlExecutor = $executor; - } - - /** - * Gets the SQL executor used by this ParserResult. - */ - public function getSqlExecutor(): AbstractSqlExecutor - { - if ($this->sqlExecutor === null) { - throw new LogicException(sprintf( - 'Executor not set yet. Call %s::setSqlExecutor() first.', - self::class, - )); - } - - return $this->sqlExecutor; - } - - /** - * Adds a DQL to SQL parameter mapping. One DQL parameter name/position can map to - * several SQL parameter positions. - */ - public function addParameterMapping(string|int $dqlPosition, int $sqlPosition): void - { - $this->parameterMappings[$dqlPosition][] = $sqlPosition; - } - - /** - * Gets all DQL to SQL parameter mappings. - * - * @psalm-return array> The parameter mappings. - */ - public function getParameterMappings(): array - { - return $this->parameterMappings; - } - - /** - * Gets the SQL parameter positions for a DQL parameter name/position. - * - * @param string|int $dqlPosition The name or position of the DQL parameter. - * - * @return int[] The positions of the corresponding SQL parameters. - * @psalm-return list - */ - public function getSqlParameterPositions(string|int $dqlPosition): array - { - return $this->parameterMappings[$dqlPosition]; - } -} diff --git a/vendor/doctrine/orm/src/Query/Printer.php b/vendor/doctrine/orm/src/Query/Printer.php deleted file mode 100644 index db1f159..0000000 --- a/vendor/doctrine/orm/src/Query/Printer.php +++ /dev/null @@ -1,64 +0,0 @@ -println('(' . $name); - $this->indent++; - } - - /** - * Decreases indentation level by one and prints a closing parenthesis. - * - * This method is called after executing a production. - */ - public function endProduction(): void - { - $this->indent--; - $this->println(')'); - } - - /** - * Prints text indented with spaces depending on current indentation level. - * - * @param string $str The text. - */ - public function println(string $str): void - { - if (! $this->silent) { - echo str_repeat(' ', $this->indent), $str, "\n"; - } - } -} diff --git a/vendor/doctrine/orm/src/Query/QueryException.php b/vendor/doctrine/orm/src/Query/QueryException.php deleted file mode 100644 index ae945b1..0000000 --- a/vendor/doctrine/orm/src/Query/QueryException.php +++ /dev/null @@ -1,155 +0,0 @@ - or ? expected.'); - } - - public static function unknownParameter(string $key): self - { - return new self('Invalid parameter: token ' . $key . ' is not defined in the query.'); - } - - public static function parameterTypeMismatch(): self - { - return new self('DQL Query parameter and type numbers mismatch, but have to be exactly equal.'); - } - - public static function invalidPathExpression(PathExpression $pathExpr): self - { - return new self( - "Invalid PathExpression '" . $pathExpr->identificationVariable . '.' . $pathExpr->field . "'.", - ); - } - - public static function invalidLiteral(string|Stringable $literal): self - { - return new self("Invalid literal '" . $literal . "'"); - } - - public static function iterateWithFetchJoinCollectionNotAllowed(AssociationMapping $assoc): self - { - return new self( - 'Invalid query operation: Not allowed to iterate over fetch join collections ' . - 'in class ' . $assoc->sourceEntity . ' association ' . $assoc->fieldName, - ); - } - - /** - * @param string[] $assoc - * @psalm-param array $assoc - */ - public static function overwritingJoinConditionsNotYetSupported(array $assoc): self - { - return new self( - 'Unsupported query operation: It is not yet possible to overwrite the join ' . - 'conditions in class ' . $assoc['sourceEntityName'] . ' association ' . $assoc['fieldName'] . '. ' . - 'Use WITH to append additional join conditions to the association.', - ); - } - - public static function associationPathInverseSideNotSupported(PathExpression $pathExpr): self - { - return new self( - 'A single-valued association path expression to an inverse side is not supported in DQL queries. ' . - 'Instead of "' . $pathExpr->identificationVariable . '.' . $pathExpr->field . '" use an explicit join.', - ); - } - - public static function iterateWithFetchJoinNotAllowed(AssociationMapping $assoc): self - { - return new self( - 'Iterate with fetch join in class ' . $assoc->sourceEntity . - ' using association ' . $assoc->fieldName . ' not allowed.', - ); - } - - public static function eagerFetchJoinWithNotAllowed(string $sourceEntity, string $fieldName): self - { - return new self( - 'Associations with fetch-mode=EAGER may not be using WITH conditions in - "' . $sourceEntity . '#' . $fieldName . '".', - ); - } - - public static function iterateWithMixedResultNotAllowed(): self - { - return new self('Iterating a query with mixed results (using scalars) is not supported.'); - } - - public static function associationPathCompositeKeyNotSupported(): self - { - return new self( - 'A single-valued association path expression to an entity with a composite primary ' . - 'key is not supported. Explicitly name the components of the composite primary key ' . - 'in the query.', - ); - } - - public static function instanceOfUnrelatedClass(string $className, string $rootClass): self - { - return new self("Cannot check if a child of '" . $rootClass . "' is instanceof '" . $className . "', " . - 'inheritance hierarchy does not exists between these two classes.'); - } - - public static function invalidQueryComponent(string $dqlAlias): self - { - return new self( - "Invalid query component given for DQL alias '" . $dqlAlias . "', " . - "requires 'metadata', 'parent', 'relation', 'map', 'nestingLevel' and 'token' keys.", - ); - } -} diff --git a/vendor/doctrine/orm/src/Query/QueryExpressionVisitor.php b/vendor/doctrine/orm/src/Query/QueryExpressionVisitor.php deleted file mode 100644 index 3e0ec65..0000000 --- a/vendor/doctrine/orm/src/Query/QueryExpressionVisitor.php +++ /dev/null @@ -1,180 +0,0 @@ - Expr\Comparison::GT, - Comparison::GTE => Expr\Comparison::GTE, - Comparison::LT => Expr\Comparison::LT, - Comparison::LTE => Expr\Comparison::LTE, - ]; - - private readonly Expr $expr; - - /** @var list */ - private array $parameters = []; - - /** @param mixed[] $queryAliases */ - public function __construct( - private readonly array $queryAliases, - ) { - $this->expr = new Expr(); - } - - /** - * Gets bound parameters. - * Filled after {@link dispach()}. - * - * @return ArrayCollection - */ - public function getParameters(): ArrayCollection - { - return new ArrayCollection($this->parameters); - } - - public function clearParameters(): void - { - $this->parameters = []; - } - - /** - * Converts Criteria expression to Query one based on static map. - */ - private static function convertComparisonOperator(string $criteriaOperator): string|null - { - return self::OPERATOR_MAP[$criteriaOperator] ?? null; - } - - public function walkCompositeExpression(CompositeExpression $expr): mixed - { - $expressionList = []; - - foreach ($expr->getExpressionList() as $child) { - $expressionList[] = $this->dispatch($child); - } - - return match ($expr->getType()) { - CompositeExpression::TYPE_AND => new Expr\Andx($expressionList), - CompositeExpression::TYPE_OR => new Expr\Orx($expressionList), - CompositeExpression::TYPE_NOT => $this->expr->not($expressionList[0]), - default => throw new RuntimeException('Unknown composite ' . $expr->getType()), - }; - } - - public function walkComparison(Comparison $comparison): mixed - { - if (! isset($this->queryAliases[0])) { - throw new QueryException('No aliases are set before invoking walkComparison().'); - } - - $field = $this->queryAliases[0] . '.' . $comparison->getField(); - - foreach ($this->queryAliases as $alias) { - if (str_starts_with($comparison->getField() . '.', $alias . '.')) { - $field = $comparison->getField(); - break; - } - } - - $parameterName = str_replace('.', '_', $comparison->getField()); - - foreach ($this->parameters as $parameter) { - if ($parameter->getName() === $parameterName) { - $parameterName .= '_' . count($this->parameters); - break; - } - } - - $parameter = new Parameter($parameterName, $this->walkValue($comparison->getValue())); - $placeholder = ':' . $parameterName; - - switch ($comparison->getOperator()) { - case Comparison::IN: - $this->parameters[] = $parameter; - - return $this->expr->in($field, $placeholder); - - case Comparison::NIN: - $this->parameters[] = $parameter; - - return $this->expr->notIn($field, $placeholder); - - case Comparison::EQ: - case Comparison::IS: - if ($this->walkValue($comparison->getValue()) === null) { - return $this->expr->isNull($field); - } - - $this->parameters[] = $parameter; - - return $this->expr->eq($field, $placeholder); - - case Comparison::NEQ: - if ($this->walkValue($comparison->getValue()) === null) { - return $this->expr->isNotNull($field); - } - - $this->parameters[] = $parameter; - - return $this->expr->neq($field, $placeholder); - - case Comparison::CONTAINS: - $parameter->setValue('%' . $parameter->getValue() . '%', $parameter->getType()); - $this->parameters[] = $parameter; - - return $this->expr->like($field, $placeholder); - - case Comparison::MEMBER_OF: - return $this->expr->isMemberOf($comparison->getField(), $comparison->getValue()->getValue()); - - case Comparison::STARTS_WITH: - $parameter->setValue($parameter->getValue() . '%', $parameter->getType()); - $this->parameters[] = $parameter; - - return $this->expr->like($field, $placeholder); - - case Comparison::ENDS_WITH: - $parameter->setValue('%' . $parameter->getValue(), $parameter->getType()); - $this->parameters[] = $parameter; - - return $this->expr->like($field, $placeholder); - - default: - $operator = self::convertComparisonOperator($comparison->getOperator()); - if ($operator) { - $this->parameters[] = $parameter; - - return new Expr\Comparison( - $field, - $operator, - $placeholder, - ); - } - - throw new RuntimeException('Unknown comparison operator: ' . $comparison->getOperator()); - } - } - - public function walkValue(Value $value): mixed - { - return $value->getValue(); - } -} diff --git a/vendor/doctrine/orm/src/Query/ResultSetMapping.php b/vendor/doctrine/orm/src/Query/ResultSetMapping.php deleted file mode 100644 index 612474d..0000000 --- a/vendor/doctrine/orm/src/Query/ResultSetMapping.php +++ /dev/null @@ -1,547 +0,0 @@ -Users should use the public methods. - * - * @todo Think about whether the number of lookup maps can be reduced. - */ -class ResultSetMapping -{ - /** - * Whether the result is mixed (contains scalar values together with field values). - * - * @ignore - */ - public bool $isMixed = false; - - /** - * Whether the result is a select statement. - * - * @ignore - */ - public bool $isSelect = true; - - /** - * Maps alias names to class names. - * - * @ignore - * @psalm-var array - */ - public array $aliasMap = []; - - /** - * Maps alias names to related association field names. - * - * @ignore - * @psalm-var array - */ - public array $relationMap = []; - - /** - * Maps alias names to parent alias names. - * - * @ignore - * @psalm-var array - */ - public array $parentAliasMap = []; - - /** - * Maps column names in the result set to field names for each class. - * - * @ignore - * @psalm-var array - */ - public array $fieldMappings = []; - - /** - * Maps column names in the result set to the alias/field name to use in the mapped result. - * - * @ignore - * @psalm-var array - */ - public array $scalarMappings = []; - - /** - * Maps scalar columns to enums - * - * @ignore - * @psalm-var array - */ - public $enumMappings = []; - - /** - * Maps column names in the result set to the alias/field type to use in the mapped result. - * - * @ignore - * @psalm-var array - */ - public array $typeMappings = []; - - /** - * Maps entities in the result set to the alias name to use in the mapped result. - * - * @ignore - * @psalm-var array - */ - public array $entityMappings = []; - - /** - * Maps column names of meta columns (foreign keys, discriminator columns, ...) to field names. - * - * @ignore - * @psalm-var array - */ - public array $metaMappings = []; - - /** - * Maps column names in the result set to the alias they belong to. - * - * @ignore - * @psalm-var array - */ - public array $columnOwnerMap = []; - - /** - * List of columns in the result set that are used as discriminator columns. - * - * @ignore - * @psalm-var array - */ - public array $discriminatorColumns = []; - - /** - * Maps alias names to field names that should be used for indexing. - * - * @ignore - * @psalm-var array - */ - public array $indexByMap = []; - - /** - * Map from column names to class names that declare the field the column is mapped to. - * - * @ignore - * @psalm-var array - */ - public array $declaringClasses = []; - - /** - * This is necessary to hydrate derivate foreign keys correctly. - * - * @psalm-var array> - */ - public array $isIdentifierColumn = []; - - /** - * Maps column names in the result set to field names for each new object expression. - * - * @psalm-var array> - */ - public array $newObjectMappings = []; - - /** - * Maps metadata parameter names to the metadata attribute. - * - * @psalm-var array - */ - public array $metadataParameterMapping = []; - - /** - * Contains query parameter names to be resolved as discriminator values - * - * @psalm-var array - */ - public array $discriminatorParameters = []; - - /** - * Adds an entity result to this ResultSetMapping. - * - * @param string $class The class name of the entity. - * @param string $alias The alias for the class. The alias must be unique among all entity - * results or joined entity results within this ResultSetMapping. - * @param string|null $resultAlias The result alias with which the entity result should be - * placed in the result structure. - * @psalm-param class-string $class - * - * @return $this - * - * @todo Rename: addRootEntity - */ - public function addEntityResult(string $class, string $alias, string|null $resultAlias = null): static - { - $this->aliasMap[$alias] = $class; - $this->entityMappings[$alias] = $resultAlias; - - if ($resultAlias !== null) { - $this->isMixed = true; - } - - return $this; - } - - /** - * Sets a discriminator column for an entity result or joined entity result. - * The discriminator column will be used to determine the concrete class name to - * instantiate. - * - * @param string $alias The alias of the entity result or joined entity result the discriminator - * column should be used for. - * @param string $discrColumn The name of the discriminator column in the SQL result set. - * - * @return $this - * - * @todo Rename: addDiscriminatorColumn - */ - public function setDiscriminatorColumn(string $alias, string $discrColumn): static - { - $this->discriminatorColumns[$alias] = $discrColumn; - $this->columnOwnerMap[$discrColumn] = $alias; - - return $this; - } - - /** - * Sets a field to use for indexing an entity result or joined entity result. - * - * @param string $alias The alias of an entity result or joined entity result. - * @param string $fieldName The name of the field to use for indexing. - * - * @return $this - */ - public function addIndexBy(string $alias, string $fieldName): static - { - $found = false; - - foreach ([...$this->metaMappings, ...$this->fieldMappings] as $columnName => $columnFieldName) { - if (! ($columnFieldName === $fieldName && $this->columnOwnerMap[$columnName] === $alias)) { - continue; - } - - $this->addIndexByColumn($alias, $columnName); - $found = true; - - break; - } - - /* TODO: check if this exception can be put back, for now it's gone because of assumptions made by some ORM internals - if ( ! $found) { - $message = sprintf( - 'Cannot add index by for DQL alias %s and field %s without calling addFieldResult() for them before.', - $alias, - $fieldName - ); - - throw new \LogicException($message); - } - */ - - return $this; - } - - /** - * Sets to index by a scalar result column name. - * - * @return $this - */ - public function addIndexByScalar(string $resultColumnName): static - { - $this->indexByMap['scalars'] = $resultColumnName; - - return $this; - } - - /** - * Sets a column to use for indexing an entity or joined entity result by the given alias name. - * - * @return $this - */ - public function addIndexByColumn(string $alias, string $resultColumnName): static - { - $this->indexByMap[$alias] = $resultColumnName; - - return $this; - } - - /** - * Checks whether an entity result or joined entity result with a given alias has - * a field set for indexing. - * - * @todo Rename: isIndexed($alias) - */ - public function hasIndexBy(string $alias): bool - { - return isset($this->indexByMap[$alias]); - } - - /** - * Checks whether the column with the given name is mapped as a field result - * as part of an entity result or joined entity result. - * - * @param string $columnName The name of the column in the SQL result set. - * - * @todo Rename: isField - */ - public function isFieldResult(string $columnName): bool - { - return isset($this->fieldMappings[$columnName]); - } - - /** - * Adds a field to the result that belongs to an entity or joined entity. - * - * @param string $alias The alias of the root entity or joined entity to which the field belongs. - * @param string $columnName The name of the column in the SQL result set. - * @param string $fieldName The name of the field on the declaring class. - * @param string|null $declaringClass The name of the class that declares/owns the specified field. - * When $alias refers to a superclass in a mapped hierarchy but - * the field $fieldName is defined on a subclass, specify that here. - * If not specified, the field is assumed to belong to the class - * designated by $alias. - * @psalm-param class-string|null $declaringClass - * - * @return $this - * - * @todo Rename: addField - */ - public function addFieldResult(string $alias, string $columnName, string $fieldName, string|null $declaringClass = null): static - { - // column name (in result set) => field name - $this->fieldMappings[$columnName] = $fieldName; - // column name => alias of owner - $this->columnOwnerMap[$columnName] = $alias; - // field name => class name of declaring class - $this->declaringClasses[$columnName] = $declaringClass ?: $this->aliasMap[$alias]; - - if (! $this->isMixed && $this->scalarMappings) { - $this->isMixed = true; - } - - return $this; - } - - /** - * Adds a joined entity result. - * - * @param string $class The class name of the joined entity. - * @param string $alias The unique alias to use for the joined entity. - * @param string $parentAlias The alias of the entity result that is the parent of this joined result. - * @param string $relation The association field that connects the parent entity result - * with the joined entity result. - * @psalm-param class-string $class - * - * @return $this - * - * @todo Rename: addJoinedEntity - */ - public function addJoinedEntityResult(string $class, string $alias, string $parentAlias, string $relation): static - { - $this->aliasMap[$alias] = $class; - $this->parentAliasMap[$alias] = $parentAlias; - $this->relationMap[$alias] = $relation; - - return $this; - } - - /** - * Adds a scalar result mapping. - * - * @param string $columnName The name of the column in the SQL result set. - * @param string|int $alias The result alias with which the scalar result should be placed in the result structure. - * @param string $type The column type - * - * @return $this - * - * @todo Rename: addScalar - */ - public function addScalarResult(string $columnName, string|int $alias, string $type = 'string'): static - { - $this->scalarMappings[$columnName] = $alias; - $this->typeMappings[$columnName] = $type; - - if (! $this->isMixed && $this->fieldMappings) { - $this->isMixed = true; - } - - return $this; - } - - /** - * Adds a scalar result mapping. - * - * @param string $columnName The name of the column in the SQL result set. - * @param string $enumType The enum type - * - * @return $this - */ - public function addEnumResult(string $columnName, string $enumType): static - { - $this->enumMappings[$columnName] = $enumType; - - return $this; - } - - /** - * Adds a metadata parameter mappings. - */ - public function addMetadataParameterMapping(string|int $parameter, string $attribute): void - { - $this->metadataParameterMapping[$parameter] = $attribute; - } - - /** - * Checks whether a column with a given name is mapped as a scalar result. - * - * @todo Rename: isScalar - */ - public function isScalarResult(string $columnName): bool - { - return isset($this->scalarMappings[$columnName]); - } - - /** - * Gets the name of the class of an entity result or joined entity result, - * identified by the given unique alias. - * - * @psalm-return class-string - */ - public function getClassName(string $alias): string - { - return $this->aliasMap[$alias]; - } - - /** - * Gets the field alias for a column that is mapped as a scalar value. - * - * @param string $columnName The name of the column in the SQL result set. - */ - public function getScalarAlias(string $columnName): string|int - { - return $this->scalarMappings[$columnName]; - } - - /** - * Gets the name of the class that owns a field mapping for the specified column. - * - * @psalm-return class-string - */ - public function getDeclaringClass(string $columnName): string - { - return $this->declaringClasses[$columnName]; - } - - public function getRelation(string $alias): string - { - return $this->relationMap[$alias]; - } - - public function isRelation(string $alias): bool - { - return isset($this->relationMap[$alias]); - } - - /** - * Gets the alias of the class that owns a field mapping for the specified column. - */ - public function getEntityAlias(string $columnName): string - { - return $this->columnOwnerMap[$columnName]; - } - - /** - * Gets the parent alias of the given alias. - */ - public function getParentAlias(string $alias): string - { - return $this->parentAliasMap[$alias]; - } - - /** - * Checks whether the given alias has a parent alias. - */ - public function hasParentAlias(string $alias): bool - { - return isset($this->parentAliasMap[$alias]); - } - - /** - * Gets the field name for a column name. - */ - public function getFieldName(string $columnName): string - { - return $this->fieldMappings[$columnName]; - } - - /** @psalm-return array */ - public function getAliasMap(): array - { - return $this->aliasMap; - } - - /** - * Gets the number of different entities that appear in the mapped result. - * - * @psalm-return 0|positive-int - */ - public function getEntityResultCount(): int - { - return count($this->aliasMap); - } - - /** - * Checks whether this ResultSetMapping defines a mixed result. - * - * Mixed results can only occur in object and array (graph) hydration. In such a - * case a mixed result means that scalar values are mixed with objects/array in - * the result. - */ - public function isMixedResult(): bool - { - return $this->isMixed; - } - - /** - * Adds a meta column (foreign key or discriminator column) to the result set. - * - * @param string $alias The result alias with which the meta result should be placed in the result structure. - * @param string $columnName The name of the column in the SQL result set. - * @param string $fieldName The name of the field on the declaring class. - * @param string|null $type The column type - * - * @return $this - * - * @todo Make all methods of this class require all parameters and not infer anything - */ - public function addMetaResult( - string $alias, - string $columnName, - string $fieldName, - bool $isIdentifierColumn = false, - string|null $type = null, - ): static { - $this->metaMappings[$columnName] = $fieldName; - $this->columnOwnerMap[$columnName] = $alias; - - if ($isIdentifierColumn) { - $this->isIdentifierColumn[$alias][$columnName] = true; - } - - if ($type) { - $this->typeMappings[$columnName] = $type; - } - - return $this; - } -} diff --git a/vendor/doctrine/orm/src/Query/ResultSetMappingBuilder.php b/vendor/doctrine/orm/src/Query/ResultSetMappingBuilder.php deleted file mode 100644 index f28f3a9..0000000 --- a/vendor/doctrine/orm/src/Query/ResultSetMappingBuilder.php +++ /dev/null @@ -1,281 +0,0 @@ - queryColumnName). - * @psalm-param class-string $class - * @psalm-param array $renamedColumns - * @psalm-param self::COLUMN_RENAMING_*|null $renameMode - */ - public function addRootEntityFromClassMetadata( - string $class, - string $alias, - array $renamedColumns = [], - int|null $renameMode = null, - ): void { - $renameMode = $renameMode ?: $this->defaultRenameMode; - $columnAliasMap = $this->getColumnAliasMap($class, $renameMode, $renamedColumns); - - $this->addEntityResult($class, $alias); - $this->addAllClassFields($class, $alias, $columnAliasMap); - } - - /** - * Adds a joined entity and all of its fields to the result set. - * - * @param string $class The class name of the joined entity. - * @param string $alias The unique alias to use for the joined entity. - * @param string $parentAlias The alias of the entity result that is the parent of this joined result. - * @param string $relation The association field that connects the parent entity result - * with the joined entity result. - * @param string[] $renamedColumns Columns that have been renamed (tableColumnName => queryColumnName). - * @psalm-param class-string $class - * @psalm-param array $renamedColumns - * @psalm-param self::COLUMN_RENAMING_*|null $renameMode - */ - public function addJoinedEntityFromClassMetadata( - string $class, - string $alias, - string $parentAlias, - string $relation, - array $renamedColumns = [], - int|null $renameMode = null, - ): void { - $renameMode = $renameMode ?: $this->defaultRenameMode; - $columnAliasMap = $this->getColumnAliasMap($class, $renameMode, $renamedColumns); - - $this->addJoinedEntityResult($class, $alias, $parentAlias, $relation); - $this->addAllClassFields($class, $alias, $columnAliasMap); - } - - /** - * Adds all fields of the given class to the result set mapping (columns and meta fields). - * - * @param string[] $columnAliasMap - * @psalm-param array $columnAliasMap - * - * @throws InvalidArgumentException - */ - protected function addAllClassFields(string $class, string $alias, array $columnAliasMap = []): void - { - $classMetadata = $this->em->getClassMetadata($class); - $platform = $this->em->getConnection()->getDatabasePlatform(); - - if (! $this->isInheritanceSupported($classMetadata)) { - throw new InvalidArgumentException('ResultSetMapping builder does not currently support your inheritance scheme.'); - } - - foreach ($classMetadata->getColumnNames() as $columnName) { - $propertyName = $classMetadata->getFieldName($columnName); - $columnAlias = $this->getSQLResultCasing($platform, $columnAliasMap[$columnName]); - - if (isset($this->fieldMappings[$columnAlias])) { - throw new InvalidArgumentException(sprintf( - "The column '%s' conflicts with another column in the mapper.", - $columnName, - )); - } - - $this->addFieldResult($alias, $columnAlias, $propertyName); - - $enumType = $classMetadata->getFieldMapping($propertyName)->enumType ?? null; - if (! empty($enumType)) { - $this->addEnumResult($columnAlias, $enumType); - } - } - - foreach ($classMetadata->associationMappings as $associationMapping) { - if ($associationMapping->isToOneOwningSide()) { - $targetClass = $this->em->getClassMetadata($associationMapping->targetEntity); - $isIdentifier = isset($associationMapping->id) && $associationMapping->id === true; - - foreach ($associationMapping->joinColumns as $joinColumn) { - $columnName = $joinColumn->name; - $columnAlias = $this->getSQLResultCasing($platform, $columnAliasMap[$columnName]); - $columnType = PersisterHelper::getTypeOfColumn($joinColumn->referencedColumnName, $targetClass, $this->em); - - if (isset($this->metaMappings[$columnAlias])) { - throw new InvalidArgumentException(sprintf( - "The column '%s' conflicts with another column in the mapper.", - $columnAlias, - )); - } - - $this->addMetaResult($alias, $columnAlias, $columnName, $isIdentifier, $columnType); - } - } - } - } - - private function isInheritanceSupported(ClassMetadata $classMetadata): bool - { - if ( - $classMetadata->isInheritanceTypeSingleTable() - && in_array($classMetadata->name, $classMetadata->discriminatorMap, true) - ) { - return true; - } - - return ! ($classMetadata->isInheritanceTypeSingleTable() || $classMetadata->isInheritanceTypeJoined()); - } - - /** - * Gets column alias for a given column. - * - * @psalm-param array $customRenameColumns - * - * @psalm-assert self::COLUMN_RENAMING_* $mode - */ - private function getColumnAlias(string $columnName, int $mode, array $customRenameColumns): string - { - return match ($mode) { - self::COLUMN_RENAMING_INCREMENT => $columnName . $this->sqlCounter++, - self::COLUMN_RENAMING_CUSTOM => $customRenameColumns[$columnName] ?? $columnName, - self::COLUMN_RENAMING_NONE => $columnName, - default => throw new InvalidArgumentException(sprintf('%d is not a valid value for $mode', $mode)), - }; - } - - /** - * Retrieves a class columns and join columns aliases that are used in the SELECT clause. - * - * This depends on the renaming mode selected by the user. - * - * @psalm-param class-string $className - * @psalm-param self::COLUMN_RENAMING_* $mode - * @psalm-param array $customRenameColumns - * - * @return string[] - * @psalm-return array - */ - private function getColumnAliasMap( - string $className, - int $mode, - array $customRenameColumns, - ): array { - if ($customRenameColumns) { // for BC with 2.2-2.3 API - $mode = self::COLUMN_RENAMING_CUSTOM; - } - - $columnAlias = []; - $class = $this->em->getClassMetadata($className); - - foreach ($class->getColumnNames() as $columnName) { - $columnAlias[$columnName] = $this->getColumnAlias($columnName, $mode, $customRenameColumns); - } - - foreach ($class->associationMappings as $associationMapping) { - if ($associationMapping->isToOneOwningSide()) { - foreach ($associationMapping->joinColumns as $joinColumn) { - $columnName = $joinColumn->name; - $columnAlias[$columnName] = $this->getColumnAlias($columnName, $mode, $customRenameColumns); - } - } - } - - return $columnAlias; - } - - /** - * Generates the Select clause from this ResultSetMappingBuilder. - * - * Works only for all the entity results. The select parts for scalar - * expressions have to be written manually. - * - * @param string[] $tableAliases - * @psalm-param array $tableAliases - */ - public function generateSelectClause(array $tableAliases = []): string - { - $sql = ''; - - foreach ($this->columnOwnerMap as $columnName => $dqlAlias) { - $tableAlias = $tableAliases[$dqlAlias] ?? $dqlAlias; - - if ($sql !== '') { - $sql .= ', '; - } - - if (isset($this->fieldMappings[$columnName])) { - $class = $this->em->getClassMetadata($this->declaringClasses[$columnName]); - $fieldName = $this->fieldMappings[$columnName]; - $classFieldMapping = $class->fieldMappings[$fieldName]; - $columnSql = $tableAlias . '.' . $classFieldMapping->columnName; - - $type = Type::getType($classFieldMapping->type); - $columnSql = $type->convertToPHPValueSQL($columnSql, $this->em->getConnection()->getDatabasePlatform()); - - $sql .= $columnSql; - } elseif (isset($this->metaMappings[$columnName])) { - $sql .= $tableAlias . '.' . $this->metaMappings[$columnName]; - } elseif (isset($this->discriminatorColumns[$dqlAlias])) { - $sql .= $tableAlias . '.' . $this->discriminatorColumns[$dqlAlias]; - } - - $sql .= ' AS ' . $columnName; - } - - return $sql; - } - - public function __toString(): string - { - return $this->generateSelectClause([]); - } -} diff --git a/vendor/doctrine/orm/src/Query/SqlWalker.php b/vendor/doctrine/orm/src/Query/SqlWalker.php deleted file mode 100644 index c6f98c1..0000000 --- a/vendor/doctrine/orm/src/Query/SqlWalker.php +++ /dev/null @@ -1,2264 +0,0 @@ -> - */ - private array $scalarResultAliasMap = []; - - /** - * Map from Table-Alias + Column-Name to OrderBy-Direction. - * - * @var array - */ - private array $orderedColumnsMap = []; - - /** - * Map from DQL-Alias + Field-Name to SQL Column Alias. - * - * @var array> - */ - private array $scalarFields = []; - - /** - * A list of classes that appear in non-scalar SelectExpressions. - * - * @psalm-var array - */ - private array $selectedClasses = []; - - /** - * The DQL alias of the root class of the currently traversed query. - * - * @psalm-var list - */ - private array $rootAliases = []; - - /** - * Flag that indicates whether to generate SQL table aliases in the SQL. - * These should only be generated for SELECT queries, not for UPDATE/DELETE. - */ - private bool $useSqlTableAliases = true; - - /** - * The database platform abstraction. - */ - private readonly AbstractPlatform $platform; - - /** - * The quote strategy. - */ - private readonly QuoteStrategy $quoteStrategy; - - /** @psalm-param array $queryComponents The query components (symbol table). */ - public function __construct( - private readonly Query $query, - private readonly ParserResult $parserResult, - private array $queryComponents, - ) { - $this->rsm = $parserResult->getResultSetMapping(); - $this->em = $query->getEntityManager(); - $this->conn = $this->em->getConnection(); - $this->platform = $this->conn->getDatabasePlatform(); - $this->quoteStrategy = $this->em->getConfiguration()->getQuoteStrategy(); - } - - /** - * Gets the Query instance used by the walker. - */ - public function getQuery(): Query - { - return $this->query; - } - - /** - * Gets the Connection used by the walker. - */ - public function getConnection(): Connection - { - return $this->conn; - } - - /** - * Gets the EntityManager used by the walker. - */ - public function getEntityManager(): EntityManagerInterface - { - return $this->em; - } - - /** - * Gets the information about a single query component. - * - * @param string $dqlAlias The DQL alias. - * - * @return mixed[] - * @psalm-return QueryComponent - */ - public function getQueryComponent(string $dqlAlias): array - { - return $this->queryComponents[$dqlAlias]; - } - - public function getMetadataForDqlAlias(string $dqlAlias): ClassMetadata - { - return $this->queryComponents[$dqlAlias]['metadata'] - ?? throw new LogicException(sprintf('No metadata for DQL alias: %s', $dqlAlias)); - } - - /** - * Returns internal queryComponents array. - * - * @return array - */ - public function getQueryComponents(): array - { - return $this->queryComponents; - } - - /** - * Sets or overrides a query component for a given dql alias. - * - * @psalm-param QueryComponent $queryComponent - */ - public function setQueryComponent(string $dqlAlias, array $queryComponent): void - { - $requiredKeys = ['metadata', 'parent', 'relation', 'map', 'nestingLevel', 'token']; - - if (array_diff($requiredKeys, array_keys($queryComponent))) { - throw QueryException::invalidQueryComponent($dqlAlias); - } - - $this->queryComponents[$dqlAlias] = $queryComponent; - } - - /** - * Gets an executor that can be used to execute the result of this walker. - */ - public function getExecutor(AST\SelectStatement|AST\UpdateStatement|AST\DeleteStatement $statement): Exec\AbstractSqlExecutor - { - return match (true) { - $statement instanceof AST\SelectStatement - => new Exec\SingleSelectExecutor($statement, $this), - $statement instanceof AST\UpdateStatement - => $this->em->getClassMetadata($statement->updateClause->abstractSchemaName)->isInheritanceTypeJoined() - ? new Exec\MultiTableUpdateExecutor($statement, $this) - : new Exec\SingleTableDeleteUpdateExecutor($statement, $this), - $statement instanceof AST\DeleteStatement - => $this->em->getClassMetadata($statement->deleteClause->abstractSchemaName)->isInheritanceTypeJoined() - ? new Exec\MultiTableDeleteExecutor($statement, $this) - : new Exec\SingleTableDeleteUpdateExecutor($statement, $this), - }; - } - - /** - * Generates a unique, short SQL table alias. - */ - public function getSQLTableAlias(string $tableName, string $dqlAlias = ''): string - { - $tableName .= $dqlAlias ? '@[' . $dqlAlias . ']' : ''; - - if (! isset($this->tableAliasMap[$tableName])) { - $this->tableAliasMap[$tableName] = (preg_match('/[a-z]/i', $tableName[0]) ? strtolower($tableName[0]) : 't') - . $this->tableAliasCounter++ . '_'; - } - - return $this->tableAliasMap[$tableName]; - } - - /** - * Forces the SqlWalker to use a specific alias for a table name, rather than - * generating an alias on its own. - */ - public function setSQLTableAlias(string $tableName, string $alias, string $dqlAlias = ''): string - { - $tableName .= $dqlAlias ? '@[' . $dqlAlias . ']' : ''; - - $this->tableAliasMap[$tableName] = $alias; - - return $alias; - } - - /** - * Gets an SQL column alias for a column name. - */ - public function getSQLColumnAlias(string $columnName): string - { - return $this->quoteStrategy->getColumnAlias($columnName, $this->aliasCounter++, $this->platform); - } - - /** - * Generates the SQL JOINs that are necessary for Class Table Inheritance - * for the given class. - */ - private function generateClassTableInheritanceJoins( - ClassMetadata $class, - string $dqlAlias, - ): string { - $sql = ''; - - $baseTableAlias = $this->getSQLTableAlias($class->getTableName(), $dqlAlias); - - // INNER JOIN parent class tables - foreach ($class->parentClasses as $parentClassName) { - $parentClass = $this->em->getClassMetadata($parentClassName); - $tableAlias = $this->getSQLTableAlias($parentClass->getTableName(), $dqlAlias); - - // If this is a joined association we must use left joins to preserve the correct result. - $sql .= isset($this->queryComponents[$dqlAlias]['relation']) ? ' LEFT ' : ' INNER '; - $sql .= 'JOIN ' . $this->quoteStrategy->getTableName($parentClass, $this->platform) . ' ' . $tableAlias . ' ON '; - - $sqlParts = []; - - foreach ($this->quoteStrategy->getIdentifierColumnNames($class, $this->platform) as $columnName) { - $sqlParts[] = $baseTableAlias . '.' . $columnName . ' = ' . $tableAlias . '.' . $columnName; - } - - // Add filters on the root class - $sqlParts[] = $this->generateFilterConditionSQL($parentClass, $tableAlias); - - $sql .= implode(' AND ', array_filter($sqlParts)); - } - - // LEFT JOIN child class tables - foreach ($class->subClasses as $subClassName) { - $subClass = $this->em->getClassMetadata($subClassName); - $tableAlias = $this->getSQLTableAlias($subClass->getTableName(), $dqlAlias); - - $sql .= ' LEFT JOIN ' . $this->quoteStrategy->getTableName($subClass, $this->platform) . ' ' . $tableAlias . ' ON '; - - $sqlParts = []; - - foreach ($this->quoteStrategy->getIdentifierColumnNames($subClass, $this->platform) as $columnName) { - $sqlParts[] = $baseTableAlias . '.' . $columnName . ' = ' . $tableAlias . '.' . $columnName; - } - - $sql .= implode(' AND ', $sqlParts); - } - - return $sql; - } - - private function generateOrderedCollectionOrderByItems(): string - { - $orderedColumns = []; - - foreach ($this->selectedClasses as $selectedClass) { - $dqlAlias = $selectedClass['dqlAlias']; - $qComp = $this->queryComponents[$dqlAlias]; - - if (! isset($qComp['relation']->orderBy)) { - continue; - } - - assert(isset($qComp['metadata'])); - $persister = $this->em->getUnitOfWork()->getEntityPersister($qComp['metadata']->name); - - foreach ($qComp['relation']->orderBy as $fieldName => $orientation) { - $columnName = $this->quoteStrategy->getColumnName($fieldName, $qComp['metadata'], $this->platform); - $tableName = $qComp['metadata']->isInheritanceTypeJoined() - ? $persister->getOwningTable($fieldName) - : $qComp['metadata']->getTableName(); - - $orderedColumn = $this->getSQLTableAlias($tableName, $dqlAlias) . '.' . $columnName; - - // OrderByClause should replace an ordered relation. see - DDC-2475 - if (isset($this->orderedColumnsMap[$orderedColumn])) { - continue; - } - - $this->orderedColumnsMap[$orderedColumn] = $orientation; - $orderedColumns[] = $orderedColumn . ' ' . $orientation; - } - } - - return implode(', ', $orderedColumns); - } - - /** - * Generates a discriminator column SQL condition for the class with the given DQL alias. - * - * @psalm-param list $dqlAliases List of root DQL aliases to inspect for discriminator restrictions. - */ - private function generateDiscriminatorColumnConditionSQL(array $dqlAliases): string - { - $sqlParts = []; - - foreach ($dqlAliases as $dqlAlias) { - $class = $this->getMetadataForDqlAlias($dqlAlias); - - if (! $class->isInheritanceTypeSingleTable()) { - continue; - } - - $sqlTableAlias = $this->useSqlTableAliases - ? $this->getSQLTableAlias($class->getTableName(), $dqlAlias) . '.' - : ''; - - $conn = $this->em->getConnection(); - $values = []; - - if ($class->discriminatorValue !== null) { // discriminators can be 0 - $values[] = $class->getDiscriminatorColumn()->type === 'integer' && is_int($class->discriminatorValue) - ? $class->discriminatorValue - : $conn->quote((string) $class->discriminatorValue); - } - - foreach ($class->subClasses as $subclassName) { - $subclassMetadata = $this->em->getClassMetadata($subclassName); - - // Abstract entity classes show up in the list of subClasses, but may be omitted - // from the discriminator map. In that case, they have a null discriminator value. - if ($subclassMetadata->discriminatorValue === null) { - continue; - } - - $values[] = $subclassMetadata->getDiscriminatorColumn()->type === 'integer' && is_int($subclassMetadata->discriminatorValue) - ? $subclassMetadata->discriminatorValue - : $conn->quote((string) $subclassMetadata->discriminatorValue); - } - - if ($values !== []) { - $sqlParts[] = $sqlTableAlias . $class->getDiscriminatorColumn()->name . ' IN (' . implode(', ', $values) . ')'; - } else { - $sqlParts[] = '1=0'; // impossible condition - } - } - - $sql = implode(' AND ', $sqlParts); - - return count($sqlParts) > 1 ? '(' . $sql . ')' : $sql; - } - - /** - * Generates the filter SQL for a given entity and table alias. - */ - private function generateFilterConditionSQL( - ClassMetadata $targetEntity, - string $targetTableAlias, - ): string { - if (! $this->em->hasFilters()) { - return ''; - } - - switch ($targetEntity->inheritanceType) { - case ClassMetadata::INHERITANCE_TYPE_NONE: - break; - case ClassMetadata::INHERITANCE_TYPE_JOINED: - // The classes in the inheritance will be added to the query one by one, - // but only the root node is getting filtered - if ($targetEntity->name !== $targetEntity->rootEntityName) { - return ''; - } - - break; - case ClassMetadata::INHERITANCE_TYPE_SINGLE_TABLE: - // With STI the table will only be queried once, make sure that the filters - // are added to the root entity - $targetEntity = $this->em->getClassMetadata($targetEntity->rootEntityName); - break; - default: - //@todo: throw exception? - return ''; - } - - $filterClauses = []; - foreach ($this->em->getFilters()->getEnabledFilters() as $filter) { - $filterExpr = $filter->addFilterConstraint($targetEntity, $targetTableAlias); - if ($filterExpr !== '') { - $filterClauses[] = '(' . $filterExpr . ')'; - } - } - - return implode(' AND ', $filterClauses); - } - - /** - * Walks down a SelectStatement AST node, thereby generating the appropriate SQL. - */ - public function walkSelectStatement(AST\SelectStatement $selectStatement): string - { - $limit = $this->query->getMaxResults(); - $offset = $this->query->getFirstResult(); - $lockMode = $this->query->getHint(Query::HINT_LOCK_MODE) ?: LockMode::NONE; - $sql = $this->walkSelectClause($selectStatement->selectClause) - . $this->walkFromClause($selectStatement->fromClause) - . $this->walkWhereClause($selectStatement->whereClause); - - if ($selectStatement->groupByClause) { - $sql .= $this->walkGroupByClause($selectStatement->groupByClause); - } - - if ($selectStatement->havingClause) { - $sql .= $this->walkHavingClause($selectStatement->havingClause); - } - - if ($selectStatement->orderByClause) { - $sql .= $this->walkOrderByClause($selectStatement->orderByClause); - } - - $orderBySql = $this->generateOrderedCollectionOrderByItems(); - if (! $selectStatement->orderByClause && $orderBySql) { - $sql .= ' ORDER BY ' . $orderBySql; - } - - $sql = $this->platform->modifyLimitQuery($sql, $limit, $offset); - - if ($lockMode === LockMode::NONE) { - return $sql; - } - - if ($lockMode === LockMode::PESSIMISTIC_READ) { - return $sql . ' ' . $this->getReadLockSQL($this->platform); - } - - if ($lockMode === LockMode::PESSIMISTIC_WRITE) { - return $sql . ' ' . $this->getWriteLockSQL($this->platform); - } - - if ($lockMode !== LockMode::OPTIMISTIC) { - throw QueryException::invalidLockMode(); - } - - foreach ($this->selectedClasses as $selectedClass) { - if (! $selectedClass['class']->isVersioned) { - throw OptimisticLockException::lockFailed($selectedClass['class']->name); - } - } - - return $sql; - } - - /** - * Walks down a UpdateStatement AST node, thereby generating the appropriate SQL. - */ - public function walkUpdateStatement(AST\UpdateStatement $updateStatement): string - { - $this->useSqlTableAliases = false; - $this->rsm->isSelect = false; - - return $this->walkUpdateClause($updateStatement->updateClause) - . $this->walkWhereClause($updateStatement->whereClause); - } - - /** - * Walks down a DeleteStatement AST node, thereby generating the appropriate SQL. - */ - public function walkDeleteStatement(AST\DeleteStatement $deleteStatement): string - { - $this->useSqlTableAliases = false; - $this->rsm->isSelect = false; - - return $this->walkDeleteClause($deleteStatement->deleteClause) - . $this->walkWhereClause($deleteStatement->whereClause); - } - - /** - * Walks down an IdentificationVariable AST node, thereby generating the appropriate SQL. - * This one differs of ->walkIdentificationVariable() because it generates the entity identifiers. - */ - public function walkEntityIdentificationVariable(string $identVariable): string - { - $class = $this->getMetadataForDqlAlias($identVariable); - $tableAlias = $this->getSQLTableAlias($class->getTableName(), $identVariable); - $sqlParts = []; - - foreach ($this->quoteStrategy->getIdentifierColumnNames($class, $this->platform) as $columnName) { - $sqlParts[] = $tableAlias . '.' . $columnName; - } - - return implode(', ', $sqlParts); - } - - /** - * Walks down an IdentificationVariable (no AST node associated), thereby generating the SQL. - */ - public function walkIdentificationVariable(string $identificationVariable, string|null $fieldName = null): string - { - $class = $this->getMetadataForDqlAlias($identificationVariable); - - if ( - $fieldName !== null && $class->isInheritanceTypeJoined() && - isset($class->fieldMappings[$fieldName]->inherited) - ) { - $class = $this->em->getClassMetadata($class->fieldMappings[$fieldName]->inherited); - } - - return $this->getSQLTableAlias($class->getTableName(), $identificationVariable); - } - - /** - * Walks down a PathExpression AST node, thereby generating the appropriate SQL. - */ - public function walkPathExpression(AST\PathExpression $pathExpr): string - { - $sql = ''; - assert($pathExpr->field !== null); - - switch ($pathExpr->type) { - case AST\PathExpression::TYPE_STATE_FIELD: - $fieldName = $pathExpr->field; - $dqlAlias = $pathExpr->identificationVariable; - $class = $this->getMetadataForDqlAlias($dqlAlias); - - if ($this->useSqlTableAliases) { - $sql .= $this->walkIdentificationVariable($dqlAlias, $fieldName) . '.'; - } - - $sql .= $this->quoteStrategy->getColumnName($fieldName, $class, $this->platform); - break; - - case AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION: - // 1- the owning side: - // Just use the foreign key, i.e. u.group_id - $fieldName = $pathExpr->field; - $dqlAlias = $pathExpr->identificationVariable; - $class = $this->getMetadataForDqlAlias($dqlAlias); - - if (isset($class->associationMappings[$fieldName]->inherited)) { - $class = $this->em->getClassMetadata($class->associationMappings[$fieldName]->inherited); - } - - $assoc = $class->associationMappings[$fieldName]; - - if (! $assoc->isOwningSide()) { - throw QueryException::associationPathInverseSideNotSupported($pathExpr); - } - - assert($assoc->isToOneOwningSide()); - - // COMPOSITE KEYS NOT (YET?) SUPPORTED - if (count($assoc->sourceToTargetKeyColumns) > 1) { - throw QueryException::associationPathCompositeKeyNotSupported(); - } - - if ($this->useSqlTableAliases) { - $sql .= $this->getSQLTableAlias($class->getTableName(), $dqlAlias) . '.'; - } - - $sql .= reset($assoc->targetToSourceKeyColumns); - break; - - default: - throw QueryException::invalidPathExpression($pathExpr); - } - - return $sql; - } - - /** - * Walks down a SelectClause AST node, thereby generating the appropriate SQL. - */ - public function walkSelectClause(AST\SelectClause $selectClause): string - { - $sql = 'SELECT ' . ($selectClause->isDistinct ? 'DISTINCT ' : ''); - $sqlSelectExpressions = array_filter(array_map($this->walkSelectExpression(...), $selectClause->selectExpressions)); - - if ($this->query->getHint(Query::HINT_INTERNAL_ITERATION) === true && $selectClause->isDistinct) { - $this->query->setHint(self::HINT_DISTINCT, true); - } - - $addMetaColumns = $this->query->getHydrationMode() === Query::HYDRATE_OBJECT - || $this->query->getHint(Query::HINT_INCLUDE_META_COLUMNS); - - foreach ($this->selectedClasses as $selectedClass) { - $class = $selectedClass['class']; - $dqlAlias = $selectedClass['dqlAlias']; - $resultAlias = $selectedClass['resultAlias']; - - // Register as entity or joined entity result - if (! isset($this->queryComponents[$dqlAlias]['relation'])) { - $this->rsm->addEntityResult($class->name, $dqlAlias, $resultAlias); - } else { - assert(isset($this->queryComponents[$dqlAlias]['parent'])); - - $this->rsm->addJoinedEntityResult( - $class->name, - $dqlAlias, - $this->queryComponents[$dqlAlias]['parent'], - $this->queryComponents[$dqlAlias]['relation']->fieldName, - ); - } - - if ($class->isInheritanceTypeSingleTable() || $class->isInheritanceTypeJoined()) { - // Add discriminator columns to SQL - $rootClass = $this->em->getClassMetadata($class->rootEntityName); - $tblAlias = $this->getSQLTableAlias($rootClass->getTableName(), $dqlAlias); - $discrColumn = $rootClass->getDiscriminatorColumn(); - $columnAlias = $this->getSQLColumnAlias($discrColumn->name); - - $sqlSelectExpressions[] = $tblAlias . '.' . $discrColumn->name . ' AS ' . $columnAlias; - - $this->rsm->setDiscriminatorColumn($dqlAlias, $columnAlias); - $this->rsm->addMetaResult($dqlAlias, $columnAlias, $discrColumn->fieldName, false, $discrColumn->type); - if (! empty($discrColumn->enumType)) { - $this->rsm->addEnumResult($columnAlias, $discrColumn->enumType); - } - } - - // Add foreign key columns to SQL, if necessary - if (! $addMetaColumns && ! $class->containsForeignIdentifier) { - continue; - } - - // Add foreign key columns of class and also parent classes - foreach ($class->associationMappings as $assoc) { - if ( - ! $assoc->isToOneOwningSide() - || ( ! $addMetaColumns && ! isset($assoc->id)) - ) { - continue; - } - - $targetClass = $this->em->getClassMetadata($assoc->targetEntity); - $isIdentifier = (isset($assoc->id) && $assoc->id === true); - $owningClass = isset($assoc->inherited) ? $this->em->getClassMetadata($assoc->inherited) : $class; - $sqlTableAlias = $this->getSQLTableAlias($owningClass->getTableName(), $dqlAlias); - - foreach ($assoc->joinColumns as $joinColumn) { - $columnName = $joinColumn->name; - $columnAlias = $this->getSQLColumnAlias($columnName); - $columnType = PersisterHelper::getTypeOfColumn($joinColumn->referencedColumnName, $targetClass, $this->em); - - $quotedColumnName = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform); - $sqlSelectExpressions[] = $sqlTableAlias . '.' . $quotedColumnName . ' AS ' . $columnAlias; - - $this->rsm->addMetaResult($dqlAlias, $columnAlias, $columnName, $isIdentifier, $columnType); - } - } - - // Add foreign key columns to SQL, if necessary - if (! $addMetaColumns) { - continue; - } - - // Add foreign key columns of subclasses - foreach ($class->subClasses as $subClassName) { - $subClass = $this->em->getClassMetadata($subClassName); - $sqlTableAlias = $this->getSQLTableAlias($subClass->getTableName(), $dqlAlias); - - foreach ($subClass->associationMappings as $assoc) { - // Skip if association is inherited - if (isset($assoc->inherited)) { - continue; - } - - if ($assoc->isToOneOwningSide()) { - $targetClass = $this->em->getClassMetadata($assoc->targetEntity); - - foreach ($assoc->joinColumns as $joinColumn) { - $columnName = $joinColumn->name; - $columnAlias = $this->getSQLColumnAlias($columnName); - $columnType = PersisterHelper::getTypeOfColumn($joinColumn->referencedColumnName, $targetClass, $this->em); - - $quotedColumnName = $this->quoteStrategy->getJoinColumnName($joinColumn, $subClass, $this->platform); - $sqlSelectExpressions[] = $sqlTableAlias . '.' . $quotedColumnName . ' AS ' . $columnAlias; - - $this->rsm->addMetaResult($dqlAlias, $columnAlias, $columnName, $subClass->isIdentifier($columnName), $columnType); - } - } - } - } - } - - return $sql . implode(', ', $sqlSelectExpressions); - } - - /** - * Walks down a FromClause AST node, thereby generating the appropriate SQL. - */ - public function walkFromClause(AST\FromClause $fromClause): string - { - $identificationVarDecls = $fromClause->identificationVariableDeclarations; - $sqlParts = []; - - foreach ($identificationVarDecls as $identificationVariableDecl) { - $sqlParts[] = $this->walkIdentificationVariableDeclaration($identificationVariableDecl); - } - - return ' FROM ' . implode(', ', $sqlParts); - } - - /** - * Walks down a IdentificationVariableDeclaration AST node, thereby generating the appropriate SQL. - */ - public function walkIdentificationVariableDeclaration(AST\IdentificationVariableDeclaration $identificationVariableDecl): string - { - $sql = $this->walkRangeVariableDeclaration($identificationVariableDecl->rangeVariableDeclaration); - - if ($identificationVariableDecl->indexBy) { - $this->walkIndexBy($identificationVariableDecl->indexBy); - } - - foreach ($identificationVariableDecl->joins as $join) { - $sql .= $this->walkJoin($join); - } - - return $sql; - } - - /** - * Walks down a IndexBy AST node. - */ - public function walkIndexBy(AST\IndexBy $indexBy): void - { - $pathExpression = $indexBy->singleValuedPathExpression; - $alias = $pathExpression->identificationVariable; - assert($pathExpression->field !== null); - - switch ($pathExpression->type) { - case AST\PathExpression::TYPE_STATE_FIELD: - $field = $pathExpression->field; - break; - - case AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION: - // Just use the foreign key, i.e. u.group_id - $fieldName = $pathExpression->field; - $class = $this->getMetadataForDqlAlias($alias); - - if (isset($class->associationMappings[$fieldName]->inherited)) { - $class = $this->em->getClassMetadata($class->associationMappings[$fieldName]->inherited); - } - - $association = $class->associationMappings[$fieldName]; - - if (! $association->isOwningSide()) { - throw QueryException::associationPathInverseSideNotSupported($pathExpression); - } - - assert($association->isToOneOwningSide()); - - if (count($association->sourceToTargetKeyColumns) > 1) { - throw QueryException::associationPathCompositeKeyNotSupported(); - } - - $field = reset($association->targetToSourceKeyColumns); - break; - - default: - throw QueryException::invalidPathExpression($pathExpression); - } - - if (isset($this->scalarFields[$alias][$field])) { - $this->rsm->addIndexByScalar($this->scalarFields[$alias][$field]); - - return; - } - - $this->rsm->addIndexBy($alias, $field); - } - - /** - * Walks down a RangeVariableDeclaration AST node, thereby generating the appropriate SQL. - */ - public function walkRangeVariableDeclaration(AST\RangeVariableDeclaration $rangeVariableDeclaration): string - { - return $this->generateRangeVariableDeclarationSQL($rangeVariableDeclaration, false); - } - - /** - * Generate appropriate SQL for RangeVariableDeclaration AST node - */ - private function generateRangeVariableDeclarationSQL( - AST\RangeVariableDeclaration $rangeVariableDeclaration, - bool $buildNestedJoins, - ): string { - $class = $this->em->getClassMetadata($rangeVariableDeclaration->abstractSchemaName); - $dqlAlias = $rangeVariableDeclaration->aliasIdentificationVariable; - - if ($rangeVariableDeclaration->isRoot) { - $this->rootAliases[] = $dqlAlias; - } - - $sql = $this->platform->appendLockHint( - $this->quoteStrategy->getTableName($class, $this->platform) . ' ' . - $this->getSQLTableAlias($class->getTableName(), $dqlAlias), - $this->query->getHint(Query::HINT_LOCK_MODE) ?: LockMode::NONE, - ); - - if (! $class->isInheritanceTypeJoined()) { - return $sql; - } - - $classTableInheritanceJoins = $this->generateClassTableInheritanceJoins($class, $dqlAlias); - - if (! $buildNestedJoins) { - return $sql . $classTableInheritanceJoins; - } - - return $classTableInheritanceJoins === '' ? $sql : '(' . $sql . $classTableInheritanceJoins . ')'; - } - - /** - * Walks down a JoinAssociationDeclaration AST node, thereby generating the appropriate SQL. - * - * @psalm-param AST\Join::JOIN_TYPE_* $joinType - * - * @throws QueryException - */ - public function walkJoinAssociationDeclaration( - AST\JoinAssociationDeclaration $joinAssociationDeclaration, - int $joinType = AST\Join::JOIN_TYPE_INNER, - AST\ConditionalExpression|AST\Phase2OptimizableConditional|null $condExpr = null, - ): string { - $sql = ''; - - $associationPathExpression = $joinAssociationDeclaration->joinAssociationPathExpression; - $joinedDqlAlias = $joinAssociationDeclaration->aliasIdentificationVariable; - $indexBy = $joinAssociationDeclaration->indexBy; - - $relation = $this->queryComponents[$joinedDqlAlias]['relation'] ?? null; - assert($relation !== null); - $targetClass = $this->em->getClassMetadata($relation->targetEntity); - $sourceClass = $this->em->getClassMetadata($relation->sourceEntity); - $targetTableName = $this->quoteStrategy->getTableName($targetClass, $this->platform); - - $targetTableAlias = $this->getSQLTableAlias($targetClass->getTableName(), $joinedDqlAlias); - $sourceTableAlias = $this->getSQLTableAlias($sourceClass->getTableName(), $associationPathExpression->identificationVariable); - - // Ensure we got the owning side, since it has all mapping info - $assoc = $this->em->getMetadataFactory()->getOwningSide($relation); - - if ($this->query->getHint(Query::HINT_INTERNAL_ITERATION) === true && (! $this->query->getHint(self::HINT_DISTINCT) || isset($this->selectedClasses[$joinedDqlAlias]))) { - if ($relation->isToMany()) { - throw QueryException::iterateWithFetchJoinNotAllowed($assoc); - } - } - - $fetchMode = $this->query->getHint('fetchMode')[$assoc->sourceEntity][$assoc->fieldName] ?? $relation->fetch; - - if ($fetchMode === ClassMetadata::FETCH_EAGER && $condExpr !== null) { - throw QueryException::eagerFetchJoinWithNotAllowed($assoc->sourceEntity, $assoc->fieldName); - } - - // This condition is not checking ClassMetadata::MANY_TO_ONE, because by definition it cannot - // be the owning side and previously we ensured that $assoc is always the owning side of the associations. - // The owning side is necessary at this point because only it contains the JoinColumn information. - switch (true) { - case $assoc->isToOne(): - assert($assoc->isToOneOwningSide()); - $conditions = []; - - foreach ($assoc->joinColumns as $joinColumn) { - $quotedSourceColumn = $this->quoteStrategy->getJoinColumnName($joinColumn, $targetClass, $this->platform); - $quotedTargetColumn = $this->quoteStrategy->getReferencedJoinColumnName($joinColumn, $targetClass, $this->platform); - - if ($relation->isOwningSide()) { - $conditions[] = $sourceTableAlias . '.' . $quotedSourceColumn . ' = ' . $targetTableAlias . '.' . $quotedTargetColumn; - - continue; - } - - $conditions[] = $sourceTableAlias . '.' . $quotedTargetColumn . ' = ' . $targetTableAlias . '.' . $quotedSourceColumn; - } - - // Apply remaining inheritance restrictions - $discrSql = $this->generateDiscriminatorColumnConditionSQL([$joinedDqlAlias]); - - if ($discrSql) { - $conditions[] = $discrSql; - } - - // Apply the filters - $filterExpr = $this->generateFilterConditionSQL($targetClass, $targetTableAlias); - - if ($filterExpr) { - $conditions[] = $filterExpr; - } - - $targetTableJoin = [ - 'table' => $targetTableName . ' ' . $targetTableAlias, - 'condition' => implode(' AND ', $conditions), - ]; - break; - - case $assoc->isManyToMany(): - // Join relation table - $joinTable = $assoc->joinTable; - $joinTableAlias = $this->getSQLTableAlias($joinTable->name, $joinedDqlAlias); - $joinTableName = $this->quoteStrategy->getJoinTableName($assoc, $sourceClass, $this->platform); - - $conditions = []; - $relationColumns = $relation->isOwningSide() - ? $assoc->joinTable->joinColumns - : $assoc->joinTable->inverseJoinColumns; - - foreach ($relationColumns as $joinColumn) { - $quotedSourceColumn = $this->quoteStrategy->getJoinColumnName($joinColumn, $targetClass, $this->platform); - $quotedTargetColumn = $this->quoteStrategy->getReferencedJoinColumnName($joinColumn, $targetClass, $this->platform); - - $conditions[] = $sourceTableAlias . '.' . $quotedTargetColumn . ' = ' . $joinTableAlias . '.' . $quotedSourceColumn; - } - - $sql .= $joinTableName . ' ' . $joinTableAlias . ' ON ' . implode(' AND ', $conditions); - - // Join target table - $sql .= $joinType === AST\Join::JOIN_TYPE_LEFT || $joinType === AST\Join::JOIN_TYPE_LEFTOUTER ? ' LEFT JOIN ' : ' INNER JOIN '; - - $conditions = []; - $relationColumns = $relation->isOwningSide() - ? $assoc->joinTable->inverseJoinColumns - : $assoc->joinTable->joinColumns; - - foreach ($relationColumns as $joinColumn) { - $quotedSourceColumn = $this->quoteStrategy->getJoinColumnName($joinColumn, $targetClass, $this->platform); - $quotedTargetColumn = $this->quoteStrategy->getReferencedJoinColumnName($joinColumn, $targetClass, $this->platform); - - $conditions[] = $targetTableAlias . '.' . $quotedTargetColumn . ' = ' . $joinTableAlias . '.' . $quotedSourceColumn; - } - - // Apply remaining inheritance restrictions - $discrSql = $this->generateDiscriminatorColumnConditionSQL([$joinedDqlAlias]); - - if ($discrSql) { - $conditions[] = $discrSql; - } - - // Apply the filters - $filterExpr = $this->generateFilterConditionSQL($targetClass, $targetTableAlias); - - if ($filterExpr) { - $conditions[] = $filterExpr; - } - - $targetTableJoin = [ - 'table' => $targetTableName . ' ' . $targetTableAlias, - 'condition' => implode(' AND ', $conditions), - ]; - break; - - default: - throw new BadMethodCallException('Type of association must be one of *_TO_ONE or MANY_TO_MANY'); - } - - // Handle WITH clause - $withCondition = $condExpr === null ? '' : ('(' . $this->walkConditionalExpression($condExpr) . ')'); - - if ($targetClass->isInheritanceTypeJoined()) { - $ctiJoins = $this->generateClassTableInheritanceJoins($targetClass, $joinedDqlAlias); - // If we have WITH condition, we need to build nested joins for target class table and cti joins - if ($withCondition && $ctiJoins) { - $sql .= '(' . $targetTableJoin['table'] . $ctiJoins . ') ON ' . $targetTableJoin['condition']; - } else { - $sql .= $targetTableJoin['table'] . ' ON ' . $targetTableJoin['condition'] . $ctiJoins; - } - } else { - $sql .= $targetTableJoin['table'] . ' ON ' . $targetTableJoin['condition']; - } - - if ($withCondition) { - $sql .= ' AND ' . $withCondition; - } - - // Apply the indexes - if ($indexBy) { - // For Many-To-One or One-To-One associations this obviously makes no sense, but is ignored silently. - $this->walkIndexBy($indexBy); - } elseif ($relation->isIndexed()) { - $this->rsm->addIndexBy($joinedDqlAlias, $relation->indexBy()); - } - - return $sql; - } - - /** - * Walks down a FunctionNode AST node, thereby generating the appropriate SQL. - */ - public function walkFunction(AST\Functions\FunctionNode $function): string - { - return $function->getSql($this); - } - - /** - * Walks down an OrderByClause AST node, thereby generating the appropriate SQL. - */ - public function walkOrderByClause(AST\OrderByClause $orderByClause): string - { - $orderByItems = array_map($this->walkOrderByItem(...), $orderByClause->orderByItems); - - $collectionOrderByItems = $this->generateOrderedCollectionOrderByItems(); - if ($collectionOrderByItems !== '') { - $orderByItems = array_merge($orderByItems, (array) $collectionOrderByItems); - } - - return ' ORDER BY ' . implode(', ', $orderByItems); - } - - /** - * Walks down an OrderByItem AST node, thereby generating the appropriate SQL. - */ - public function walkOrderByItem(AST\OrderByItem $orderByItem): string - { - $type = strtoupper($orderByItem->type); - $expr = $orderByItem->expression; - $sql = $expr instanceof AST\Node - ? $expr->dispatch($this) - : $this->walkResultVariable($this->queryComponents[$expr]['token']->value); - - $this->orderedColumnsMap[$sql] = $type; - - if ($expr instanceof AST\Subselect) { - return '(' . $sql . ') ' . $type; - } - - return $sql . ' ' . $type; - } - - /** - * Walks down a HavingClause AST node, thereby generating the appropriate SQL. - */ - public function walkHavingClause(AST\HavingClause $havingClause): string - { - return ' HAVING ' . $this->walkConditionalExpression($havingClause->conditionalExpression); - } - - /** - * Walks down a Join AST node and creates the corresponding SQL. - */ - public function walkJoin(AST\Join $join): string - { - $joinType = $join->joinType; - $joinDeclaration = $join->joinAssociationDeclaration; - - $sql = $joinType === AST\Join::JOIN_TYPE_LEFT || $joinType === AST\Join::JOIN_TYPE_LEFTOUTER - ? ' LEFT JOIN ' - : ' INNER JOIN '; - - switch (true) { - case $joinDeclaration instanceof AST\RangeVariableDeclaration: - $class = $this->em->getClassMetadata($joinDeclaration->abstractSchemaName); - $dqlAlias = $joinDeclaration->aliasIdentificationVariable; - $tableAlias = $this->getSQLTableAlias($class->table['name'], $dqlAlias); - $conditions = []; - - if ($join->conditionalExpression) { - $conditions[] = '(' . $this->walkConditionalExpression($join->conditionalExpression) . ')'; - } - - $isUnconditionalJoin = $conditions === []; - $condExprConjunction = $class->isInheritanceTypeJoined() && $joinType !== AST\Join::JOIN_TYPE_LEFT && $joinType !== AST\Join::JOIN_TYPE_LEFTOUTER && $isUnconditionalJoin - ? ' AND ' - : ' ON '; - - $sql .= $this->generateRangeVariableDeclarationSQL($joinDeclaration, ! $isUnconditionalJoin); - - // Apply remaining inheritance restrictions - $discrSql = $this->generateDiscriminatorColumnConditionSQL([$dqlAlias]); - - if ($discrSql) { - $conditions[] = $discrSql; - } - - // Apply the filters - $filterExpr = $this->generateFilterConditionSQL($class, $tableAlias); - - if ($filterExpr) { - $conditions[] = $filterExpr; - } - - if ($conditions) { - $sql .= $condExprConjunction . implode(' AND ', $conditions); - } - - break; - - case $joinDeclaration instanceof AST\JoinAssociationDeclaration: - $sql .= $this->walkJoinAssociationDeclaration($joinDeclaration, $joinType, $join->conditionalExpression); - break; - } - - return $sql; - } - - /** - * Walks down a CoalesceExpression AST node and generates the corresponding SQL. - */ - public function walkCoalesceExpression(AST\CoalesceExpression $coalesceExpression): string - { - $sql = 'COALESCE('; - - $scalarExpressions = []; - - foreach ($coalesceExpression->scalarExpressions as $scalarExpression) { - $scalarExpressions[] = $this->walkSimpleArithmeticExpression($scalarExpression); - } - - return $sql . implode(', ', $scalarExpressions) . ')'; - } - - /** - * Walks down a NullIfExpression AST node and generates the corresponding SQL. - */ - public function walkNullIfExpression(AST\NullIfExpression $nullIfExpression): string - { - $firstExpression = is_string($nullIfExpression->firstExpression) - ? $this->conn->quote($nullIfExpression->firstExpression) - : $this->walkSimpleArithmeticExpression($nullIfExpression->firstExpression); - - $secondExpression = is_string($nullIfExpression->secondExpression) - ? $this->conn->quote($nullIfExpression->secondExpression) - : $this->walkSimpleArithmeticExpression($nullIfExpression->secondExpression); - - return 'NULLIF(' . $firstExpression . ', ' . $secondExpression . ')'; - } - - /** - * Walks down a GeneralCaseExpression AST node and generates the corresponding SQL. - */ - public function walkGeneralCaseExpression(AST\GeneralCaseExpression $generalCaseExpression): string - { - $sql = 'CASE'; - - foreach ($generalCaseExpression->whenClauses as $whenClause) { - $sql .= ' WHEN ' . $this->walkConditionalExpression($whenClause->caseConditionExpression); - $sql .= ' THEN ' . $this->walkSimpleArithmeticExpression($whenClause->thenScalarExpression); - } - - $sql .= ' ELSE ' . $this->walkSimpleArithmeticExpression($generalCaseExpression->elseScalarExpression) . ' END'; - - return $sql; - } - - /** - * Walks down a SimpleCaseExpression AST node and generates the corresponding SQL. - */ - public function walkSimpleCaseExpression(AST\SimpleCaseExpression $simpleCaseExpression): string - { - $sql = 'CASE ' . $this->walkStateFieldPathExpression($simpleCaseExpression->caseOperand); - - foreach ($simpleCaseExpression->simpleWhenClauses as $simpleWhenClause) { - $sql .= ' WHEN ' . $this->walkSimpleArithmeticExpression($simpleWhenClause->caseScalarExpression); - $sql .= ' THEN ' . $this->walkSimpleArithmeticExpression($simpleWhenClause->thenScalarExpression); - } - - $sql .= ' ELSE ' . $this->walkSimpleArithmeticExpression($simpleCaseExpression->elseScalarExpression) . ' END'; - - return $sql; - } - - /** - * Walks down a SelectExpression AST node and generates the corresponding SQL. - */ - public function walkSelectExpression(AST\SelectExpression $selectExpression): string - { - $sql = ''; - $expr = $selectExpression->expression; - $hidden = $selectExpression->hiddenAliasResultVariable; - - switch (true) { - case $expr instanceof AST\PathExpression: - if ($expr->type !== AST\PathExpression::TYPE_STATE_FIELD) { - throw QueryException::invalidPathExpression($expr); - } - - assert($expr->field !== null); - $fieldName = $expr->field; - $dqlAlias = $expr->identificationVariable; - $class = $this->getMetadataForDqlAlias($dqlAlias); - - $resultAlias = $selectExpression->fieldIdentificationVariable ?: $fieldName; - $tableName = $class->isInheritanceTypeJoined() - ? $this->em->getUnitOfWork()->getEntityPersister($class->name)->getOwningTable($fieldName) - : $class->getTableName(); - - $sqlTableAlias = $this->getSQLTableAlias($tableName, $dqlAlias); - $fieldMapping = $class->fieldMappings[$fieldName]; - $columnName = $this->quoteStrategy->getColumnName($fieldName, $class, $this->platform); - $columnAlias = $this->getSQLColumnAlias($fieldMapping->columnName); - $col = $sqlTableAlias . '.' . $columnName; - - $type = Type::getType($fieldMapping->type); - $col = $type->convertToPHPValueSQL($col, $this->conn->getDatabasePlatform()); - - $sql .= $col . ' AS ' . $columnAlias; - - $this->scalarResultAliasMap[$resultAlias] = $columnAlias; - - if (! $hidden) { - $this->rsm->addScalarResult($columnAlias, $resultAlias, $fieldMapping->type); - $this->scalarFields[$dqlAlias][$fieldName] = $columnAlias; - - if (! empty($fieldMapping->enumType)) { - $this->rsm->addEnumResult($columnAlias, $fieldMapping->enumType); - } - } - - break; - - case $expr instanceof AST\AggregateExpression: - case $expr instanceof AST\Functions\FunctionNode: - case $expr instanceof AST\SimpleArithmeticExpression: - case $expr instanceof AST\ArithmeticTerm: - case $expr instanceof AST\ArithmeticFactor: - case $expr instanceof AST\ParenthesisExpression: - case $expr instanceof AST\Literal: - case $expr instanceof AST\NullIfExpression: - case $expr instanceof AST\CoalesceExpression: - case $expr instanceof AST\GeneralCaseExpression: - case $expr instanceof AST\SimpleCaseExpression: - $columnAlias = $this->getSQLColumnAlias('sclr'); - $resultAlias = $selectExpression->fieldIdentificationVariable ?: $this->scalarResultCounter++; - - $sql .= $expr->dispatch($this) . ' AS ' . $columnAlias; - - $this->scalarResultAliasMap[$resultAlias] = $columnAlias; - - if ($hidden) { - break; - } - - if (! $expr instanceof Query\AST\TypedExpression) { - // Conceptually we could resolve field type here by traverse through AST to retrieve field type, - // but this is not a feasible solution; assume 'string'. - $this->rsm->addScalarResult($columnAlias, $resultAlias, 'string'); - - break; - } - - $this->rsm->addScalarResult($columnAlias, $resultAlias, Type::getTypeRegistry()->lookupName($expr->getReturnType())); - - break; - - case $expr instanceof AST\Subselect: - $columnAlias = $this->getSQLColumnAlias('sclr'); - $resultAlias = $selectExpression->fieldIdentificationVariable ?: $this->scalarResultCounter++; - - $sql .= '(' . $this->walkSubselect($expr) . ') AS ' . $columnAlias; - - $this->scalarResultAliasMap[$resultAlias] = $columnAlias; - - if (! $hidden) { - // We cannot resolve field type here; assume 'string'. - $this->rsm->addScalarResult($columnAlias, $resultAlias, 'string'); - } - - break; - - case $expr instanceof AST\NewObjectExpression: - $sql .= $this->walkNewObject($expr, $selectExpression->fieldIdentificationVariable); - break; - - default: - $dqlAlias = $expr; - $class = $this->getMetadataForDqlAlias($dqlAlias); - $resultAlias = $selectExpression->fieldIdentificationVariable ?: null; - - if (! isset($this->selectedClasses[$dqlAlias])) { - $this->selectedClasses[$dqlAlias] = [ - 'class' => $class, - 'dqlAlias' => $dqlAlias, - 'resultAlias' => $resultAlias, - ]; - } - - $sqlParts = []; - - // Select all fields from the queried class - foreach ($class->fieldMappings as $fieldName => $mapping) { - $tableName = isset($mapping->inherited) - ? $this->em->getClassMetadata($mapping->inherited)->getTableName() - : $class->getTableName(); - - $sqlTableAlias = $this->getSQLTableAlias($tableName, $dqlAlias); - $columnAlias = $this->getSQLColumnAlias($mapping->columnName); - $quotedColumnName = $this->quoteStrategy->getColumnName($fieldName, $class, $this->platform); - - $col = $sqlTableAlias . '.' . $quotedColumnName; - - $type = Type::getType($mapping->type); - $col = $type->convertToPHPValueSQL($col, $this->platform); - - $sqlParts[] = $col . ' AS ' . $columnAlias; - - $this->scalarResultAliasMap[$resultAlias][] = $columnAlias; - - $this->rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName, $class->name); - - if (! empty($mapping->enumType)) { - $this->rsm->addEnumResult($columnAlias, $mapping->enumType); - } - } - - // Add any additional fields of subclasses (excluding inherited fields) - // 1) on Single Table Inheritance: always, since its marginal overhead - // 2) on Class Table Inheritance - foreach ($class->subClasses as $subClassName) { - $subClass = $this->em->getClassMetadata($subClassName); - $sqlTableAlias = $this->getSQLTableAlias($subClass->getTableName(), $dqlAlias); - - foreach ($subClass->fieldMappings as $fieldName => $mapping) { - if (isset($mapping->inherited)) { - continue; - } - - $columnAlias = $this->getSQLColumnAlias($mapping->columnName); - $quotedColumnName = $this->quoteStrategy->getColumnName($fieldName, $subClass, $this->platform); - - $col = $sqlTableAlias . '.' . $quotedColumnName; - - $type = Type::getType($mapping->type); - $col = $type->convertToPHPValueSQL($col, $this->platform); - - $sqlParts[] = $col . ' AS ' . $columnAlias; - - $this->scalarResultAliasMap[$resultAlias][] = $columnAlias; - - $this->rsm->addFieldResult($dqlAlias, $columnAlias, $fieldName, $subClassName); - } - } - - $sql .= implode(', ', $sqlParts); - } - - return $sql; - } - - public function walkQuantifiedExpression(AST\QuantifiedExpression $qExpr): string - { - return ' ' . strtoupper($qExpr->type) . '(' . $this->walkSubselect($qExpr->subselect) . ')'; - } - - /** - * Walks down a Subselect AST node, thereby generating the appropriate SQL. - */ - public function walkSubselect(AST\Subselect $subselect): string - { - $useAliasesBefore = $this->useSqlTableAliases; - $rootAliasesBefore = $this->rootAliases; - - $this->rootAliases = []; // reset the rootAliases for the subselect - $this->useSqlTableAliases = true; - - $sql = $this->walkSimpleSelectClause($subselect->simpleSelectClause); - $sql .= $this->walkSubselectFromClause($subselect->subselectFromClause); - $sql .= $this->walkWhereClause($subselect->whereClause); - - $sql .= $subselect->groupByClause ? $this->walkGroupByClause($subselect->groupByClause) : ''; - $sql .= $subselect->havingClause ? $this->walkHavingClause($subselect->havingClause) : ''; - $sql .= $subselect->orderByClause ? $this->walkOrderByClause($subselect->orderByClause) : ''; - - $this->rootAliases = $rootAliasesBefore; // put the main aliases back - $this->useSqlTableAliases = $useAliasesBefore; - - return $sql; - } - - /** - * Walks down a SubselectFromClause AST node, thereby generating the appropriate SQL. - */ - public function walkSubselectFromClause(AST\SubselectFromClause $subselectFromClause): string - { - $identificationVarDecls = $subselectFromClause->identificationVariableDeclarations; - $sqlParts = []; - - foreach ($identificationVarDecls as $subselectIdVarDecl) { - $sqlParts[] = $this->walkIdentificationVariableDeclaration($subselectIdVarDecl); - } - - return ' FROM ' . implode(', ', $sqlParts); - } - - /** - * Walks down a SimpleSelectClause AST node, thereby generating the appropriate SQL. - */ - public function walkSimpleSelectClause(AST\SimpleSelectClause $simpleSelectClause): string - { - return 'SELECT' . ($simpleSelectClause->isDistinct ? ' DISTINCT' : '') - . $this->walkSimpleSelectExpression($simpleSelectClause->simpleSelectExpression); - } - - public function walkParenthesisExpression(AST\ParenthesisExpression $parenthesisExpression): string - { - return sprintf('(%s)', $parenthesisExpression->expression->dispatch($this)); - } - - public function walkNewObject(AST\NewObjectExpression $newObjectExpression, string|null $newObjectResultAlias = null): string - { - $sqlSelectExpressions = []; - $objIndex = $newObjectResultAlias ?: $this->newObjectCounter++; - - foreach ($newObjectExpression->args as $argIndex => $e) { - $resultAlias = $this->scalarResultCounter++; - $columnAlias = $this->getSQLColumnAlias('sclr'); - $fieldType = 'string'; - - switch (true) { - case $e instanceof AST\NewObjectExpression: - $sqlSelectExpressions[] = $e->dispatch($this); - break; - - case $e instanceof AST\Subselect: - $sqlSelectExpressions[] = '(' . $e->dispatch($this) . ') AS ' . $columnAlias; - break; - - case $e instanceof AST\PathExpression: - assert($e->field !== null); - $dqlAlias = $e->identificationVariable; - $class = $this->getMetadataForDqlAlias($dqlAlias); - $fieldName = $e->field; - $fieldMapping = $class->fieldMappings[$fieldName]; - $fieldType = $fieldMapping->type; - $col = trim($e->dispatch($this)); - - $type = Type::getType($fieldType); - $col = $type->convertToPHPValueSQL($col, $this->platform); - - $sqlSelectExpressions[] = $col . ' AS ' . $columnAlias; - - if (! empty($fieldMapping->enumType)) { - $this->rsm->addEnumResult($columnAlias, $fieldMapping->enumType); - } - - break; - - case $e instanceof AST\Literal: - switch ($e->type) { - case AST\Literal::BOOLEAN: - $fieldType = 'boolean'; - break; - - case AST\Literal::NUMERIC: - $fieldType = is_float($e->value) ? 'float' : 'integer'; - break; - } - - $sqlSelectExpressions[] = trim($e->dispatch($this)) . ' AS ' . $columnAlias; - break; - - default: - $sqlSelectExpressions[] = trim($e->dispatch($this)) . ' AS ' . $columnAlias; - break; - } - - $this->scalarResultAliasMap[$resultAlias] = $columnAlias; - $this->rsm->addScalarResult($columnAlias, $resultAlias, $fieldType); - - $this->rsm->newObjectMappings[$columnAlias] = [ - 'className' => $newObjectExpression->className, - 'objIndex' => $objIndex, - 'argIndex' => $argIndex, - ]; - } - - return implode(', ', $sqlSelectExpressions); - } - - /** - * Walks down a SimpleSelectExpression AST node, thereby generating the appropriate SQL. - */ - public function walkSimpleSelectExpression(AST\SimpleSelectExpression $simpleSelectExpression): string - { - $expr = $simpleSelectExpression->expression; - $sql = ' '; - - switch (true) { - case $expr instanceof AST\PathExpression: - $sql .= $this->walkPathExpression($expr); - break; - - case $expr instanceof AST\Subselect: - $alias = $simpleSelectExpression->fieldIdentificationVariable ?: $this->scalarResultCounter++; - - $columnAlias = 'sclr' . $this->aliasCounter++; - $this->scalarResultAliasMap[$alias] = $columnAlias; - - $sql .= '(' . $this->walkSubselect($expr) . ') AS ' . $columnAlias; - break; - - case $expr instanceof AST\Functions\FunctionNode: - case $expr instanceof AST\SimpleArithmeticExpression: - case $expr instanceof AST\ArithmeticTerm: - case $expr instanceof AST\ArithmeticFactor: - case $expr instanceof AST\Literal: - case $expr instanceof AST\NullIfExpression: - case $expr instanceof AST\CoalesceExpression: - case $expr instanceof AST\GeneralCaseExpression: - case $expr instanceof AST\SimpleCaseExpression: - $alias = $simpleSelectExpression->fieldIdentificationVariable ?: $this->scalarResultCounter++; - - $columnAlias = $this->getSQLColumnAlias('sclr'); - $this->scalarResultAliasMap[$alias] = $columnAlias; - - $sql .= $expr->dispatch($this) . ' AS ' . $columnAlias; - break; - - case $expr instanceof AST\ParenthesisExpression: - $sql .= $this->walkParenthesisExpression($expr); - break; - - default: // IdentificationVariable - $sql .= $this->walkEntityIdentificationVariable($expr); - break; - } - - return $sql; - } - - /** - * Walks down an AggregateExpression AST node, thereby generating the appropriate SQL. - */ - public function walkAggregateExpression(AST\AggregateExpression $aggExpression): string - { - return $aggExpression->functionName . '(' . ($aggExpression->isDistinct ? 'DISTINCT ' : '') - . $this->walkSimpleArithmeticExpression($aggExpression->pathExpression) . ')'; - } - - /** - * Walks down a GroupByClause AST node, thereby generating the appropriate SQL. - */ - public function walkGroupByClause(AST\GroupByClause $groupByClause): string - { - $sqlParts = []; - - foreach ($groupByClause->groupByItems as $groupByItem) { - $sqlParts[] = $this->walkGroupByItem($groupByItem); - } - - return ' GROUP BY ' . implode(', ', $sqlParts); - } - - /** - * Walks down a GroupByItem AST node, thereby generating the appropriate SQL. - */ - public function walkGroupByItem(AST\PathExpression|string $groupByItem): string - { - // StateFieldPathExpression - if (! is_string($groupByItem)) { - return $this->walkPathExpression($groupByItem); - } - - // ResultVariable - if (isset($this->queryComponents[$groupByItem]['resultVariable'])) { - $resultVariable = $this->queryComponents[$groupByItem]['resultVariable']; - - if ($resultVariable instanceof AST\PathExpression) { - return $this->walkPathExpression($resultVariable); - } - - if ($resultVariable instanceof AST\Node && isset($resultVariable->pathExpression)) { - return $this->walkPathExpression($resultVariable->pathExpression); - } - - return $this->walkResultVariable($groupByItem); - } - - // IdentificationVariable - $sqlParts = []; - - foreach ($this->getMetadataForDqlAlias($groupByItem)->fieldNames as $field) { - $item = new AST\PathExpression(AST\PathExpression::TYPE_STATE_FIELD, $groupByItem, $field); - $item->type = AST\PathExpression::TYPE_STATE_FIELD; - - $sqlParts[] = $this->walkPathExpression($item); - } - - foreach ($this->getMetadataForDqlAlias($groupByItem)->associationMappings as $mapping) { - if ($mapping->isToOneOwningSide()) { - $item = new AST\PathExpression(AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION, $groupByItem, $mapping->fieldName); - $item->type = AST\PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION; - - $sqlParts[] = $this->walkPathExpression($item); - } - } - - return implode(', ', $sqlParts); - } - - /** - * Walks down a DeleteClause AST node, thereby generating the appropriate SQL. - */ - public function walkDeleteClause(AST\DeleteClause $deleteClause): string - { - $class = $this->em->getClassMetadata($deleteClause->abstractSchemaName); - $tableName = $class->getTableName(); - $sql = 'DELETE FROM ' . $this->quoteStrategy->getTableName($class, $this->platform); - - $this->setSQLTableAlias($tableName, $tableName, $deleteClause->aliasIdentificationVariable); - $this->rootAliases[] = $deleteClause->aliasIdentificationVariable; - - return $sql; - } - - /** - * Walks down an UpdateClause AST node, thereby generating the appropriate SQL. - */ - public function walkUpdateClause(AST\UpdateClause $updateClause): string - { - $class = $this->em->getClassMetadata($updateClause->abstractSchemaName); - $tableName = $class->getTableName(); - $sql = 'UPDATE ' . $this->quoteStrategy->getTableName($class, $this->platform); - - $this->setSQLTableAlias($tableName, $tableName, $updateClause->aliasIdentificationVariable); - $this->rootAliases[] = $updateClause->aliasIdentificationVariable; - - return $sql . ' SET ' . implode(', ', array_map($this->walkUpdateItem(...), $updateClause->updateItems)); - } - - /** - * Walks down an UpdateItem AST node, thereby generating the appropriate SQL. - */ - public function walkUpdateItem(AST\UpdateItem $updateItem): string - { - $useTableAliasesBefore = $this->useSqlTableAliases; - $this->useSqlTableAliases = false; - - $sql = $this->walkPathExpression($updateItem->pathExpression) . ' = '; - $newValue = $updateItem->newValue; - - $sql .= match (true) { - $newValue instanceof AST\Node => $newValue->dispatch($this), - $newValue === null => 'NULL', - }; - - $this->useSqlTableAliases = $useTableAliasesBefore; - - return $sql; - } - - /** - * Walks down a WhereClause AST node, thereby generating the appropriate SQL. - * - * WhereClause or not, the appropriate discriminator sql is added. - */ - public function walkWhereClause(AST\WhereClause|null $whereClause): string - { - $condSql = $whereClause !== null ? $this->walkConditionalExpression($whereClause->conditionalExpression) : ''; - $discrSql = $this->generateDiscriminatorColumnConditionSQL($this->rootAliases); - - if ($this->em->hasFilters()) { - $filterClauses = []; - foreach ($this->rootAliases as $dqlAlias) { - $class = $this->getMetadataForDqlAlias($dqlAlias); - $tableAlias = $this->getSQLTableAlias($class->table['name'], $dqlAlias); - - $filterExpr = $this->generateFilterConditionSQL($class, $tableAlias); - if ($filterExpr) { - $filterClauses[] = $filterExpr; - } - } - - if (count($filterClauses)) { - if ($condSql) { - $condSql = '(' . $condSql . ') AND '; - } - - $condSql .= implode(' AND ', $filterClauses); - } - } - - if ($condSql) { - return ' WHERE ' . (! $discrSql ? $condSql : '(' . $condSql . ') AND ' . $discrSql); - } - - if ($discrSql) { - return ' WHERE ' . $discrSql; - } - - return ''; - } - - /** - * Walk down a ConditionalExpression AST node, thereby generating the appropriate SQL. - */ - public function walkConditionalExpression( - AST\ConditionalExpression|AST\Phase2OptimizableConditional $condExpr, - ): string { - // Phase 2 AST optimization: Skip processing of ConditionalExpression - // if only one ConditionalTerm is defined - if (! ($condExpr instanceof AST\ConditionalExpression)) { - return $this->walkConditionalTerm($condExpr); - } - - return implode(' OR ', array_map($this->walkConditionalTerm(...), $condExpr->conditionalTerms)); - } - - /** - * Walks down a ConditionalTerm AST node, thereby generating the appropriate SQL. - */ - public function walkConditionalTerm( - AST\ConditionalTerm|AST\ConditionalPrimary|AST\ConditionalFactor $condTerm, - ): string { - // Phase 2 AST optimization: Skip processing of ConditionalTerm - // if only one ConditionalFactor is defined - if (! ($condTerm instanceof AST\ConditionalTerm)) { - return $this->walkConditionalFactor($condTerm); - } - - return implode(' AND ', array_map($this->walkConditionalFactor(...), $condTerm->conditionalFactors)); - } - - /** - * Walks down a ConditionalFactor AST node, thereby generating the appropriate SQL. - */ - public function walkConditionalFactor( - AST\ConditionalFactor|AST\ConditionalPrimary $factor, - ): string { - // Phase 2 AST optimization: Skip processing of ConditionalFactor - // if only one ConditionalPrimary is defined - return ! ($factor instanceof AST\ConditionalFactor) - ? $this->walkConditionalPrimary($factor) - : ($factor->not ? 'NOT ' : '') . $this->walkConditionalPrimary($factor->conditionalPrimary); - } - - /** - * Walks down a ConditionalPrimary AST node, thereby generating the appropriate SQL. - */ - public function walkConditionalPrimary(AST\ConditionalPrimary $primary): string - { - if ($primary->isSimpleConditionalExpression()) { - return $primary->simpleConditionalExpression->dispatch($this); - } - - if ($primary->isConditionalExpression()) { - $condExpr = $primary->conditionalExpression; - - return '(' . $this->walkConditionalExpression($condExpr) . ')'; - } - - throw new LogicException('Unexpected state of ConditionalPrimary node.'); - } - - /** - * Walks down an ExistsExpression AST node, thereby generating the appropriate SQL. - */ - public function walkExistsExpression(AST\ExistsExpression $existsExpr): string - { - $sql = $existsExpr->not ? 'NOT ' : ''; - - $sql .= 'EXISTS (' . $this->walkSubselect($existsExpr->subselect) . ')'; - - return $sql; - } - - /** - * Walks down a CollectionMemberExpression AST node, thereby generating the appropriate SQL. - */ - public function walkCollectionMemberExpression(AST\CollectionMemberExpression $collMemberExpr): string - { - $sql = $collMemberExpr->not ? 'NOT ' : ''; - $sql .= 'EXISTS (SELECT 1 FROM '; - - $entityExpr = $collMemberExpr->entityExpression; - $collPathExpr = $collMemberExpr->collectionValuedPathExpression; - assert($collPathExpr->field !== null); - - $fieldName = $collPathExpr->field; - $dqlAlias = $collPathExpr->identificationVariable; - - $class = $this->getMetadataForDqlAlias($dqlAlias); - - switch (true) { - // InputParameter - case $entityExpr instanceof AST\InputParameter: - $dqlParamKey = $entityExpr->name; - $entitySql = '?'; - break; - - // SingleValuedAssociationPathExpression | IdentificationVariable - case $entityExpr instanceof AST\PathExpression: - $entitySql = $this->walkPathExpression($entityExpr); - break; - - default: - throw new BadMethodCallException('Not implemented'); - } - - $assoc = $class->associationMappings[$fieldName]; - - if ($assoc->isOneToMany()) { - $targetClass = $this->em->getClassMetadata($assoc->targetEntity); - $targetTableAlias = $this->getSQLTableAlias($targetClass->getTableName()); - $sourceTableAlias = $this->getSQLTableAlias($class->getTableName(), $dqlAlias); - - $sql .= $this->quoteStrategy->getTableName($targetClass, $this->platform) . ' ' . $targetTableAlias . ' WHERE '; - - $owningAssoc = $targetClass->associationMappings[$assoc->mappedBy]; - assert($owningAssoc->isManyToOne()); - $sqlParts = []; - - foreach ($owningAssoc->targetToSourceKeyColumns as $targetColumn => $sourceColumn) { - $targetColumn = $this->quoteStrategy->getColumnName($class->fieldNames[$targetColumn], $class, $this->platform); - - $sqlParts[] = $sourceTableAlias . '.' . $targetColumn . ' = ' . $targetTableAlias . '.' . $sourceColumn; - } - - foreach ($this->quoteStrategy->getIdentifierColumnNames($targetClass, $this->platform) as $targetColumnName) { - if (isset($dqlParamKey)) { - $this->parserResult->addParameterMapping($dqlParamKey, $this->sqlParamIndex++); - } - - $sqlParts[] = $targetTableAlias . '.' . $targetColumnName . ' = ' . $entitySql; - } - - $sql .= implode(' AND ', $sqlParts); - } else { // many-to-many - $targetClass = $this->em->getClassMetadata($assoc->targetEntity); - - $owningAssoc = $this->em->getMetadataFactory()->getOwningSide($assoc); - assert($owningAssoc->isManyToManyOwningSide()); - $joinTable = $owningAssoc->joinTable; - - // SQL table aliases - $joinTableAlias = $this->getSQLTableAlias($joinTable->name); - $sourceTableAlias = $this->getSQLTableAlias($class->getTableName(), $dqlAlias); - - $sql .= $this->quoteStrategy->getJoinTableName($owningAssoc, $targetClass, $this->platform) . ' ' . $joinTableAlias . ' WHERE '; - - $joinColumns = $assoc->isOwningSide() ? $joinTable->joinColumns : $joinTable->inverseJoinColumns; - $sqlParts = []; - - foreach ($joinColumns as $joinColumn) { - $targetColumn = $this->quoteStrategy->getColumnName($class->fieldNames[$joinColumn->referencedColumnName], $class, $this->platform); - - $sqlParts[] = $joinTableAlias . '.' . $joinColumn->name . ' = ' . $sourceTableAlias . '.' . $targetColumn; - } - - $joinColumns = $assoc->isOwningSide() ? $joinTable->inverseJoinColumns : $joinTable->joinColumns; - - foreach ($joinColumns as $joinColumn) { - if (isset($dqlParamKey)) { - $this->parserResult->addParameterMapping($dqlParamKey, $this->sqlParamIndex++); - } - - $sqlParts[] = $joinTableAlias . '.' . $joinColumn->name . ' IN (' . $entitySql . ')'; - } - - $sql .= implode(' AND ', $sqlParts); - } - - return $sql . ')'; - } - - /** - * Walks down an EmptyCollectionComparisonExpression AST node, thereby generating the appropriate SQL. - */ - public function walkEmptyCollectionComparisonExpression(AST\EmptyCollectionComparisonExpression $emptyCollCompExpr): string - { - $sizeFunc = new AST\Functions\SizeFunction('size'); - $sizeFunc->collectionPathExpression = $emptyCollCompExpr->expression; - - return $sizeFunc->getSql($this) . ($emptyCollCompExpr->not ? ' > 0' : ' = 0'); - } - - /** - * Walks down a NullComparisonExpression AST node, thereby generating the appropriate SQL. - */ - public function walkNullComparisonExpression(AST\NullComparisonExpression $nullCompExpr): string - { - $expression = $nullCompExpr->expression; - $comparison = ' IS' . ($nullCompExpr->not ? ' NOT' : '') . ' NULL'; - - // Handle ResultVariable - if (is_string($expression) && isset($this->queryComponents[$expression]['resultVariable'])) { - return $this->walkResultVariable($expression) . $comparison; - } - - // Handle InputParameter mapping inclusion to ParserResult - if ($expression instanceof AST\InputParameter) { - return $this->walkInputParameter($expression) . $comparison; - } - - assert(! is_string($expression)); - - return $expression->dispatch($this) . $comparison; - } - - /** - * Walks down an InExpression AST node, thereby generating the appropriate SQL. - */ - public function walkInListExpression(AST\InListExpression $inExpr): string - { - return $this->walkArithmeticExpression($inExpr->expression) - . ($inExpr->not ? ' NOT' : '') . ' IN (' - . implode(', ', array_map($this->walkInParameter(...), $inExpr->literals)) - . ')'; - } - - /** - * Walks down an InExpression AST node, thereby generating the appropriate SQL. - */ - public function walkInSubselectExpression(AST\InSubselectExpression $inExpr): string - { - return $this->walkArithmeticExpression($inExpr->expression) - . ($inExpr->not ? ' NOT' : '') . ' IN (' - . $this->walkSubselect($inExpr->subselect) - . ')'; - } - - /** - * Walks down an InstanceOfExpression AST node, thereby generating the appropriate SQL. - * - * @throws QueryException - */ - public function walkInstanceOfExpression(AST\InstanceOfExpression $instanceOfExpr): string - { - $sql = ''; - - $dqlAlias = $instanceOfExpr->identificationVariable; - $discrClass = $class = $this->getMetadataForDqlAlias($dqlAlias); - - if ($class->discriminatorColumn) { - $discrClass = $this->em->getClassMetadata($class->rootEntityName); - } - - if ($this->useSqlTableAliases) { - $sql .= $this->getSQLTableAlias($discrClass->getTableName(), $dqlAlias) . '.'; - } - - $sql .= $class->getDiscriminatorColumn()->name . ($instanceOfExpr->not ? ' NOT IN ' : ' IN '); - $sql .= $this->getChildDiscriminatorsFromClassMetadata($discrClass, $instanceOfExpr); - - return $sql; - } - - public function walkInParameter(mixed $inParam): string - { - return $inParam instanceof AST\InputParameter - ? $this->walkInputParameter($inParam) - : $this->walkArithmeticExpression($inParam); - } - - /** - * Walks down a literal that represents an AST node, thereby generating the appropriate SQL. - */ - public function walkLiteral(AST\Literal $literal): string - { - return match ($literal->type) { - AST\Literal::STRING => $this->conn->quote($literal->value), - AST\Literal::BOOLEAN => (string) $this->conn->getDatabasePlatform()->convertBooleans(strtolower($literal->value) === 'true'), - AST\Literal::NUMERIC => (string) $literal->value, - default => throw QueryException::invalidLiteral($literal), - }; - } - - /** - * Walks down a BetweenExpression AST node, thereby generating the appropriate SQL. - */ - public function walkBetweenExpression(AST\BetweenExpression $betweenExpr): string - { - $sql = $this->walkArithmeticExpression($betweenExpr->expression); - - if ($betweenExpr->not) { - $sql .= ' NOT'; - } - - $sql .= ' BETWEEN ' . $this->walkArithmeticExpression($betweenExpr->leftBetweenExpression) - . ' AND ' . $this->walkArithmeticExpression($betweenExpr->rightBetweenExpression); - - return $sql; - } - - /** - * Walks down a LikeExpression AST node, thereby generating the appropriate SQL. - */ - public function walkLikeExpression(AST\LikeExpression $likeExpr): string - { - $stringExpr = $likeExpr->stringExpression; - if (is_string($stringExpr)) { - if (! isset($this->queryComponents[$stringExpr]['resultVariable'])) { - throw new LogicException(sprintf('No result variable found for string expression "%s".', $stringExpr)); - } - - $leftExpr = $this->walkResultVariable($stringExpr); - } else { - $leftExpr = $stringExpr->dispatch($this); - } - - $sql = $leftExpr . ($likeExpr->not ? ' NOT' : '') . ' LIKE '; - - if ($likeExpr->stringPattern instanceof AST\InputParameter) { - $sql .= $this->walkInputParameter($likeExpr->stringPattern); - } elseif ($likeExpr->stringPattern instanceof AST\Functions\FunctionNode) { - $sql .= $this->walkFunction($likeExpr->stringPattern); - } elseif ($likeExpr->stringPattern instanceof AST\PathExpression) { - $sql .= $this->walkPathExpression($likeExpr->stringPattern); - } else { - $sql .= $this->walkLiteral($likeExpr->stringPattern); - } - - if ($likeExpr->escapeChar) { - $sql .= ' ESCAPE ' . $this->walkLiteral($likeExpr->escapeChar); - } - - return $sql; - } - - /** - * Walks down a StateFieldPathExpression AST node, thereby generating the appropriate SQL. - */ - public function walkStateFieldPathExpression(AST\PathExpression $stateFieldPathExpression): string - { - return $this->walkPathExpression($stateFieldPathExpression); - } - - /** - * Walks down a ComparisonExpression AST node, thereby generating the appropriate SQL. - */ - public function walkComparisonExpression(AST\ComparisonExpression $compExpr): string - { - $leftExpr = $compExpr->leftExpression; - $rightExpr = $compExpr->rightExpression; - $sql = ''; - - $sql .= $leftExpr instanceof AST\Node - ? $leftExpr->dispatch($this) - : (is_numeric($leftExpr) ? $leftExpr : $this->conn->quote($leftExpr)); - - $sql .= ' ' . $compExpr->operator . ' '; - - $sql .= $rightExpr instanceof AST\Node - ? $rightExpr->dispatch($this) - : (is_numeric($rightExpr) ? $rightExpr : $this->conn->quote($rightExpr)); - - return $sql; - } - - /** - * Walks down an InputParameter AST node, thereby generating the appropriate SQL. - */ - public function walkInputParameter(AST\InputParameter $inputParam): string - { - $this->parserResult->addParameterMapping($inputParam->name, $this->sqlParamIndex++); - - $parameter = $this->query->getParameter($inputParam->name); - - if ($parameter) { - $type = $parameter->getType(); - if (is_string($type) && Type::hasType($type)) { - return Type::getType($type)->convertToDatabaseValueSQL('?', $this->platform); - } - } - - return '?'; - } - - /** - * Walks down an ArithmeticExpression AST node, thereby generating the appropriate SQL. - */ - public function walkArithmeticExpression(AST\ArithmeticExpression $arithmeticExpr): string - { - return $arithmeticExpr->isSimpleArithmeticExpression() - ? $this->walkSimpleArithmeticExpression($arithmeticExpr->simpleArithmeticExpression) - : '(' . $this->walkSubselect($arithmeticExpr->subselect) . ')'; - } - - /** - * Walks down an SimpleArithmeticExpression AST node, thereby generating the appropriate SQL. - */ - public function walkSimpleArithmeticExpression(AST\Node|string $simpleArithmeticExpr): string - { - if (! ($simpleArithmeticExpr instanceof AST\SimpleArithmeticExpression)) { - return $this->walkArithmeticTerm($simpleArithmeticExpr); - } - - return implode(' ', array_map($this->walkArithmeticTerm(...), $simpleArithmeticExpr->arithmeticTerms)); - } - - /** - * Walks down an ArithmeticTerm AST node, thereby generating the appropriate SQL. - */ - public function walkArithmeticTerm(AST\Node|string $term): string - { - if (is_string($term)) { - return isset($this->queryComponents[$term]) - ? $this->walkResultVariable($this->queryComponents[$term]['token']->value) - : $term; - } - - // Phase 2 AST optimization: Skip processing of ArithmeticTerm - // if only one ArithmeticFactor is defined - if (! ($term instanceof AST\ArithmeticTerm)) { - return $this->walkArithmeticFactor($term); - } - - return implode(' ', array_map($this->walkArithmeticFactor(...), $term->arithmeticFactors)); - } - - /** - * Walks down an ArithmeticFactor that represents an AST node, thereby generating the appropriate SQL. - */ - public function walkArithmeticFactor(AST\Node|string $factor): string - { - if (is_string($factor)) { - return isset($this->queryComponents[$factor]) - ? $this->walkResultVariable($this->queryComponents[$factor]['token']->value) - : $factor; - } - - // Phase 2 AST optimization: Skip processing of ArithmeticFactor - // if only one ArithmeticPrimary is defined - if (! ($factor instanceof AST\ArithmeticFactor)) { - return $this->walkArithmeticPrimary($factor); - } - - $sign = $factor->isNegativeSigned() ? '-' : ($factor->isPositiveSigned() ? '+' : ''); - - return $sign . $this->walkArithmeticPrimary($factor->arithmeticPrimary); - } - - /** - * Walks down an ArithmeticPrimary that represents an AST node, thereby generating the appropriate SQL. - */ - public function walkArithmeticPrimary(AST\Node|string $primary): string - { - if ($primary instanceof AST\SimpleArithmeticExpression) { - return '(' . $this->walkSimpleArithmeticExpression($primary) . ')'; - } - - if ($primary instanceof AST\Node) { - return $primary->dispatch($this); - } - - return $this->walkEntityIdentificationVariable($primary); - } - - /** - * Walks down a StringPrimary that represents an AST node, thereby generating the appropriate SQL. - */ - public function walkStringPrimary(AST\Node|string $stringPrimary): string - { - return is_string($stringPrimary) - ? $this->conn->quote($stringPrimary) - : $stringPrimary->dispatch($this); - } - - /** - * Walks down a ResultVariable that represents an AST node, thereby generating the appropriate SQL. - */ - public function walkResultVariable(string $resultVariable): string - { - if (! isset($this->scalarResultAliasMap[$resultVariable])) { - throw new InvalidArgumentException(sprintf('Unknown result variable: %s', $resultVariable)); - } - - $resultAlias = $this->scalarResultAliasMap[$resultVariable]; - - if (is_array($resultAlias)) { - return implode(', ', $resultAlias); - } - - return $resultAlias; - } - - /** - * @return string The list in parentheses of valid child discriminators from the given class - * - * @throws QueryException - */ - private function getChildDiscriminatorsFromClassMetadata( - ClassMetadata $rootClass, - AST\InstanceOfExpression $instanceOfExpr, - ): string { - $sqlParameterList = []; - $discriminators = []; - foreach ($instanceOfExpr->value as $parameter) { - if ($parameter instanceof AST\InputParameter) { - $this->rsm->discriminatorParameters[$parameter->name] = $parameter->name; - $sqlParameterList[] = $this->walkInParameter($parameter); - continue; - } - - $metadata = $this->em->getClassMetadata($parameter); - - if ($metadata->getName() !== $rootClass->name && ! $metadata->getReflectionClass()->isSubclassOf($rootClass->name)) { - throw QueryException::instanceOfUnrelatedClass($parameter, $rootClass->name); - } - - $discriminators += HierarchyDiscriminatorResolver::resolveDiscriminatorsForClass($metadata, $this->em); - } - - foreach (array_keys($discriminators) as $discriminatorValue) { - $sqlParameterList[] = $rootClass->getDiscriminatorColumn()->type === 'integer' && is_int($discriminatorValue) - ? $discriminatorValue - : $this->conn->quote((string) $discriminatorValue); - } - - return '(' . implode(', ', $sqlParameterList) . ')'; - } -} diff --git a/vendor/doctrine/orm/src/Query/TokenType.php b/vendor/doctrine/orm/src/Query/TokenType.php deleted file mode 100644 index e745e4a..0000000 --- a/vendor/doctrine/orm/src/Query/TokenType.php +++ /dev/null @@ -1,91 +0,0 @@ -= 100 - case T_FULLY_QUALIFIED_NAME = 101; - case T_IDENTIFIER = 102; - - // All keyword tokens should be >= 200 - case T_ALL = 200; - case T_AND = 201; - case T_ANY = 202; - case T_AS = 203; - case T_ASC = 204; - case T_AVG = 205; - case T_BETWEEN = 206; - case T_BOTH = 207; - case T_BY = 208; - case T_CASE = 209; - case T_COALESCE = 210; - case T_COUNT = 211; - case T_DELETE = 212; - case T_DESC = 213; - case T_DISTINCT = 214; - case T_ELSE = 215; - case T_EMPTY = 216; - case T_END = 217; - case T_ESCAPE = 218; - case T_EXISTS = 219; - case T_FALSE = 220; - case T_FROM = 221; - case T_GROUP = 222; - case T_HAVING = 223; - case T_HIDDEN = 224; - case T_IN = 225; - case T_INDEX = 226; - case T_INNER = 227; - case T_INSTANCE = 228; - case T_IS = 229; - case T_JOIN = 230; - case T_LEADING = 231; - case T_LEFT = 232; - case T_LIKE = 233; - case T_MAX = 234; - case T_MEMBER = 235; - case T_MIN = 236; - case T_NEW = 237; - case T_NOT = 238; - case T_NULL = 239; - case T_NULLIF = 240; - case T_OF = 241; - case T_OR = 242; - case T_ORDER = 243; - case T_OUTER = 244; - case T_SELECT = 246; - case T_SET = 247; - case T_SOME = 248; - case T_SUM = 249; - case T_THEN = 250; - case T_TRAILING = 251; - case T_TRUE = 252; - case T_UPDATE = 253; - case T_WHEN = 254; - case T_WHERE = 255; - case T_WITH = 256; -} diff --git a/vendor/doctrine/orm/src/Query/TreeWalker.php b/vendor/doctrine/orm/src/Query/TreeWalker.php deleted file mode 100644 index 6c21577..0000000 --- a/vendor/doctrine/orm/src/Query/TreeWalker.php +++ /dev/null @@ -1,44 +0,0 @@ - $queryComponents The query components (symbol table). - */ - public function __construct(AbstractQuery $query, ParserResult $parserResult, array $queryComponents); - - /** - * Returns internal queryComponents array. - * - * @psalm-return array - */ - public function getQueryComponents(): array; - - /** - * Walks down a SelectStatement AST node. - */ - public function walkSelectStatement(AST\SelectStatement $selectStatement): void; - - /** - * Walks down an UpdateStatement AST node. - */ - public function walkUpdateStatement(AST\UpdateStatement $updateStatement): void; - - /** - * Walks down a DeleteStatement AST node. - */ - public function walkDeleteStatement(AST\DeleteStatement $deleteStatement): void; -} diff --git a/vendor/doctrine/orm/src/Query/TreeWalkerAdapter.php b/vendor/doctrine/orm/src/Query/TreeWalkerAdapter.php deleted file mode 100644 index a7948db..0000000 --- a/vendor/doctrine/orm/src/Query/TreeWalkerAdapter.php +++ /dev/null @@ -1,90 +0,0 @@ -queryComponents; - } - - public function walkSelectStatement(AST\SelectStatement $selectStatement): void - { - } - - public function walkUpdateStatement(AST\UpdateStatement $updateStatement): void - { - } - - public function walkDeleteStatement(AST\DeleteStatement $deleteStatement): void - { - } - - /** - * Sets or overrides a query component for a given dql alias. - * - * @psalm-param QueryComponent $queryComponent - */ - protected function setQueryComponent(string $dqlAlias, array $queryComponent): void - { - $requiredKeys = ['metadata', 'parent', 'relation', 'map', 'nestingLevel', 'token']; - - if (array_diff($requiredKeys, array_keys($queryComponent))) { - throw QueryException::invalidQueryComponent($dqlAlias); - } - - $this->queryComponents[$dqlAlias] = $queryComponent; - } - - /** - * Retrieves the Query Instance responsible for the current walkers execution. - */ - protected function _getQuery(): AbstractQuery - { - return $this->query; - } - - /** - * Retrieves the ParserResult. - */ - protected function _getParserResult(): ParserResult - { - return $this->parserResult; - } - - protected function getMetadataForDqlAlias(string $dqlAlias): ClassMetadata - { - return $this->queryComponents[$dqlAlias]['metadata'] - ?? throw new LogicException(sprintf('No metadata for DQL alias: %s', $dqlAlias)); - } -} diff --git a/vendor/doctrine/orm/src/Query/TreeWalkerChain.php b/vendor/doctrine/orm/src/Query/TreeWalkerChain.php deleted file mode 100644 index 7bb3051..0000000 --- a/vendor/doctrine/orm/src/Query/TreeWalkerChain.php +++ /dev/null @@ -1,88 +0,0 @@ -> - */ - private array $walkers = []; - - /** - * {@inheritDoc} - */ - public function __construct( - private readonly AbstractQuery $query, - private readonly ParserResult $parserResult, - private array $queryComponents, - ) { - } - - /** - * Returns the internal queryComponents array. - * - * {@inheritDoc} - */ - public function getQueryComponents(): array - { - return $this->queryComponents; - } - - /** - * Adds a tree walker to the chain. - * - * @param string $walkerClass The class of the walker to instantiate. - * @psalm-param class-string $walkerClass - */ - public function addTreeWalker(string $walkerClass): void - { - $this->walkers[] = $walkerClass; - } - - public function walkSelectStatement(AST\SelectStatement $selectStatement): void - { - foreach ($this->getWalkers() as $walker) { - $walker->walkSelectStatement($selectStatement); - - $this->queryComponents = $walker->getQueryComponents(); - } - } - - public function walkUpdateStatement(AST\UpdateStatement $updateStatement): void - { - foreach ($this->getWalkers() as $walker) { - $walker->walkUpdateStatement($updateStatement); - } - } - - public function walkDeleteStatement(AST\DeleteStatement $deleteStatement): void - { - foreach ($this->getWalkers() as $walker) { - $walker->walkDeleteStatement($deleteStatement); - } - } - - /** @psalm-return Generator */ - private function getWalkers(): Generator - { - foreach ($this->walkers as $walkerClass) { - yield new $walkerClass($this->query, $this->parserResult, $this->queryComponents); - } - } -} -- cgit v1.2.3