org.eclipse.persistence.internal.jpa.jpql.ReadAllQueryBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eclipselink Show documentation
Show all versions of eclipselink Show documentation
EclipseLink build based upon Git transaction f2b9fc5
/*
* 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.internal.jpa.jpql;
import org.eclipse.persistence.jpa.jpql.parser.CollectionExpression;
import org.eclipse.persistence.jpa.jpql.parser.EclipseLinkAnonymousExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.Expression;
import org.eclipse.persistence.jpa.jpql.parser.IdentificationVariable;
import org.eclipse.persistence.jpa.jpql.parser.NullExpression;
import org.eclipse.persistence.jpa.jpql.parser.ObjectExpression;
import org.eclipse.persistence.jpa.jpql.parser.ResultVariable;
import org.eclipse.persistence.jpa.jpql.parser.SelectClause;
import org.eclipse.persistence.jpa.jpql.parser.SelectStatement;
import org.eclipse.persistence.queries.ReadAllQuery;
import org.eclipse.persistence.queries.ReportQuery;
/**
* This visitor visits the select expression in order to create the correct {@link ReadAllQuery},
* which is either a {@link ReportQuery} or a {@link ReadAllQuery}.
*
* @version 2.5
* @since 2.3
* @author Pascal Filion
* @author John Bracken
*/
final class ReadAllQueryBuilder extends EclipseLinkAnonymousExpressionVisitor {
/**
* The query that was created based on the type of select clause.
*/
ReadAllQuery query;
/**
* The {@link JPQLQueryContext} is used to query information about the application metadata and
* cached information.
*/
private final JPQLQueryContext queryContext;
/**
* The {@link Expression} being visited.
*/
private SelectStatement selectStatement;
/**
* Creates a new ReadAllQueryBuilder
.
*
* @param queryContext The context used to query information about the application metadata and
* cached information
*/
ReadAllQueryBuilder(JPQLQueryContext queryContext) {
super();
this.queryContext = queryContext;
}
private void initializeReadAllQuery() {
ReadAllQuery query = new ReadAllQuery();
query.dontUseDistinct();
this.query = query;
}
private void initializeReportQuery() {
ReportQuery query = new ReportQuery();
query.returnWithoutReportQueryResult();
query.dontUseDistinct();
this.query = query;
}
@Override
public void visit(CollectionExpression expression) {
// Multiple expressions in the select clause => ReportQuery
initializeReportQuery();
}
@Override
protected void visit(Expression expression) {
// Does not select an identification variable
// (e.g. projection or aggregate function) => ReportQuery
initializeReportQuery();
}
@Override
public void visit(IdentificationVariable expression) {
// Use ReadAllQuery if the variable of the SELECT clause expression is the base variable
// Example: ReadAllQuery = SELECT e FROM Employee e
// Example: ReportQuery = SELECT e FROM Department d JOIN d.employees e
String variableName = expression.getVariableName();
if (queryContext.isRangeIdentificationVariable(variableName)) {
if (selectStatement.hasGroupByClause() ||
selectStatement.hasHavingClause() ||
variableName != queryContext.getFirstDeclaration().getVariableName()) {
initializeReportQuery();
}
else {
initializeReadAllQuery();
}
}
else {
initializeReportQuery();
}
}
@Override
public void visit(NullExpression expression) {
// For from clause only JPQL the full object is always selected, so is ReadAllQuery.
initializeReadAllQuery();
}
@Override
public void visit(ObjectExpression expression) {
// Visit the identification variable directly
expression.getExpression().accept(this);
}
@Override
public void visit(ResultVariable expression) {
// Make sure to traverse the select expression since
// it has a result variable assigned to it
expression.getSelectExpression().accept(this);
}
@Override
public void visit(SelectClause expression) {
expression.getSelectExpression().accept(this);
}
@Override
public void visit(SelectStatement expression) {
this.selectStatement = expression;
expression.getSelectClause().accept(this);
}
}