All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.persistence.jpa.jpql.parser.SelectStatement Maven / Gradle / Ivy

There is a newer version: 5.0.0-B03
Show newest version
/*
 * Copyright (c) 2006, 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
//
package org.eclipse.persistence.jpa.jpql.parser;

import java.util.Collection;
import java.util.List;
import org.eclipse.persistence.jpa.jpql.WordParser;

/**
 * A SELECT query is an operation that retrieves data from one or more tables or
 * views.
 * 
* JPA: *
BNF: select_statement ::= select_clause * from_clause * [where_clause] * [groupby_clause] * [having_clause] * [orderby_clause]
*
* EclipseLink 2.4: *
BNF: select_statement ::= select_clause * from_clause * [where_clause] * [groupby_clause] * [having_clause] * [orderby_clause] * {union_clause}*
*
* HQL query (EclipseLink 2.5): *
BNF: select_statement ::= [select_clause] * from_clause * [where_clause] * [groupby_clause] * [having_clause] * [orderby_clause] * {union_clause}*
* * @see FromClause * @see GroupByClause * @see HavingClause * @see HierarchicalQueryClause * @see OrderByClause * @see SelectClause * @see UnionClause * @see WhereClause * * @version 2.5 * @since 2.3 * @author Pascal Filion */ public final class SelectStatement extends AbstractSelectStatement { /** * Determines whether there is a whitespace after the select statement parsed by the superclass * and the ORDER BY identifier. */ private boolean hasSpaceBeforeOrderBy; /** * Determines whether there is a whitespace after the select statement parsed by the superclass * and the UNION identifier. */ private boolean hasSpaceBeforeUnion; /** * The ORDER BY expression. */ private AbstractExpression orderByClause; /** * The UNION expression. */ private AbstractExpression unionClauses; /** * Creates a new SelectStatement. * * @param parent The parent of this expression */ public SelectStatement(AbstractExpression parent) { super(parent); } @Override public void accept(ExpressionVisitor visitor) { visitor.visit(this); } @Override public void acceptChildren(ExpressionVisitor visitor) { super.acceptChildren(visitor); getOrderByClause().accept(visitor); getUnionClauses().accept(visitor); } @Override protected void addChildrenTo(Collection children) { super.addChildrenTo(children); children.add(getOrderByClause()); children.add(getUnionClauses()); } @Override protected void addOrderedChildrenTo(List children) { super.addOrderedChildrenTo(children); if (hasSpaceBeforeOrderBy) { children.add(buildStringExpression(SPACE)); } // 'ORDER BY' clause if (orderByClause != null) { children.add(orderByClause); } // 'UNION' clauses if (unionClauses != null) { children.add(unionClauses); } } @Override protected FromClause buildFromClause() { return new FromClause(this); } @Override protected SelectClause buildSelectClause() { return new SelectClause(this); } @Override public JPQLQueryBNF findQueryBNF(Expression expression) { if ((orderByClause != null) && orderByClause.isAncestor(expression)) { return orderByClause.getQueryBNF(); } if ((unionClauses != null) && unionClauses.isAncestor(expression)) { return getQueryBNF(UnionClauseBNF.ID); } return super.findQueryBNF(expression); } /** * Returns the {@link Expression} representing the ORDER BY clause. * * @return The expression representing the ORDER BY clause */ public Expression getOrderByClause() { if (orderByClause == null) { orderByClause = buildNullExpression(); } return orderByClause; } @Override public JPQLQueryBNF getQueryBNF() { return getQueryBNF(SelectStatementBNF.ID); } /** * Returns the {@link Expression} representing the UNION clauses. * * @return The {@link Expression} representing the UNION clauses */ public Expression getUnionClauses() { if (unionClauses == null) { unionClauses = buildNullExpression(); } return unionClauses; } /** * Determines whether the ORDER BY clause is defined or not. * * @return true if the query that got parsed had the ORDER BY clause */ public boolean hasOrderByClause() { return orderByClause != null && !orderByClause.isNull(); } /** * Determines whether a whitespace was parsed before the ORDER BY clause. In some cases, * the space could be owned by a child of the previous clause. * * @return true if there was a whitespace before the ORDER BY; false * otherwise */ public boolean hasSpaceBeforeOrderBy() { return hasSpaceBeforeOrderBy; } /** * Determines whether a whitespace was parsed before the UNION clause. In some cases, * the space could be owned by a child of the previous clause. * * @return true if there was a whitespace before the UNION; * false otherwise */ public boolean hasSpaceBeforeUnion() { return hasSpaceBeforeUnion; } /** * Determines whether at least one UNION clause was defined. * * @return true if the query that got parsed had the UNION clauses */ public boolean hasUnionClauses() { return unionClauses != null && !unionClauses.isNull(); } @Override protected boolean isParsingComplete(WordParser wordParser, String word, Expression expression) { if (word.equalsIgnoreCase(UNION) || word.equalsIgnoreCase(INTERSECT) || word.equalsIgnoreCase(EXCEPT)) { return false; } return super.isParsingComplete(wordParser, word, expression); } @Override protected void parse(WordParser wordParser, boolean tolerant) { super.parse(wordParser, tolerant); hasSpaceBeforeOrderBy = wordParser.skipLeadingWhitespace() > 0; // Parse 'ORDER BY' if (wordParser.startsWithIdentifier(ORDER_BY)) { orderByClause = new OrderByClause(this); orderByClause.parse(wordParser, tolerant); } // Parse the union clauses and make sure the grammar supports it if (getQueryBNF(UnionClauseBNF.ID) != null) { hasSpaceBeforeUnion = wordParser.skipLeadingWhitespace() > 0; unionClauses = parse(wordParser, UnionClauseBNF.ID, tolerant); } } @Override protected void toParsedText(StringBuilder writer, boolean actual) { super.toParsedText(writer, actual); if (hasSpaceBeforeOrderBy) { writer.append(SPACE); } // 'ORDER BY' clause if (hasOrderByClause()) { orderByClause.toParsedText(writer, actual); } if (hasSpaceBeforeUnion) { writer.append(SPACE); } // 'UNION' clauses if (hasUnionClauses()) { unionClauses.toParsedText(writer, actual); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy