public static String[][] generateColumnNames(Type[] types, SessionFactoryImplementor f) throws MappingException { String[][] columnNames = new String[types.length][]; for (int i = 0; i < types.length; i++) { int span = types[i].getColumnSpan(f); columnNames[i] = new String[span]; for (int j = 0; j < span; j++) { columnNames[i][j] = NameGenerator.scalarName(i, j); } } return columnNames; }
/** Generates the scalar column AST nodes for a given array of SQL columns */ public static void generateScalarColumns(HqlSqlWalkerNode node, String sqlColumns[], int i) { if (sqlColumns.length == 1) { generateSingleScalarColumn(node, i); } else { ASTFactory factory = node.getASTFactory(); AST n = node; n.setText(sqlColumns[0]); // Use the DOT node to emit the first column name. // Create the column names, folled by the column aliases. for (int j = 0; j < sqlColumns.length; j++) { if (j > 0) { n = ASTUtil.createSibling(factory, SqlTokenTypes.SQL_TOKEN, sqlColumns[j], n); } n = ASTUtil.createSibling( factory, SqlTokenTypes.SELECT_COLUMNS, " as " + NameGenerator.scalarName(i, j), n); } } }
public String generateAlias(String sqlExpression) { return NameGenerator.scalarName(base, counter++); }
/** WARNING: side-effecty */ private String renderScalarSelect() { boolean isSubselect = superQuery != null; StringBuffer buf = new StringBuffer(20); if (scalarTypes.size() == 0) { // ie. no select clause int size = returnedTypes.size(); for (int k = 0; k < size; k++) { scalarTypes.add(TypeFactory.manyToOne(persisters[k].getEntityName(), shallowQuery)); String[] idColumnNames = persisters[k].getIdentifierColumnNames(); for (int i = 0; i < idColumnNames.length; i++) { buf.append(returnedTypes.get(k)).append('.').append(idColumnNames[i]); if (!isSubselect) buf.append(" as ").append(NameGenerator.scalarName(k, i)); if (i != idColumnNames.length - 1 || k != size - 1) buf.append(", "); } } } else { // there _was_ a select clause Iterator iter = scalarSelectTokens.iterator(); int c = 0; boolean nolast = false; // real hacky... int parenCount = 0; // used to count the nesting of parentheses while (iter.hasNext()) { Object next = iter.next(); if (next instanceof String) { String token = (String) next; if ("(".equals(token)) { parenCount++; } else if (")".equals(token)) { parenCount--; } String lc = token.toLowerCase(); if (lc.equals(", ")) { if (nolast) { nolast = false; } else { if (!isSubselect && parenCount == 0) { int x = c++; buf.append(" as ").append(NameGenerator.scalarName(x, 0)); } } } buf.append(token); if (lc.equals("distinct") || lc.equals("all")) { buf.append(' '); } } else { nolast = true; String[] tokens = (String[]) next; for (int i = 0; i < tokens.length; i++) { buf.append(tokens[i]); if (!isSubselect) { buf.append(" as ").append(NameGenerator.scalarName(c, i)); } if (i != tokens.length - 1) buf.append(", "); } c++; } } if (!isSubselect && !nolast) { int x = c++; buf.append(" as ").append(NameGenerator.scalarName(x, 0)); } } return buf.toString(); }
private void renderSQL() throws QueryException, MappingException { final int rtsize; if (returnedTypes.size() == 0 && scalarTypes.size() == 0) { // ie no select clause in HQL returnedTypes = fromTypes; rtsize = returnedTypes.size(); } else { rtsize = returnedTypes.size(); Iterator iter = entitiesToFetch.iterator(); while (iter.hasNext()) { returnedTypes.add(iter.next()); } } int size = returnedTypes.size(); persisters = new Queryable[size]; names = new String[size]; owners = new int[size]; ownerAssociationTypes = new EntityType[size]; suffixes = new String[size]; includeInSelect = new boolean[size]; for (int i = 0; i < size; i++) { String name = (String) returnedTypes.get(i); // if ( !isName(name) ) throw new QueryException("unknown type: " + name); persisters[i] = getEntityPersisterForName(name); // TODO: cannot use generateSuffixes() - it handles the initial suffix differently. suffixes[i] = (size == 1) ? "" : Integer.toString(i) + '_'; names[i] = name; includeInSelect[i] = !entitiesToFetch.contains(name); if (includeInSelect[i]) selectLength++; if (name.equals(collectionOwnerName)) collectionOwnerColumn = i; String oneToOneOwner = (String) oneToOneOwnerNames.get(name); owners[i] = (oneToOneOwner == null) ? -1 : returnedTypes.indexOf(oneToOneOwner); ownerAssociationTypes[i] = (EntityType) uniqueKeyOwnerReferences.get(name); } if (ArrayHelper.isAllNegative(owners)) owners = null; String scalarSelect = renderScalarSelect(); // Must be done here because of side-effect! yuck... int scalarSize = scalarTypes.size(); hasScalars = scalarTypes.size() != rtsize; returnTypes = new Type[scalarSize]; for (int i = 0; i < scalarSize; i++) { returnTypes[i] = (Type) scalarTypes.get(i); } QuerySelect sql = new QuerySelect(getFactory().getDialect()); sql.setDistinct(distinct); if (!shallowQuery) { renderIdentifierSelect(sql); renderPropertiesSelect(sql); } if (collectionPersister != null) { sql.addSelectFragmentString(collectionPersister.selectFragment(fetchName, "__")); } if (hasScalars || shallowQuery) sql.addSelectFragmentString(scalarSelect); // TODO: for some dialects it would be appropriate to add the renderOrderByPropertiesSelect() to // other select strings mergeJoins(sql.getJoinFragment()); sql.setWhereTokens(whereTokens.iterator()); sql.setGroupByTokens(groupByTokens.iterator()); sql.setHavingTokens(havingTokens.iterator()); sql.setOrderByTokens(orderByTokens.iterator()); if (collectionPersister != null && collectionPersister.hasOrdering()) { sql.addOrderBy(collectionPersister.getSQLOrderByString(fetchName)); } scalarColumnNames = NameGenerator.generateColumnNames(returnTypes, getFactory()); // initialize the Set of queried identifier spaces (ie. tables) Iterator iter = collections.values().iterator(); while (iter.hasNext()) { CollectionPersister p = getCollectionPersister((String) iter.next()); addQuerySpaces(p.getCollectionSpaces()); } iter = typeMap.keySet().iterator(); while (iter.hasNext()) { Queryable p = getEntityPersisterForName((String) iter.next()); addQuerySpaces(p.getQuerySpaces()); } sqlString = sql.toQueryString(); if (holderClass != null) holderConstructor = ReflectHelper.getConstructor(holderClass, returnTypes); if (hasScalars) { actualReturnTypes = returnTypes; } else { actualReturnTypes = new Type[selectLength]; int j = 0; for (int i = 0; i < persisters.length; i++) { if (includeInSelect[i]) { actualReturnTypes[j++] = TypeFactory.manyToOne(persisters[i].getEntityName(), shallowQuery); } } } }
static void generateSingleScalarColumn(HqlSqlWalkerNode node, int i) { ASTFactory factory = node.getASTFactory(); ASTUtil.createSibling( factory, SqlTokenTypes.SELECT_COLUMNS, " as " + NameGenerator.scalarName(i, 0), node); }