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

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

The 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.List;
import org.eclipse.persistence.jpa.jpql.ExpressionTools;
import org.eclipse.persistence.jpa.jpql.WordParser;

/**
 * In the SELECT clause the result of a query may be the result of an aggregate function
 * applied to a path expression. The following aggregate functions can be used in the SELECT
 * clause of a query: AVG, COUNT, MAX, MIN, SUM.
 * 

* A single_valued_association_field is designated by the name of an association-field * in a one-to-one or many-to-one relationship. The type of a single_valued_association_field * and thus a single_valued_association_path_expression is the abstract schema type of * the related entity. *

* The argument to an aggregate function may be preceded by the keyword DISTINCT to specify * that duplicate values are to be eliminated before the aggregate function is applied. Null values * are eliminated before the aggregate function is applied, regardless of whether the keyword * DISTINCT * is specified. * *

BNF: aggregate_expression ::= { AVG | MAX | MIN | SUM } ([DISTINCT] state_field_path_expression) | * COUNT ([DISTINCT] identification_variable | * state_field_path_expression | * single_valued_object_path_expression)
* * @see AvgFunction * @see CountFunction * @see MaxFunction * @see MinFunction * @see SumFunction * * @version 2.5 * @since 2.3 * @author Pascal Filion */ public abstract class AggregateFunction extends AbstractSingleEncapsulatedExpression { /** * The actual DISTINCT identifier found in the string representation of the JPQL query. */ private String distinctIdentifier; /** * Determines whether whitespace was found after the identifier DISTINCT. */ private boolean hasSpaceAfterDistinct; /** * Creates a new AggregateFunction. * * @param parent The parent of this expression * @param identifier The JPQL identifier that starts this expression */ protected AggregateFunction(AbstractExpression parent, String identifier) { super(parent, identifier); } @Override protected void addOrderedEncapsulatedExpressionTo(List children) { if (distinctIdentifier != null) { children.add(buildStringExpression(DISTINCT)); } if (hasSpaceAfterDistinct) { children.add(buildStringExpression(SPACE)); } super.addOrderedEncapsulatedExpressionTo(children); } /** * Creates the {@link AbstractExpression} to represent the given word. * * @param word The word that was parsed * @return The encapsulated {@link AbstractExpression} */ protected AbstractExpression buildEncapsulatedExpression(WordParser wordParser, String word) { return new StateFieldPathExpression(this, word); } @Override public String getEncapsulatedExpressionQueryBNFId() { return InternalAggregateFunctionBNF.ID; } /** * Returns the actual DISTINCT identifier found in the string representation of the JPQL * query, which has the actual case that was used. * * @return The DISTINCT identifier that was actually parsed, or an empty string if it was * not parsed */ public String getActualDistinctIdentifier() { return (distinctIdentifier != null) ?distinctIdentifier : ExpressionTools.EMPTY_STRING; } @Override public JPQLQueryBNF getQueryBNF() { return getQueryBNF(AggregateExpressionBNF.ID); } /** * Determines whether the DISTINCT identifier was specified in the query. * * @return true if the query has DISTINCT; false otherwise */ public final boolean hasDistinct() { return distinctIdentifier != null; } /** * Determines whether a whitespace was parsed after DISTINCT. * * @return true if there was a whitespace after DISTINCT; false * otherwise */ public final boolean hasSpaceAfterDistinct() { return hasSpaceAfterDistinct; } @Override protected final void parseEncapsulatedExpression(WordParser wordParser, int whitespaceCount, boolean tolerant) { // Parse 'DISTINCT' if (wordParser.startsWithIdentifier(DISTINCT)) { distinctIdentifier = wordParser.moveForward(DISTINCT); hasSpaceAfterDistinct = wordParser.skipLeadingWhitespace() > 0; } // Parse the rest super.parseEncapsulatedExpression(wordParser, whitespaceCount, tolerant); } @Override protected void toParsedTextEncapsulatedExpression(StringBuilder writer, boolean actual) { if (distinctIdentifier != null) { writer.append(actual ? distinctIdentifier : DISTINCT); } if (hasSpaceAfterDistinct) { writer.append(SPACE); } super.toParsedTextEncapsulatedExpression(writer, actual); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy