📄 selectclause.java
字号:
// $Id: SelectClause.java 10528 2006-09-25 15:14:10Z epbernard $
package org.hibernate.hql.ast.tree;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.hibernate.hql.antlr.SqlTokenTypes;
import org.hibernate.hql.ast.util.ASTAppender;
import org.hibernate.hql.ast.util.ASTIterator;
import org.hibernate.hql.ast.util.ASTPrinter;
import org.hibernate.hql.ast.QuerySyntaxException;
import org.hibernate.type.Type;
import org.hibernate.QueryException;
import antlr.SemanticException;
import antlr.collections.AST;
/**
* Represents the list of expressions in a SELECT clause.
*
* @author josh Sep 21, 2004 7:53:55 AM
*/
public class SelectClause extends SelectExpressionList {
private boolean prepared = false;
private boolean scalarSelect;
private List fromElementsForLoad = new ArrayList();
//private Type[] sqlResultTypes;
private Type[] queryReturnTypes;
private String[][] columnNames;
private ConstructorNode constructorNode;
private List collectionFromElements;
private String[] aliases;
/**
* Does this SelectClause represent a scalar query
*
* @return True if this is a scalara select clause; false otherwise.
*/
public boolean isScalarSelect() {
return scalarSelect;
}
public boolean isDistinct() {
return getFirstChild() != null && getFirstChild().getType() == SqlTokenTypes.DISTINCT;
}
/**
* FromElements which need to be accounted for in the load phase (either for return or for fetch).
*
* @return List of appropriate FromElements.
*/
public List getFromElementsForLoad() {
return fromElementsForLoad;
}
/*
* The types represented in the SQL result set.
*
* @return The types represented in the SQL result set.
*/
/*public Type[] getSqlResultTypes() {
return sqlResultTypes;
}*/
/**
* The types actually being returned from this query at the "object level".
*
* @return The query return types.
*/
public Type[] getQueryReturnTypes() {
return queryReturnTypes;
}
/**
* The HQL aliases, or generated aliases
*/
public String[] getQueryReturnAliases() {
return aliases;
}
/**
* The column alias names being used in the generated SQL.
*
* @return The SQL column aliases.
*/
public String[][] getColumnNames() {
return columnNames;
}
/**
* The constructor to use for dynamic instantiation queries.
*
* @return The appropriate Constructor reference, or null if not a
* dynamic instantiation query.
*/
public Constructor getConstructor() {
return constructorNode == null ? null : constructorNode.getConstructor();
}
public boolean isMap() {
return constructorNode == null ? false : constructorNode.isMap();
}
public boolean isList() {
return constructorNode == null ? false : constructorNode.isList();
}
/**
* Prepares an explicitly defined select clause.
*
* @param fromClause The from clause linked to this select clause.
* @throws SemanticException
*/
public void initializeExplicitSelectClause(FromClause fromClause) throws SemanticException {
if ( prepared ) {
throw new IllegalStateException( "SelectClause was already prepared!" );
}
//explicit = true; // This is an explict Select.
//ArrayList sqlResultTypeList = new ArrayList();
ArrayList queryReturnTypeList = new ArrayList();
// First, collect all of the select expressions.
// NOTE: This must be done *before* invoking setScalarColumnText() because setScalarColumnText()
// changes the AST!!!
SelectExpression[] selectExpressions = collectSelectExpressions();
for ( int i = 0; i < selectExpressions.length; i++ ) {
SelectExpression expr = selectExpressions[i];
if ( expr.isConstructor() ) {
constructorNode = ( ConstructorNode ) expr;
List constructorArgumentTypeList = constructorNode.getConstructorArgumentTypeList();
//sqlResultTypeList.addAll( constructorArgumentTypeList );
queryReturnTypeList.addAll( constructorArgumentTypeList );
scalarSelect = true;
}
else {
Type type = expr.getDataType();
if ( type == null ) {
throw new IllegalStateException( "No data type for node: " + expr.getClass().getName() + " "
+ new ASTPrinter( SqlTokenTypes.class ).showAsString( ( AST ) expr, "" ) );
}
//sqlResultTypeList.add( type );
// If the data type is not an association type, it could not have been in the FROM clause.
if ( expr.isScalar() ) {
scalarSelect = true;
}
if ( isReturnableEntity( expr ) ) {
fromElementsForLoad.add( expr.getFromElement() );
}
// Always add the type to the return type list.
queryReturnTypeList.add( type );
}
}
//init the aliases, after initing the constructornode
initAliases(selectExpressions);
if ( !getWalker().isShallowQuery() ) {
// add the fetched entities
List fromElements = fromClause.getProjectionList();
ASTAppender appender = new ASTAppender( getASTFactory(), this ); // Get ready to start adding nodes.
int size = fromElements.size();
Iterator iterator = fromElements.iterator();
for ( int k = 0; iterator.hasNext(); k++ ) {
FromElement fromElement = ( FromElement ) iterator.next();
if ( fromElement.isFetch() ) {
FromElement origin = null;
if ( fromElement.getRealOrigin() == null ) {
// work around that crazy issue where the tree contains
// "empty" FromElements (no text); afaict, this is caused
// by FromElementFactory.createCollectionJoin()
if ( fromElement.getOrigin() == null ) {
throw new QueryException( "Unable to determine origin of join fetch [" + fromElement.getDisplayText() + "]" );
}
else {
origin = fromElement.getOrigin();
}
}
else {
origin = fromElement.getRealOrigin();
}
if ( !fromElementsForLoad.contains( origin ) ) {
throw new QueryException(
"query specified join fetching, but the owner " +
"of the fetched association was not present in the select list " +
"[" + fromElement.getDisplayText() + "]"
);
}
Type type = fromElement.getSelectType();
addCollectionFromElement( fromElement );
if ( type != null ) {
boolean collectionOfElements = fromElement.isCollectionOfValuesOrComponents();
if ( !collectionOfElements ) {
// Add the type to the list of returned sqlResultTypes.
fromElement.setIncludeSubclasses( true );
fromElementsForLoad.add( fromElement );
//sqlResultTypeList.add( type );
// Generate the select expression.
String text = fromElement.renderIdentifierSelect( size, k );
SelectExpressionImpl generatedExpr = ( SelectExpressionImpl ) appender.append( SqlTokenTypes.SELECT_EXPR, text, false );
if ( generatedExpr != null ) {
generatedExpr.setFromElement( fromElement );
}
}
}
}
}
// generate id select fragment and then property select fragment for
// each expression, just like generateSelectFragments().
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -