use of org.hibernate.hql.internal.ast.util.ASTPrinter in project hibernate-orm by hibernate.
the class ASTIteratorTest method testSimpleTree.
@Test
public void testSimpleTree() throws Exception {
String input = "select foo from foo in class org.hibernate.test.Foo, fee in class org.hibernate.test.Fee where foo.dependent = fee order by foo.string desc, foo.component.count asc, fee.id";
HqlParser parser = HqlParser.getInstance(input);
parser.statement();
AST ast = parser.getAST();
ASTPrinter printer = new ASTPrinter(HqlTokenTypes.class);
printer.showAst(ast, new PrintWriter(System.out));
ASTIterator iterator = new ASTIterator(ast);
int count = 0;
while (iterator.hasNext()) {
assertTrue(iterator.next() instanceof AST);
count++;
}
assertEquals(43, count);
UnsupportedOperationException uoe = null;
try {
iterator.remove();
} catch (UnsupportedOperationException e) {
uoe = e;
}
assertNotNull(uoe);
}
use of org.hibernate.hql.internal.ast.util.ASTPrinter in project hibernate-orm by hibernate.
the class SelectExpressionList method collectSelectExpressions.
/**
* Returns an array of SelectExpressions gathered from the children of the given parent AST node.
*
* @return an array of SelectExpressions gathered from the children of the given parent AST node.
*/
public SelectExpression[] collectSelectExpressions() {
// Get the first child to be considered. Sub-classes may do this differently in order to skip nodes that
// are not select expressions (e.g. DISTINCT).
AST firstChild = getFirstSelectExpression();
ArrayList<SelectExpression> list = new ArrayList<SelectExpression>();
int p = 0;
for (AST n = firstChild; n != null; n = n.getNextSibling()) {
if (n instanceof SelectExpression) {
list.add((SelectExpression) n);
} else if (n instanceof ParameterNode) {
parameterPositions.add(p);
} else {
throw new IllegalStateException("Unexpected AST: " + n.getClass().getName() + " " + new ASTPrinter(SqlTokenTypes.class).showAsString(n, ""));
}
p++;
}
return list.toArray(new SelectExpression[list.size()]);
}
use of org.hibernate.hql.internal.ast.util.ASTPrinter in project hibernate-orm by hibernate.
the class OrderByFragmentTranslator method translate.
/**
* Perform the translation of the user-supplied fragment, returning the translation.
* <p/>
* The important distinction to this split between (1) translating and (2) resolving aliases is that
* both happen at different times
*
* @param context Context giving access to delegates needed during translation.
* @param fragment The user-supplied order-by fragment
*
* @return The translation.
*/
public static OrderByTranslation translate(TranslationContext context, String fragment) {
LOG.tracef("Beginning parsing of order-by fragment : " + fragment);
GeneratedOrderByLexer lexer = new GeneratedOrderByLexer(new StringReader(fragment));
// Perform the parsing (and some analysis/resolution). Another important aspect is the collection
// of "column references" which are important later to seek out replacement points in the
// translated fragment.
OrderByFragmentParser parser = new OrderByFragmentParser(lexer, context);
try {
parser.orderByFragment();
} catch (HibernateException e) {
throw e;
} catch (Throwable t) {
throw new HibernateException("Unable to parse order-by fragment", t);
}
if (LOG.isTraceEnabled()) {
ASTPrinter printer = new ASTPrinter(OrderByTemplateTokenTypes.class);
LOG.trace(printer.showAsString(parser.getAST(), "--- {order-by fragment} ---"));
}
// Render the parsed tree to text.
OrderByFragmentRenderer renderer = new OrderByFragmentRenderer(context.getSessionFactory());
try {
renderer.orderByFragment(parser.getAST());
} catch (HibernateException e) {
throw e;
} catch (Throwable t) {
throw new HibernateException("Unable to render parsed order-by fragment", t);
}
return new StandardOrderByTranslationImpl(renderer.getRenderedFragment(), parser.getColumnReferences());
}
use of org.hibernate.hql.internal.ast.util.ASTPrinter in project hibernate-orm by hibernate.
the class SelectClause method initializeExplicitSelectClause.
/**
* Prepares an explicitly defined select clause.
*
* @param fromClause The from clause linked to this select clause.
*
* @throws SemanticException indicates a semntic issue with the explicit select clause.
*/
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();
// we only support parameters in select in the case of INSERT...SELECT statements
if (getParameterPositions().size() > 0 && getWalker().getStatementType() != HqlSqlTokenTypes.INSERT) {
throw new QueryException("Parameters are only supported in SELECT clauses when used as part of a INSERT INTO DML statement");
}
for (SelectExpression selectExpression : selectExpressions) {
if (AggregatedSelectExpression.class.isInstance(selectExpression)) {
aggregatedSelectExpression = (AggregatedSelectExpression) selectExpression;
queryReturnTypeList.addAll(aggregatedSelectExpression.getAggregatedSelectionTypeList());
scalarSelect = true;
} else {
// we have no choice but to do this check here
// this is not very elegant but the "right way" would most likely involve a bigger rewrite so as to
// treat ParameterNodes in select clauses as SelectExpressions
boolean inSubquery = selectExpression instanceof QueryNode && ((QueryNode) selectExpression).getFromClause().getParentFromClause() != null;
if (getWalker().getStatementType() == HqlSqlTokenTypes.INSERT && inSubquery) {
// we do not support parameters for subqueries in INSERT...SELECT
if (((QueryNode) selectExpression).getSelectClause().getParameterPositions().size() > 0) {
throw new QueryException("Use of parameters in subqueries of INSERT INTO DML statements is not supported.");
}
}
Type type = selectExpression.getDataType();
if (type == null) {
throw new QueryException("No data type for node: " + selectExpression.getClass().getName() + " " + new ASTPrinter(SqlTokenTypes.class).showAsString((AST) selectExpression, ""));
}
// If the data type is not an association type, it could not have been in the FROM clause.
if (selectExpression.isScalar()) {
scalarSelect = true;
}
if (isReturnableEntity(selectExpression)) {
fromElementsForLoad.add(selectExpression.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();
// Get ready to start adding nodes.
ASTAppender appender = new ASTAppender(getASTFactory(), this);
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) {
// 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) && // work around that fetch joins of element collections where their parent instead of the root is selected
(!fromElement.isCollectionJoin() || !fromElementsForLoad.contains(fromElement.getFetchOrigin()))) {
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);
alreadyRenderedIdentifiers.add(text);
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().
renderNonScalarSelects(collectSelectExpressions(), fromClause);
}
if (scalarSelect || getWalker().isShallowQuery()) {
// If there are any scalars (non-entities) selected, render the select column aliases.
renderScalarSelects(selectExpressions, fromClause);
}
finishInitialization(/*sqlResultTypeList,*/
queryReturnTypeList);
}
Aggregations