| /* |
| * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // Oracle - initial API and implementation from Oracle TopLink |
| // tware - updates for JPA 2.0 specification |
| package org.eclipse.persistence.internal.jpa.parsing; |
| |
| import java.util.List; |
| |
| import org.eclipse.persistence.internal.jpa.parsing.TemporalLiteralNode.TemporalType; |
| |
| /** |
| * INTERNAL |
| * <p><b>Purpose</b>: Implements a node factory used by the EJBQLParser |
| * class. |
| * <p><b>Responsibilities</b>: |
| * <ul> |
| * <li> Create EJBQLParseTree instances for EJBQL SELECT-, UPDATE- and DELETE |
| * statements (see methods newSelectStatement, newUpdateStatement and |
| * newDeleteStatement).</li> |
| * <li> Any new<XXX> method returns an instance of the appropriate Node |
| * subclass.</li> |
| * <li> The relationship to the child nodes passed as arguments are |
| * automatically initialized.</li> |
| * <li>Note, this implementation has a state managing the parse tree context |
| * and a list of parameter names for the current parse tree. This state needs |
| * to be initialized before the same node factory implementation instance may |
| * be used to create a second parse tree (see methods initContext and |
| * initParameters).</li> |
| * <li> The implementation automatically adds the list of parameters to the |
| * created parse tree.</li> |
| * <li> The implementation automatically sets the parse tree context for any |
| * created major node.</li> |
| * </ul> |
| */ |
| public class NodeFactoryImpl implements NodeFactory { |
| |
| /** The parse tree context. */ |
| private ParseTreeContext context; |
| |
| /** */ |
| private String currentIdentificationVariable; |
| |
| /** No-arg Constructor */ |
| public NodeFactoryImpl(String queryInfo) { |
| this.context = new ParseTreeContext(this, queryInfo); |
| } |
| |
| // ------------------------------------------ |
| // Trees |
| // ------------------------------------------ |
| |
| /** */ |
| @Override |
| public Object newSelectStatement(int line, int column, |
| Object select, Object from, |
| Object where, Object groupBy, |
| Object having, Object orderBy) { |
| QueryNode queryNode = (QueryNode)select; |
| JPQLParseTree tree = new JPQLParseTree(); |
| queryNode.setParseTree(tree); |
| tree.setContext(context); |
| tree.setQueryNode(queryNode); |
| tree.setFromNode((FromNode)from); |
| tree.setWhereNode((WhereNode)where); |
| tree.setGroupByNode((GroupByNode)groupBy); |
| tree.setHavingNode((HavingNode)having); |
| tree.setOrderByNode((OrderByNode)orderBy); |
| return tree; |
| } |
| |
| /** */ |
| @Override |
| public Object newUpdateStatement(int line, int column, |
| Object update, Object set, Object where) { |
| QueryNode queryNode = (QueryNode)update; |
| JPQLParseTree tree = new JPQLParseTree(); |
| queryNode.setParseTree(tree); |
| tree.setContext(context); |
| tree.setQueryNode(queryNode); |
| tree.setSetNode((SetNode)set); |
| tree.setWhereNode((WhereNode)where); |
| return tree; |
| } |
| |
| /** */ |
| @Override |
| public Object newDeleteStatement(int line, int column, |
| Object delete, Object where) { |
| QueryNode queryNode = (QueryNode)delete; |
| JPQLParseTree tree = new JPQLParseTree(); |
| queryNode.setParseTree(tree); |
| tree.setContext(context); |
| tree.setQueryNode(queryNode); |
| tree.setWhereNode((WhereNode)where); |
| return tree; |
| } |
| |
| // ------------------------------------------ |
| // Major nodes |
| // ------------------------------------------ |
| |
| @Override |
| public Object newSelectClause(int line, int column, |
| boolean distinct, List<Node> selectExprs) { |
| return newSelectClause(line, column, distinct, selectExprs, null); |
| } |
| |
| @Override |
| public Object newSelectClause(int line, int column, boolean distinct, List<Node> selectExprs, List<String> identifiers) { |
| SelectNode node = new SelectNode(); |
| node.setContext(context); |
| node.setSelectExpressions(selectExprs); |
| node.setIdentifiers(identifiers); |
| if (identifiers != null){ |
| for (int i=0;i<identifiers.size();i++){ |
| if (identifiers.get(i) != null){ |
| context.registerJoinVariable(calculateCanonicalName(identifiers.get(i)), selectExprs.get(i), line, column); |
| } |
| } |
| } |
| node.setDistinct(distinct); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newFromClause(int line, int column, List<Node> decls) { |
| FromNode node = new FromNode(); |
| node.setContext(context); |
| node.setDeclarations(decls); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newWhereClause(int line, int column, Object condition) { |
| WhereNode node = new WhereNode(); |
| node.setContext(context); |
| node.setLeft((Node)condition); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newGroupByClause(int line, int column, List<Node> items) { |
| GroupByNode node = new GroupByNode(); |
| node.setContext(context); |
| node.setGroupByItems(items); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newHavingClause(int line, int column, Object arg) { |
| HavingNode node = new HavingNode(); |
| node.setContext(context); |
| node.setHaving((Node)arg); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newOrderByClause(int line, int column, List<Node> items) { |
| OrderByNode node = new OrderByNode(); |
| node.setContext(context); |
| node.setOrderByItems(items); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newUpdateClause(int line, int column, |
| String schema, String variable) { |
| UpdateNode node = new UpdateNode(); |
| node.setContext(context); |
| node.setAbstractSchemaName(schema); |
| node.setAbstractSchemaIdentifier(variable); |
| setPosition(node, line, column); |
| registerSchema(calculateCanonicalName(variable), schema, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newDeleteClause(int line, int column, |
| String schema, String variable) { |
| DeleteNode node = new DeleteNode(); |
| node.setContext(context); |
| node.setAbstractSchemaName(schema); |
| node.setAbstractSchemaIdentifier(variable); |
| setPosition(node, line, column); |
| registerSchema(calculateCanonicalName(variable), schema, line, column); |
| return node; |
| } |
| |
| // ------------------------------------------ |
| // Variable declaration nodes |
| // ------------------------------------------ |
| |
| /** */ |
| @Override |
| public Object newRangeVariableDecl(int line, int column, |
| String schema, String variable) { |
| RangeDeclNode node = new RangeDeclNode(); |
| node.setAbstractSchemaName(schema); |
| node.setVariableName(variable); |
| setPosition(node, line, column); |
| registerSchema(node.getCanonicalVariableName(), schema, line, column); |
| currentIdentificationVariable = variable; |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newJoinVariableDecl(int line, int column, boolean outerJoin, |
| Object path, String variable, Object downcast) { |
| DotNode dotNode = (DotNode)path; |
| AttributeNode rightNode = (AttributeNode)dotNode.getRight(); |
| rightNode.setOuterJoin(outerJoin); |
| if (downcast != null){ |
| AttributeNode rightMostNode = (AttributeNode)dotNode.getRightMostNode(); |
| rightMostNode.setCastClassName((String)downcast); |
| } |
| JoinDeclNode node = new JoinDeclNode(); |
| node.setPath(dotNode); |
| node.setVariableName(variable); |
| node.setOuterJoin(outerJoin); |
| setPosition(node, line, column); |
| context.registerJoinVariable(node.getCanonicalVariableName(), dotNode, line, column); |
| currentIdentificationVariable = variable; |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newFetchJoin(int line, int column, |
| boolean outerJoin, Object path) { |
| DotNode dotNode = (DotNode)path; |
| AttributeNode rightNode = (AttributeNode)dotNode.getRight(); |
| rightNode.setOuterJoin(outerJoin); |
| // register the dot expression to be added as joined attribute |
| FetchJoinNode node = new FetchJoinNode(); |
| node.setPath(dotNode); |
| node.setOuterJoin(outerJoin); |
| setPosition(node, line, column); |
| context.registerFetchJoin(currentIdentificationVariable, dotNode); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newCollectionMemberVariableDecl(int line, int column, |
| Object path, String variable) { |
| DotNode dotNode = (DotNode)path; |
| AttributeNode rightNode = (AttributeNode)dotNode.getRight(); |
| // The IN-clause expression must be a collection valued path expression |
| rightNode.setRequiresCollectionAttribute(true); |
| CollectionMemberDeclNode node = new CollectionMemberDeclNode(); |
| node.setPath(dotNode); |
| node.setVariableName(variable); |
| setPosition(node, line, column); |
| context.registerJoinVariable(node.getCanonicalVariableName(), dotNode, line, column); |
| currentIdentificationVariable = variable; |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newVariableDecl(int line, int column, |
| Object path, String variable) { |
| DotNode dotNode = (DotNode)path; |
| JoinDeclNode node = new JoinDeclNode(); |
| node.setPath(dotNode); |
| node.setVariableName(variable); |
| setPosition(node, line, column); |
| context.registerJoinVariable(node.getCanonicalVariableName(), dotNode, line, column); |
| currentIdentificationVariable = variable; |
| return node; |
| } |
| |
| // ------------------------------------------ |
| // Identifier and path expression nodes |
| // ------------------------------------------ |
| |
| /** */ |
| @Override |
| public Object newDot(int line, int column, Object left, Object right) { |
| DotNode node = new DotNode(); |
| node.setLeft((Node)left); |
| node.setRight((Node)right); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newVariableAccessOrTypeConstant(int line, int column, String identifier) { |
| VariableNode node = new VariableNode(identifier); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newAttribute(int line, int column, String identifier) { |
| AttributeNode node = new AttributeNode(identifier); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newQualifiedAttribute(int line, int column, |
| String variable, String attribute) { |
| Object varNode = newVariableAccessOrTypeConstant(line, column, variable); |
| Object attrNode = newAttribute(line, column, attribute); |
| return newDot(line, column, varNode, attrNode); |
| } |
| |
| // ------------------------------------------ |
| // Aggregate nodes |
| // ------------------------------------------ |
| |
| /** */ |
| @Override |
| public Object newAvg(int line, int column, boolean distinct, Object arg) { |
| AvgNode node = new AvgNode(); |
| node.setLeft((Node)arg); |
| node.setDistinct(distinct); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newMax(int line, int column, boolean distinct, Object arg) { |
| MaxNode node = new MaxNode(); |
| node.setLeft((Node)arg); |
| node.setDistinct(distinct); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newMin(int line, int column, boolean distinct, Object arg) { |
| MinNode node = new MinNode(); |
| node.setLeft((Node)arg); |
| node.setDistinct(distinct); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newSum(int line, int column, boolean distinct, Object arg) { |
| SumNode node = new SumNode(); |
| node.setLeft((Node)arg); |
| node.setDistinct(distinct); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newCount(int line, int column, boolean distinct, Object arg) { |
| CountNode node = new CountNode(); |
| node.setLeft((Node)arg); |
| node.setDistinct(distinct); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| // ------------------------------------------ |
| // Binary expression nodes |
| // ------------------------------------------ |
| |
| /** */ |
| @Override |
| public Object newOr(int line, int column, Object left, Object right) { |
| OrNode node = new OrNode(); |
| node.setLeft((Node)left); |
| node.setRight((Node)right); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newAnd(int line, int column, Object left, Object right) { |
| AndNode node = new AndNode(); |
| node.setLeft((Node)left); |
| node.setRight((Node)right); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newEquals(int line, int column, Object left, Object right) { |
| EqualsNode node = new EqualsNode(); |
| node.setLeft((Node)left); |
| node.setRight((Node)right); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newNotEquals(int line, int column, Object left, Object right) { |
| NotEqualsNode node = new NotEqualsNode(); |
| node.setLeft((Node)left); |
| node.setRight((Node)right); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newGreaterThan(int line, int column, |
| Object left, Object right) { |
| GreaterThanNode node = new GreaterThanNode(); |
| node.setLeft((Node)left); |
| node.setRight((Node)right); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newGreaterThanEqual(int line, int column, |
| Object left, Object right) { |
| GreaterThanEqualToNode node = new GreaterThanEqualToNode(); |
| node.setLeft((Node)left); |
| node.setRight((Node)right); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newLessThan(int line, int column, Object left, Object right) { |
| LessThanNode node = new LessThanNode(); |
| node.setLeft((Node)left); |
| node.setRight((Node)right); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newLessThanEqual(int line, int column, |
| Object left, Object right) { |
| LessThanEqualToNode node = new LessThanEqualToNode(); |
| node.setLeft((Node)left); |
| node.setRight((Node)right); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newPlus(int line, int column, Object left, Object right) { |
| PlusNode node = new PlusNode(); |
| node.setLeft((Node)left); |
| node.setRight((Node)right); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newMinus(int line, int column, Object left, Object right) { |
| MinusNode node = new MinusNode(); |
| node.setLeft((Node)left); |
| node.setRight((Node)right); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newMultiply(int line, int column, Object left, Object right) { |
| MultiplyNode node = new MultiplyNode(); |
| node.setLeft((Node)left); |
| node.setRight((Node)right); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| // ------------------------------------------ |
| // Conditional expression nodes |
| // ------------------------------------------ |
| |
| /** */ |
| @Override |
| public Object newBetween(int line, int column, boolean not, Object arg, |
| Object lower, Object upper) { |
| BetweenNode node = new BetweenNode(); |
| node.setLeft((Node)arg); |
| node.setRightForBetween((Node)lower); |
| node.setRightForAnd((Node)upper); |
| setPosition(node, line, column); |
| return not? newNot(line, column, node) : node; |
| } |
| |
| /** */ |
| @Override |
| public Object newDivide(int line, int column, Object left, Object right) { |
| DivideNode node = new DivideNode(); |
| node.setLeft((Node)left); |
| node.setRight((Node)right); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| // ------------------------------------------ |
| // Unary expression nodes |
| // ------------------------------------------ |
| |
| /** */ |
| @Override |
| public Object newUnaryPlus(int line, int column, Object arg) { |
| return arg; |
| } |
| |
| /** */ |
| @Override |
| public Object newUnaryMinus(int line, int column, Object arg) { |
| UnaryMinus node = new UnaryMinus(); |
| node.setLeft((Node)arg); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newNot(int line, int column, Object arg) { |
| NotNode node = new NotNode(); |
| node.setLeft((Node)arg); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| // ------------------------------------------ |
| // Conditional expression nodes |
| // ------------------------------------------ |
| |
| /** */ |
| @Override |
| public Object newLike(int line, int column, boolean not, Object string, |
| Object pattern, Object escape) { |
| LikeNode node = new LikeNode(); |
| node.setLeft((Node)string); |
| node.setRight((Node)pattern); |
| node.setEscapeNode((EscapeNode)escape); |
| setPosition(node, line, column); |
| return not ? newNot(line, column, node) : node; |
| } |
| |
| /** */ |
| @Override |
| public Object newEscape(int line, int column, Object arg) { |
| EscapeNode node = new EscapeNode(); |
| node.setLeft((Node)arg); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newIn(int line, int column, |
| boolean not, Object expr, List<Node> items) { |
| InNode node = new InNode(); |
| if (not) node.indicateNot(); |
| node.setLeft((Node)expr); |
| node.setTheObjects(items); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newIsNull(int line, int column, boolean not, Object expr) { |
| NullComparisonNode node = new NullComparisonNode(); |
| node.setLeft((Node)expr); |
| setPosition(node, line, column); |
| return not ? newNot(line, column, node) : node; |
| } |
| |
| /** */ |
| @Override |
| public Object newIsEmpty(int line, int column, boolean not, Object expr) { |
| EmptyCollectionComparisonNode node = |
| new EmptyCollectionComparisonNode(); |
| node.setLeft((Node)expr); |
| if (not) node.indicateNot(); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newMemberOf(int line, int column, |
| boolean not, Object expr, Object collection) { |
| MemberOfNode node = new MemberOfNode(); |
| node.setLeft((Node)expr); |
| node.setRight((Node)collection); |
| if (not) node.indicateNot(); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| // ------------------------------------------ |
| // Parameter nodes |
| // ------------------------------------------ |
| |
| /** */ |
| @Override |
| public Object newPositionalParameter(int line, int column, String position) { |
| ParameterNode node = new ParameterNode(position); |
| context.addParameter(position); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newNamedParameter(int line, int column, String name) { |
| ParameterNode node = new ParameterNode(name); |
| context.addParameter(name); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| // ------------------------------------------ |
| // Literal nodes |
| // ------------------------------------------ |
| |
| /** */ |
| @Override |
| public Object newBooleanLiteral(int line, int column, Object value) { |
| BooleanLiteralNode node = new BooleanLiteralNode(); |
| node.setLiteral(value); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newIntegerLiteral(int line, int column, Object value) { |
| IntegerLiteralNode node = new IntegerLiteralNode(); |
| node.setLiteral(value); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newLongLiteral(int line, int column, Object value) { |
| LongLiteralNode node = new LongLiteralNode(); |
| node.setLiteral(value); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newFloatLiteral(int line, int column, Object value) { |
| FloatLiteralNode node = new FloatLiteralNode(); |
| node.setLiteral(value); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newDoubleLiteral(int line, int column, Object value) { |
| DoubleLiteralNode node = new DoubleLiteralNode(); |
| node.setLiteral(value); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newStringLiteral(int line, int column, Object value) { |
| StringLiteralNode node = new StringLiteralNode(); |
| node.setLiteral(value); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newNullLiteral(int line, int column) { |
| LiteralNode node = new LiteralNode(); |
| node.setLiteral(null); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| // ------------------------------------------ |
| // Objects for functions returning strings |
| // ------------------------------------------ |
| |
| /** */ |
| @Override |
| public Object newConcat(int line, int column, List<Node> objects) { |
| ConcatNode node = new ConcatNode(); |
| node.setObjects(objects); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newSubstring(int line, int column, |
| Object string, Object start, Object length) { |
| SubstringNode node = new SubstringNode(); |
| node.setLeft((Node)string); |
| node.setStartPosition((Node)start); |
| node.setStringLength((Node)length); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newTrim(int line, int column, TrimSpecification trimSpec, |
| Object trimChar, Object string) { |
| TrimNode node = new TrimNode(); |
| node.setLeft((Node)string); |
| node.setTrimChar((Node)trimChar); |
| switch (trimSpec) { |
| case LEADING: |
| node.setLeading(true); |
| break; |
| case TRAILING: |
| node.setTrailing(true); |
| break; |
| case BOTH: |
| node.setBoth(true); |
| break; |
| } |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newLower(int line, int column, Object arg) { |
| LowerNode node = new LowerNode(); |
| node.setLeft((Node)arg); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newUpper(int line, int column, Object arg) { |
| UpperNode node = new UpperNode(); |
| node.setLeft((Node)arg); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| // ------------------------------------------ |
| // Objects for functions returning numerics |
| // ------------------------------------------ |
| |
| /** */ |
| @Override |
| public Object newLocate(int line, int column, |
| Object pattern, Object arg, Object startPos) { |
| LocateNode node = new LocateNode(); |
| node.setFind((Node)pattern); |
| node.setFindIn((Node)arg); |
| node.setStartPosition((Node)startPos); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newLength(int line, int column, Object arg) { |
| LengthNode node = new LengthNode(); |
| node.setLeft((Node)arg); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newAbs(int line, int column, Object arg) { |
| AbsNode node = new AbsNode(); |
| node.setLeft((Node)arg); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newSqrt(int line, int column, Object arg) { |
| SqrtNode node = new SqrtNode(); |
| node.setLeft((Node)arg); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newMod(int line, int column, Object left, Object right) { |
| ModNode node = new ModNode(); |
| node.setLeft((Node)left); |
| node.setDenominator((Node)right); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newSize(int line, int column, Object arg) { |
| SizeNode node = new SizeNode(); |
| node.setLeft((Node)arg); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| // ------------------------------------------ |
| // Objects for functions returning datetime |
| // ------------------------------------------ |
| |
| /** */ |
| @Override |
| public Object newCurrentDate(int line, int column) { |
| DateFunctionNode node = new DateFunctionNode(); |
| node.useCurrentDate(); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newCurrentTime(int line, int column) { |
| DateFunctionNode node = new DateFunctionNode(); |
| node.useCurrentTime(); |
| setPosition(node, line, column); |
| |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newCurrentTimestamp(int line, int column) { |
| DateFunctionNode node = new DateFunctionNode(); |
| node.useCurrentTimestamp(); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| // ------------------------------------------ |
| // Custom function |
| // ------------------------------------------ |
| |
| /** */ |
| @Override |
| public Object newFunc(int line, int column, String name, List<Node> parameters) { |
| FuncNode node = new FuncNode(); |
| if(name.startsWith("'") && name.endsWith("'")) { |
| name = name.substring(1, name.length()-1); |
| } |
| node.setName(name); |
| node.setParameters(parameters); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| // ------------------------------------------ |
| // Subquery nodes |
| // ------------------------------------------ |
| |
| /** */ |
| @Override |
| public Object newSubquery(int line, int column, |
| Object select, Object from, Object where, |
| Object groupBy, Object having) { |
| QueryNode queryNode = (QueryNode)select; |
| JPQLParseTree tree = new JPQLParseTree(); |
| queryNode.setParseTree(tree); |
| tree.setQueryNode(queryNode); |
| tree.setFromNode((FromNode)from); |
| tree.setWhereNode((WhereNode)where); |
| tree.setGroupByNode((GroupByNode)groupBy); |
| tree.setHavingNode((HavingNode)having); |
| tree.setContext(context); |
| SubqueryNode node = new SubqueryNode(); |
| node.setParseTree(tree); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newExists(int line, int column, boolean not, Object subquery) { |
| ExistsNode node = new ExistsNode(); |
| if (not) node.indicateNot(); |
| node.setLeft((Node)subquery); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newIn(int line, int column, |
| boolean not, Object expr, Object subquery) { |
| InNode node = new InNode(); |
| if (not) node.indicateNot(); |
| node.setLeft((Node)expr); |
| node.addNodeToTheObjects((Node)subquery); |
| setPosition(node, line, column); |
| node.setIsListParameterOrSubquery(true); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newAll(int line, int column, Object subquery) { |
| AllNode node = new AllNode(); |
| node.setLeft((Node)subquery); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newAny(int line, int column, Object subquery) { |
| AnyNode node = new AnyNode(); |
| node.setLeft((Node)subquery); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newSome(int line, int column, Object subquery) { |
| SomeNode node = new SomeNode(); |
| node.setLeft((Node)subquery); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| // ------------------------------------------ |
| // Miscellaneous nodes |
| // ------------------------------------------ |
| |
| /** */ |
| @Override |
| public Object newAscOrdering(int line, int column, Object arg) { |
| OrderByItemNode node = new OrderByItemNode(); |
| SortDirectionNode sortDirection = new SortDirectionNode(); |
| sortDirection.useAscending(); |
| node.setDirection(sortDirection); |
| node.setOrderByItem(arg); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newDescOrdering(int line, int column, Object arg) { |
| OrderByItemNode node = new OrderByItemNode(); |
| SortDirectionNode sortDirection = new SortDirectionNode(); |
| sortDirection.useDescending(); |
| node.setDirection(sortDirection); |
| node.setOrderByItem(arg); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newConstructor(int line, int column, |
| String className, List<Node> args) { |
| ConstructorNode node = new ConstructorNode(className); |
| node.setConstructorItems(args); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newSetClause(int line, int column, List<Node> assignments) { |
| SetNode node = new SetNode(); |
| node.setAssignmentNodes(assignments); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| /** */ |
| @Override |
| public Object newSetAssignmentClause(int line, int column, |
| Object target, Object value) { |
| EqualsAssignmentNode node = new EqualsAssignmentNode(); |
| node.setLeft((Node)target); |
| node.setRight((Node)value); |
| return node; |
| } |
| |
| // ------------------------------------------ |
| // Helper methods |
| // ------------------------------------------ |
| |
| /** */ |
| private void setPosition(Node node, int line, int column) { |
| node.setLine(line); |
| node.setColumn(column); |
| } |
| |
| /** */ |
| private void registerSchema(String variable, String schema, int line, int column) { |
| if (variable != null) { |
| context.registerSchema(variable, schema, line, column); |
| } |
| else { |
| // UPDATE and DELETE may not define a variable => |
| // use schema name as variable |
| context.registerSchema(calculateCanonicalName(schema), schema, line, column); |
| } |
| } |
| |
| /** */ |
| private String calculateCanonicalName(String name) { |
| return (name == null) ? null : |
| IdentificationVariableDeclNode.calculateCanonicalName(name); |
| } |
| |
| @Override |
| public Object newKey(int line, int column, Object left){ |
| MapKeyNode node = new MapKeyNode(); |
| node.setLeft((Node)left); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| @Override |
| public Object newMapEntry(int line, int column, Object arg){ |
| MapEntryNode node = new MapEntryNode(); |
| node.setLeft((Node)arg); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| @Override |
| public Object newType(int line, int column, Object left){ |
| ClassForInheritanceNode node = new ClassForInheritanceNode(); |
| node.setLeft((Node)left); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| @Override |
| public Object newCaseClause(int line, int column, Object base, List<Node> whenClauses, Object elseClause){ |
| CaseNode node = new CaseNode(); |
| node.setWhenClauses(whenClauses); |
| if (base != null){ |
| node.setLeft((Node)base); |
| } |
| node.setRight((Node)elseClause); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| @Override |
| public Object newCoalesceClause(int line, int column, List<Node> clauses){ |
| CoalesceNode node = new CoalesceNode(); |
| node.setClauses(clauses); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| @Override |
| public Object newNullIfClause(int line, int column, Object left, Object right){ |
| NullIfNode node = new NullIfNode(); |
| node.setLeft((Node)left); |
| node.setRight((Node)right); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| @Override |
| public Object newWhenClause(int line, int column, Object conditionClause, Object thenClause){ |
| WhenThenNode node = new WhenThenNode(); |
| node.setLeft((Node)conditionClause); |
| node.setRight((Node)thenClause); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| @Override |
| public Object newIndex(int line, int column, Object object){ |
| IndexNode node = new IndexNode(); |
| node.setLeft((Node)object); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| @Override |
| public Object newDateLiteral(int line, int column, Object value){ |
| TemporalLiteralNode node = new TemporalLiteralNode(TemporalType.DATE); |
| node.setLiteral(value); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| @Override |
| public Object newTimeLiteral(int line, int column, Object value){ |
| TemporalLiteralNode node = new TemporalLiteralNode(TemporalType.TIME); |
| node.setLiteral(value); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| @Override |
| public Object newTimeStampLiteral(int line, int column, Object value){ |
| TemporalLiteralNode node = new TemporalLiteralNode(TemporalType.TIMESTAMP); |
| node.setLiteral(value); |
| setPosition(node, line, column); |
| return node; |
| } |
| |
| } |
| |