OPENJPA:2099: rollback revision 1225299

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@1225348 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Pinaki Poddar 2011-12-28 21:36:25 +00:00
parent fab4535961
commit db415aa984
4 changed files with 201 additions and 206 deletions

View File

@ -74,7 +74,7 @@ public abstract class AbstractResult
private static final Joins JOINS = new NoOpJoins(); private static final Joins JOINS = new NoOpJoins();
private Map<Object,Object> _eager = null; private Map _eager = null;
private ClassMapping _base = null; private ClassMapping _base = null;
private int _index = 0; private int _index = 0;
private boolean _gotEager = false; private boolean _gotEager = false;
@ -86,14 +86,14 @@ public abstract class AbstractResult
private Object _mappedByValue = null; private Object _mappedByValue = null;
public Object getEager(FieldMapping key) { public Object getEager(FieldMapping key) {
Map<Object,Object> map = getEagerMap(true); Map map = getEagerMap(true);
return (map == null) ? null : map.get(key); return (map == null) ? null : map.get(key);
} }
public void putEager(FieldMapping key, Object res) { public void putEager(FieldMapping key, Object res) {
Map<Object,Object> map = getEagerMap(false); Map map = getEagerMap(false);
if (map == null) { if (map == null) {
map = new HashMap<Object,Object>(); map = new HashMap();
setEagerMap(map); setEagerMap(map);
} }
map.put(key, res); map.put(key, res);
@ -104,7 +104,7 @@ public abstract class AbstractResult
* *
* @param client whether the client is accessing eager information * @param client whether the client is accessing eager information
*/ */
protected Map<Object,Object> getEagerMap(boolean client) { protected Map getEagerMap(boolean client) {
if (client) if (client)
_gotEager = true; _gotEager = true;
return _eager; return _eager;
@ -113,7 +113,7 @@ public abstract class AbstractResult
/** /**
* Raw eager information. * Raw eager information.
*/ */
protected void setEagerMap(Map<Object,Object> eager) { protected void setEagerMap(Map eager) {
_eager = eager; _eager = eager;
} }
@ -129,9 +129,11 @@ public abstract class AbstractResult
/** /**
* Close all results in eager map. * Close all results in eager map.
*/ */
protected void closeEagerMap(Map<Object,Object> eager) { protected void closeEagerMap(Map eager) {
if (eager != null) { if (eager != null) {
for (Object res : eager.values()) { Object res;
for (Iterator itr = eager.values().iterator(); itr.hasNext();) {
res = itr.next();
if (res != this && res instanceof Closeable) if (res != this && res instanceof Closeable)
try { try {
((Closeable) res).close(); ((Closeable) res).close();

View File

@ -39,9 +39,9 @@ class JoinSet {
// efficient representation with O(1) lookup, add, remove operations for // efficient representation with O(1) lookup, add, remove operations for
// typical sets of joins, and it means we'd have to create a graph anyway // typical sets of joins, and it means we'd have to create a graph anyway
// when joinIterator() is called // when joinIterator() is called
private final List<Node> _graph = new ArrayList<Node>(); private final List _graph = new ArrayList();
private int _size = 0; private int _size = 0;
private List<Join> _sorted = null; private List _sorted = null;
public JoinSet() { public JoinSet() {
} }
@ -51,7 +51,7 @@ class JoinSet {
if (copy._graph.get(i) == null) if (copy._graph.get(i) == null)
_graph.add(null); _graph.add(null);
else else
_graph.add((Node) copy._graph.get(i).clone()); _graph.add(((Node) copy._graph.get(i)).clone());
} }
_size = copy._size; _size = copy._size;
_sorted = copy._sorted; _sorted = copy._sorted;
@ -95,14 +95,14 @@ class JoinSet {
/** /**
* Iterator over joins that prepares them for SQL translation. * Iterator over joins that prepares them for SQL translation.
*/ */
public Iterator<Join> joinIterator() { public Iterator joinIterator() {
if (_size < 2) if (_size < 2)
return iterator(); return iterator();
if (_sorted != null) if (_sorted != null)
return _sorted.iterator(); return _sorted.iterator();
List<Join> sorted = new ArrayList<Join>(_size); List sorted = new ArrayList(_size);
LinkedList<Node> queue = new LinkedList<Node>(); LinkedList queue = new LinkedList();
BitSet seen = new BitSet(_graph.size() * _graph.size() BitSet seen = new BitSet(_graph.size() * _graph.size()
+ _graph.size()); + _graph.size());
@ -183,8 +183,8 @@ class JoinSet {
return false; return false;
boolean added = false; boolean added = false;
for (Iterator<Join> itr = js.iterator(); itr.hasNext();) for (Iterator itr = js.iterator(); itr.hasNext();)
added = add(itr.next()) || added; added = add((Join) itr.next()) || added;
return added; return added;
} }
@ -198,7 +198,7 @@ class JoinSet {
while (_graph.size() < size) while (_graph.size() < size)
_graph.add(null); _graph.add(null);
Node node = _graph.get(join.getIndex1()); Node node = (Node) _graph.get(join.getIndex1());
if (node == null) if (node == null)
_graph.set(join.getIndex1(), new Node(join, true)); _graph.set(join.getIndex1(), new Node(join, true));
else { else {
@ -207,7 +207,7 @@ class JoinSet {
node.next = new Node(join, true); node.next = new Node(join, true);
} }
node = _graph.get(join.getIndex2()); node = (Node) _graph.get(join.getIndex2());
if (node == null) if (node == null)
_graph.set(join.getIndex2(), new Node(join, false)); _graph.set(join.getIndex2(), new Node(join, false));
else { else {
@ -218,8 +218,8 @@ class JoinSet {
_size++; _size++;
} }
public Iterator<Join> iterator() { public Iterator iterator() {
return new Iterator<Join>() { return new Iterator() {
private Node _next = null; private Node _next = null;
private int _idx = -1; private int _idx = -1;
@ -237,7 +237,7 @@ class JoinSet {
return false; return false;
} }
public Join next() { public Object next() {
if (!hasNext()) if (!hasNext())
throw new NoSuchElementException(); throw new NoSuchElementException();
Join j = _next.join; Join j = _next.join;
@ -289,16 +289,16 @@ class JoinSet {
public boolean removeAll(JoinSet js) { public boolean removeAll(JoinSet js) {
boolean remd = false; boolean remd = false;
for (Iterator<Join> itr = js.iterator(); itr.hasNext();) for (Iterator itr = js.iterator(); itr.hasNext();)
remd = remove(itr.next()) || remd; remd = remove((Join) itr.next()) || remd;
return remd; return remd;
} }
public boolean retainAll(JoinSet js) { public boolean retainAll(JoinSet js) {
boolean remd = false; boolean remd = false;
Join join; Join join;
for (Iterator<Join> itr = iterator(); itr.hasNext();) { for (Iterator itr = iterator(); itr.hasNext();) {
join = itr.next(); join = (Join) itr.next();
if (!js.contains(join)) if (!js.contains(join))
remd = remove(join); remd = remove(join);
} }
@ -318,8 +318,8 @@ class JoinSet {
public boolean containsAll(JoinSet js) { public boolean containsAll(JoinSet js) {
if (js._size > _size || js._graph.size() > _graph.size()) if (js._size > _size || js._graph.size() > _graph.size())
return false; return false;
for (Iterator<Join> itr = js.iterator(); itr.hasNext();) for (Iterator itr = js.iterator(); itr.hasNext();)
if (!contains(itr.next())) if (!contains((Join) itr.next()))
return false; return false;
return true; return true;
} }
@ -347,7 +347,7 @@ class JoinSet {
public String toString() { public String toString() {
StringBuilder buf = new StringBuilder(); StringBuilder buf = new StringBuilder();
buf.append("["); buf.append("[");
for (Iterator<Join> itr = iterator(); itr.hasNext();) { for (Iterator itr = iterator(); itr.hasNext();) {
buf.append("<").append(itr.next()).append(">"); buf.append("<").append(itr.next()).append(">");
if (itr.hasNext()) if (itr.hasNext())
buf.append(", "); buf.append(", ");

View File

@ -102,7 +102,7 @@ public interface Select
/** /**
* Return this select's subselects, or empty collection if none. * Return this select's subselects, or empty collection if none.
*/ */
public List<Select> getSubselects(); public List getSubselects();
/** /**
* Return the parent of this select, if it is a subselect. * Return the parent of this select, if it is a subselect.
@ -149,7 +149,7 @@ public interface Select
/** /**
* Return the set of all used table aliases. * Return the set of all used table aliases.
*/ */
public Collection<String> getTableAliases(); public Collection getTableAliases();
/** /**
* Return the actual {@link Val}s and {@link Column}s that were * Return the actual {@link Val}s and {@link Column}s that were
@ -157,22 +157,22 @@ public interface Select
* *
* @since 1.1.0 * @since 1.1.0
*/ */
public List<Object> getSelects(); public List getSelects();
/** /**
* Return the aliases of all selected columns and all selected buffers, * Return the aliases of all selected columns and all selected buffers,
* in the order they were selected. Each alias may be either a string * in the order they were selected. Each alias may be either a string
* or a {@link SQLBuffer}. * or a {@link SQLBuffer}.
*/ */
public List<Object> getSelectAliases(); public List getSelectAliases();
/** /**
* Get the aliases for identifier columns that can be used in COUNT * Get the aliases for identifier columns that can be used in COUNT
* selects to find the number of matches. Each alias will be a * selects to find the number of matches. Each alias will be a
* string. If no identifier columns have been nominated, then all * string. If no identifier columns have been nominated, then all
* column aliases are returned. * column alises are returned.
*/ */
public List<String> getIdentifierAliases(); public List getIdentifierAliases();
/** /**
* Return the ordering SQL for this select. * Return the ordering SQL for this select.
@ -209,7 +209,7 @@ public interface Select
/** /**
* Return the top-level {@link Join} elements for this select. * Return the top-level {@link Join} elements for this select.
*/ */
public Iterator<Join> getJoinIterator(); public Iterator getJoinIterator();
/** /**
* The result start index. * The result start index.
@ -751,22 +751,22 @@ public interface Select
/** /**
* Set joined table metadatas for polymorphic queries * Set joined table metadatas for polymorphic queries
*/ */
public void setJoinedTableClassMeta(List<ClassMapping> meta); public void setJoinedTableClassMeta(List meta);
/** /**
* get joined table metadatas for polymorphic queries * get joined table metadatas for polymorphic queries
*/ */
public List<ClassMapping> getJoinedTableClassMeta(); public List getJoinedTableClassMeta();
/** /**
* Set joined table metadatas excluded for polymorphic queries * Set joined table metadatas excluded for polymorphic queries
*/ */
public void setExcludedJoinedTableClassMeta(List<ClassMapping> meta); public void setExcludedJoinedTableClassMeta(List meta);
/** /**
* get joined table metadatas excluded for polymorphic queries * get joined table metadatas excluded for polymorphic queries
*/ */
public List<ClassMapping> getExcludedJoinedTableClassMeta(); public List getExcludedJoinedTableClassMeta();
public DBDictionary getDictionary() ; public DBDictionary getDictionary() ;
} }

View File

@ -38,6 +38,8 @@ import java.util.SortedMap;
import java.util.Stack; import java.util.Stack;
import java.util.TreeMap; import java.util.TreeMap;
import org.apache.commons.collections.iterators.EmptyIterator;
import org.apache.commons.lang.StringUtils;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration; import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.kernel.EagerFetchModes; import org.apache.openjpa.jdbc.kernel.EagerFetchModes;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration; import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
@ -115,15 +117,15 @@ public class SelectImpl
// field of type Address: // field of type Address:
// 'address.street' should map to a different table alias than // 'address.street' should map to a different table alias than
// 'parent.address.street' for the purposes of comparisons // 'parent.address.street' for the purposes of comparisons
private Map<Object,Object> _aliases = null; private Map _aliases = null;
// map of indexes to table aliases like 'TABLENAME t0' // map of indexes to table aliases like 'TABLENAME t0'
private SortedMap<Object,String> _tables = null; private SortedMap _tables = null;
// combined list of selected ids and map of each id to its alias // combined list of selected ids and map of each id to its alias
protected final Selects _selects = newSelects(); protected final Selects _selects = newSelects();
private List<Object> _ordered = null; private List _ordered = null;
private List<Object> _grouped = null; private List _grouped = null;
// flags // flags
private int _flags = 0; private int _flags = 0;
@ -145,15 +147,15 @@ public class SelectImpl
// joins to add to the end of our where clause, and joins to prepend to // joins to add to the end of our where clause, and joins to prepend to
// all selects (see select(classmapping) method) // all selects (see select(classmapping) method)
private SelectJoins _joins = null; private SelectJoins _joins = null;
private Stack<PathJoins> _preJoins = null; private Stack _preJoins = null;
// map of joins+keys to eager selects and global set of eager keys; the // map of joins+keys to eager selects and global set of eager keys; the
// same key can't be used more than once // same key can't be used more than once
private Map<Object,SelectExecutor> _eager = null; private Map _eager = null;
private Set<Object> _eagerKeys = null; private Set _eagerKeys = null;
// subselect support // subselect support
private List<Select> _subsels = null; private List<SelectImpl> _subsels = null;
private SelectImpl _parent = null; private SelectImpl _parent = null;
private String _subPath = null; private String _subPath = null;
private boolean _hasSub = false; private boolean _hasSub = false;
@ -168,8 +170,8 @@ public class SelectImpl
// A path navigation is begin with this schema alias // A path navigation is begin with this schema alias
private String _schemaAlias = null; private String _schemaAlias = null;
private ClassMapping _tpcMeta = null; private ClassMapping _tpcMeta = null;
private List<ClassMapping> _joinedTables = null; private List _joinedTables = null;
private List<ClassMapping> _exJoinedTables = null; private List _exJoinedTables = null;
public ClassMapping getTablePerClassMeta() { public ClassMapping getTablePerClassMeta() {
return _tpcMeta; return _tpcMeta;
@ -178,19 +180,19 @@ public class SelectImpl
_tpcMeta = meta; _tpcMeta = meta;
} }
public void setJoinedTableClassMeta(List<ClassMapping> meta) { public void setJoinedTableClassMeta(List meta) {
_joinedTables = meta; _joinedTables = meta;
} }
public List<ClassMapping> getJoinedTableClassMeta() { public List getJoinedTableClassMeta() {
return _joinedTables; return _joinedTables;
} }
public void setExcludedJoinedTableClassMeta(List<ClassMapping> meta) { public void setExcludedJoinedTableClassMeta(List meta) {
_exJoinedTables = meta; _exJoinedTables = meta;
} }
public List<ClassMapping> getExcludedJoinedTableClassMeta() { public List getExcludedJoinedTableClassMeta() {
return _exJoinedTables; return _exJoinedTables;
} }
@ -339,8 +341,9 @@ public class SelectImpl
public boolean hasMultipleSelects() { public boolean hasMultipleSelects() {
if (_eager == null) if (_eager == null)
return false; return false;
Map.Entry entry;
for (Map.Entry<Object,SelectExecutor> entry : _eager.entrySet()) { for (Iterator itr = _eager.entrySet().iterator(); itr.hasNext();) {
entry = (Map.Entry) itr.next();
if (entry.getValue() != this) if (entry.getValue() != this)
return true; return true;
} }
@ -440,17 +443,24 @@ public class SelectImpl
return; return;
// execute eager selects // execute eager selects
Map.Entry entry;
Result eres; Result eres;
Map<Object,Object> eager; Map eager;
for (Map.Entry<Object,SelectExecutor> entry : sel._eager.entrySet()) { for (Iterator itr = sel._eager.entrySet().iterator(); itr.hasNext();) {
entry = (Map.Entry) itr.next();
// simulated batched selects for inner/outer joins; for separate // simulated batched selects for inner/outer joins; for separate
// selects, don't pass on lock level, because they're probably // selects, don't pass on lock level, because they're probably
// for relations and therefore should use default level // for relations and therefore should use default level
eres = (entry.getValue() == sel) ? res : entry.getValue().execute(store, fetch); if (entry.getValue() == sel)
eres = res;
else
eres = ((SelectExecutor) entry.getValue()).execute(store,
fetch);
eager = res.getEagerMap(false); eager = res.getEagerMap(false);
if (eager == null) { if (eager == null) {
eager = new HashMap<Object,Object>(); eager = new HashMap();
res.setEagerMap(eager); res.setEagerMap(eager);
} }
eager.put(entry.getKey(), eres); eager.put(entry.getKey(), eres);
@ -537,10 +547,8 @@ public class SelectImpl
return 0; return 0;
} }
public List<Select> getSubselects() { public List getSubselects() {
if (_subsels == null) return (_subsels == null) ? Collections.EMPTY_LIST : _subsels;
return Collections.emptyList();
return _subsels;
} }
public Select getParent() { public Select getParent() {
@ -571,7 +579,7 @@ public class SelectImpl
_parent = (SelectImpl) parent; _parent = (SelectImpl) parent;
if (_parent != null) { if (_parent != null) {
if (_parent._subsels == null) if (_parent._subsels == null)
_parent._subsels = new ArrayList<Select>(2); _parent._subsels = new ArrayList(2);
_parent._subsels.add(this); _parent._subsels.add(this);
if (_parent._joinSyntax == JoinSyntaxes.SYNTAX_SQL92) if (_parent._joinSyntax == JoinSyntaxes.SYNTAX_SQL92)
_joinSyntax = JoinSyntaxes.SYNTAX_TRADITIONAL; _joinSyntax = JoinSyntaxes.SYNTAX_TRADITIONAL;
@ -588,7 +596,7 @@ public class SelectImpl
return _hasSub; return _hasSub;
} }
public Map<Object,Object> getAliases() { public Map getAliases() {
return _aliases; return _aliases;
} }
@ -596,7 +604,7 @@ public class SelectImpl
_aliases.remove(key); _aliases.remove(key);
} }
public Map<Object,String> getTables() { public Map getTables() {
return _tables; return _tables;
} }
@ -633,27 +641,20 @@ public class SelectImpl
return getTableIndex(table, pj, false) != -1; return getTableIndex(table, pj, false) != -1;
} }
public Collection<String> getTableAliases() { public Collection getTableAliases() {
if (_tables == null) return (_tables == null) ? Collections.EMPTY_SET : _tables.values();
return Collections.emptySet();
return _tables.values();
} }
public List<Object> getSelects() { public List getSelects() {
return Collections.unmodifiableList(_selects); return Collections.unmodifiableList(_selects);
} }
public List<Object> getSelectAliases() { public List getSelectAliases() {
return _selects.getAliases(false, _outer != null); return _selects.getAliases(false, _outer != null);
} }
public List<String> getIdentifierAliases() { public List getIdentifierAliases() {
List<String> result = new ArrayList<String>(); return _selects.getAliases(true, _outer != null);
List<Object> ids = _selects.getAliases(true, _outer != null);
for (Object id : ids) {
result.add((String)id);
}
return result;
} }
public SQLBuffer getOrdering() { public SQLBuffer getOrdering() {
@ -678,8 +679,8 @@ public class SelectImpl
// join set iterator allows concurrent modification // join set iterator allows concurrent modification
Join j; Join j;
for (Iterator<Join> itr = _joins.joins().iterator(); itr.hasNext();) { for (Iterator itr = _joins.joins().iterator(); itr.hasNext();) {
j = itr.next(); j = (Join) itr.next();
if (j.getRelationTarget() != null) { if (j.getRelationTarget() != null) {
j.getRelationTarget().getDiscriminator().addClassConditions j.getRelationTarget().getDiscriminator().addClassConditions
(this, j.getSubclasses() == SUBS_JOINABLE, (this, j.getSubclasses() == SUBS_JOINABLE,
@ -693,9 +694,9 @@ public class SelectImpl
return _joins; return _joins;
} }
public Iterator<Join> getJoinIterator() { public Iterator getJoinIterator() {
if (_joins == null || _joins.isEmpty()) if (_joins == null || _joins.isEmpty())
return new EmptyJoinIterator(); return EmptyIterator.INSTANCE;
return _joins.joins().joinIterator(); return _joins.joins().joinIterator();
} }
@ -741,9 +742,9 @@ public class SelectImpl
public String getColumnAlias(Column col, Object path) { public String getColumnAlias(Column col, Object path) {
Table table = col.getTable(); Table table = col.getTable();
String tableAlias = null; String tableAlias = null;
Iterator<Join> itr = getJoinIterator(); Iterator itr = getJoinIterator();
while (itr.hasNext()) { while (itr.hasNext()) {
Join join = itr.next(); Join join = (Join) itr.next();
if (join != null) { if (join != null) {
if (join.getTable1() == table) if (join.getTable1() == table)
tableAlias = join.getAlias1(); tableAlias = join.getAlias1();
@ -966,7 +967,7 @@ public class SelectImpl
boolean hasJoins = pj != null && pj.isDirty(); boolean hasJoins = pj != null && pj.isDirty();
if (hasJoins) { if (hasJoins) {
if (_preJoins == null) if (_preJoins == null)
_preJoins = new Stack<PathJoins>(); _preJoins = new Stack();
_preJoins.push(pj); _preJoins.push(pj);
} }
@ -1106,7 +1107,7 @@ public class SelectImpl
id = getColumnAlias(col, pj); id = getColumnAlias(col, pj);
if ((_flags & RECORD_ORDERED) != 0) { if ((_flags & RECORD_ORDERED) != 0) {
if (_ordered == null) if (_ordered == null)
_ordered = new ArrayList<Object>(5); _ordered = new ArrayList(5);
_ordered.add(id); _ordered.add(id);
} }
if (aliasOrder) { if (aliasOrder) {
@ -1230,7 +1231,7 @@ public class SelectImpl
} }
if ((_flags & RECORD_ORDERED) != 0) { if ((_flags & RECORD_ORDERED) != 0) {
if (_ordered == null) if (_ordered == null)
_ordered = new ArrayList<Object>(5); _ordered = new ArrayList(5);
_ordered.add(selAs == null ? sql : selAs); _ordered.add(selAs == null ? sql : selAs);
} }
@ -1283,10 +1284,10 @@ public class SelectImpl
* Return the indexes in the select list of all items we're ordering * Return the indexes in the select list of all items we're ordering
* by, or null if none. For use with unions. * by, or null if none. For use with unions.
*/ */
List<Integer> getOrderedIndexes() { List getOrderedIndexes() {
if (_ordered == null) if (_ordered == null)
return null; return null;
List<Integer> idxs = new ArrayList<Integer>(_ordered.size()); List idxs = new ArrayList(_ordered.size());
for (int i = 0; i < _ordered.size(); i++) for (int i = 0; i < _ordered.size(); i++)
idxs.add(_selects.indexOf(_ordered.get(i))); idxs.add(_selects.indexOf(_ordered.get(i)));
return idxs; return idxs;
@ -1354,10 +1355,13 @@ public class SelectImpl
wherePrimaryKey(oid, mapping, joins, store); wherePrimaryKey(oid, mapping, joins, store);
return; return;
} }
where(oid, mapping,
fk.getPrimaryKeyColumns(), fk.getColumns(), Column[] fromCols = fk.getColumns();
fk.getConstants(), fk.getConstantColumns(), Column[] toCols = fk.getPrimaryKeyColumns();
getJoins(joins, true), store); Column[] constCols = fk.getConstantColumns();
Object[] consts = fk.getConstants();
where(oid, mapping, toCols, fromCols, consts, constCols,
getJoins(joins, true), store);
} }
/** /**
@ -1374,39 +1378,16 @@ public class SelectImpl
return; return;
} }
SQLBuffer buf = new SQLBuffer(_dict); // only bother to pack pk values into array if app id
Object[] params = getBindParametrs(oid, mapping, toCols, fromCols, store);
bindToBuffer(buf, params, fromCols, pj);
if (constCols != null && constCols.length > 0) {
bindToBuffer(buf, vals, constCols, pj);
}
where(buf, pj);
}
/**
* Gets the values to bind in a WHERE clause for joining a relation.
*
* @param oid the identifier to be joined
* @param mapping the class mapping of the identifier
* @param toCols the target column(s)
* @param fromCols the source column(s)
* @param store the store
* @return bind parameter values in the same index order of the target columns
*/
Object[] getBindParametrs(Object oid, ClassMapping mapping, Column[] toCols, Column[] fromCols,
JDBCStore store) {
// only pack primary key values into array if application id
Object[] pks = null; Object[] pks = null;
boolean relationId = RelationStrategies.isRelationId(fromCols); boolean relationId = RelationStrategies.isRelationId(fromCols);
if (!relationId && mapping.getIdentityType() == ClassMapping.ID_APPLICATION) if (!relationId && mapping.getIdentityType() == ClassMapping.ID_APPLICATION)
pks = ApplicationIds.toPKValues(oid, mapping); pks = ApplicationIds.toPKValues(oid, mapping);
SQLBuffer buf = new SQLBuffer(_dict);
Joinable join; Joinable join;
Object val; Object val;
int count = 0; int count = 0;
Object[] vals = new Object[toCols.length];
for (int i = 0; i < toCols.length; i++, count++) { for (int i = 0; i < toCols.length; i++, count++) {
if (pks == null) { if (pks == null) {
val = (oid == null) ? null : relationId ? oid : ((Id) oid).getId(); val = (oid == null) ? null : relationId ? oid : ((Id) oid).getId();
@ -1416,19 +1397,32 @@ public class SelectImpl
val = pks[mapping.getField(join.getFieldIndex()).getPrimaryKeyIndex()]; val = pks[mapping.getField(join.getFieldIndex()).getPrimaryKeyIndex()];
val = join.getJoinValue(val, toCols[i], store); val = join.getJoinValue(val, toCols[i], store);
} }
vals[i] = val;
}
return vals;
}
void bindToBuffer(SQLBuffer buf, Object[] vals, Column[] fromCols, PathJoins pj) { if (count > 0)
for (int i = 0; i < vals.length; i++) { buf.append(" AND ");
if (i > 0) buf.append(getColumnAlias(fromCols[i], pj));
buf.append(" AND "); if (val == null)
buf.append(getColumnAlias(fromCols[i], pj)); buf.append(" IS ");
buf.append(vals[i] == null ? " IS " : " = "); else
buf.appendValue(vals[i], fromCols[i]); buf.append(" = ");
} buf.appendValue(val, fromCols[i]);
}
if (constCols != null && constCols.length > 0) {
for (int i = 0; i < constCols.length; i++, count++) {
if (count > 0)
buf.append(" AND ");
buf.append(getColumnAlias(constCols[i], pj));
if (vals[i] == null)
buf.append(" IS ");
else
buf.append(" = ");
buf.appendValue(vals[i], constCols[i]);
}
}
where(buf, pj);
} }
/** /**
@ -1544,7 +1538,7 @@ public class SelectImpl
if (_grouped == null || !_grouped.contains(sql)) { if (_grouped == null || !_grouped.contains(sql)) {
if (_grouping == null) { if (_grouping == null) {
_grouping = new SQLBuffer(_dict); _grouping = new SQLBuffer(_dict);
_grouped = new ArrayList<Object>(); _grouped = new ArrayList();
} else } else
_grouping.append(", "); _grouping.append(", ");
@ -1595,7 +1589,7 @@ public class SelectImpl
boolean pre = (pj == null || !pj.isDirty()) boolean pre = (pj == null || !pj.isDirty())
&& _preJoins != null && !_preJoins.isEmpty(); && _preJoins != null && !_preJoins.isEmpty();
if (pre) if (pre)
pj = _preJoins.peek(); pj = (PathJoins) _preJoins.peek();
if (pj == null || !pj.isDirty()) if (pj == null || !pj.isDirty())
pj = _joins; pj = _joins;
@ -1634,9 +1628,9 @@ public class SelectImpl
sel._joinSyntax = _joinSyntax; sel._joinSyntax = _joinSyntax;
sel._schemaAlias = _schemaAlias; sel._schemaAlias = _schemaAlias;
if (_aliases != null) if (_aliases != null)
sel._aliases = new HashMap<Object,Object>(_aliases); sel._aliases = new HashMap(_aliases);
if (_tables != null) if (_tables != null)
sel._tables = new TreeMap<Object,String>(_tables); sel._tables = new TreeMap(_tables);
if (_joins != null) if (_joins != null)
sel._joins = _joins.clone(sel); sel._joins = _joins.clone(sel);
if (_where != null) if (_where != null)
@ -1646,7 +1640,7 @@ public class SelectImpl
sel._from._outer = sel; sel._from._outer = sel;
} }
if (_subsels != null) { if (_subsels != null) {
sel._subsels = new ArrayList<Select>(_subsels.size()); sel._subsels = new ArrayList(_subsels.size());
SelectImpl sub, selSub; SelectImpl sub, selSub;
for (int j = 0; j < _subsels.size(); j++) { for (int j = 0; j < _subsels.size(); j++) {
sub = (SelectImpl) _subsels.get(j); sub = (SelectImpl) _subsels.get(j);
@ -1710,7 +1704,7 @@ public class SelectImpl
// global set of eager keys // global set of eager keys
if (_eagerKeys == null) if (_eagerKeys == null)
_eagerKeys = new HashSet<Object>(); _eagerKeys = new HashSet();
_eagerKeys.add(key); _eagerKeys.add(key);
SelectExecutor sel; SelectExecutor sel;
@ -1730,7 +1724,7 @@ public class SelectImpl
} }
if (_eager == null) if (_eager == null)
_eager = new HashMap<Object,SelectExecutor>(); _eager = new HashMap();
_eager.put(toEagerKey(key, getJoins(null, false)), sel); _eager.put(toEagerKey(key, getJoins(null, false)), sel);
return sel; return sel;
} }
@ -1743,8 +1737,9 @@ public class SelectImpl
sel._flags &= ~NONAUTO_DISTINCT; sel._flags &= ~NONAUTO_DISTINCT;
sel._eagerKeys = _eagerKeys; sel._eagerKeys = _eagerKeys;
if (_preJoins != null && !_preJoins.isEmpty()) { if (_preJoins != null && !_preJoins.isEmpty()) {
sel._preJoins = new Stack<PathJoins>(); sel._preJoins = new Stack();
sel._preJoins.push(((SelectJoins) _preJoins.peek()).clone(sel)); sel._preJoins.push(((SelectJoins) _preJoins.peek()).
clone(sel));
} }
return sel; return sel;
} }
@ -1752,7 +1747,7 @@ public class SelectImpl
/** /**
* Return view of eager selects. May be null. * Return view of eager selects. May be null.
*/ */
public Map<Object,SelectExecutor> getEagerMap() { public Map getEagerMap() {
return _eager; return _eager;
} }
@ -1801,8 +1796,9 @@ public class SelectImpl
if (!buf.isEmpty()) if (!buf.isEmpty())
buf.append(" AND "); buf.append(" AND ");
Join join = null; Join join = null;
for (Iterator<Join> itr = ((PathJoins) joins).joins().joinIterator(); itr.hasNext();) { for (Iterator itr = ((PathJoins) joins).joins().joinIterator();
join = itr.next(); itr.hasNext();) {
join = (Join) itr.next();
switch (_joinSyntax) { switch (_joinSyntax) {
case JoinSyntaxes.SYNTAX_TRADITIONAL: case JoinSyntaxes.SYNTAX_TRADITIONAL:
buf.append(_dict.toTraditionalJoin(join)); buf.append(_dict.toTraditionalJoin(join));
@ -1927,12 +1923,12 @@ public class SelectImpl
Join join; Join join;
Join rec; Join rec;
boolean hasJoins = _joins != null && _joins.joins() != null; boolean hasJoins = _joins != null && _joins.joins() != null;
for (Iterator<Join> itr = pj.joins().iterator(); itr.hasNext();) { for (Iterator itr = pj.joins().iterator(); itr.hasNext();) {
join = itr.next(); join = (Join) itr.next();
if (join.getType() == Join.TYPE_INNER) { if (join.getType() == Join.TYPE_INNER) {
if (!hasJoins) { if (!hasJoins)
join.setType(Join.TYPE_OUTER); join.setType(Join.TYPE_OUTER);
} else { else {
rec = _joins.joins().getRecordedJoin(join); rec = _joins.joins().getRecordedJoin(join);
if (rec == null || rec.getType() == Join.TYPE_OUTER) if (rec == null || rec.getType() == Join.TYPE_OUTER)
join.setType(Join.TYPE_OUTER); join.setType(Join.TYPE_OUTER);
@ -1960,14 +1956,15 @@ public class SelectImpl
} }
Join join; Join join;
for (Iterator<Join> itr = pj.joins().iterator(); itr.hasNext();) { for (Iterator itr = pj.joins().iterator(); itr.hasNext();) {
join = itr.next(); join = (Join) itr.next();
if (join.getType() == Join.TYPE_INNER) { if (join.getType() == Join.TYPE_INNER) {
if (join.getForeignKey() != null if (join.getForeignKey() != null
&& !_dict.canOuterJoin(_joinSyntax, join.getForeignKey())) { && !_dict.canOuterJoin(_joinSyntax, join.getForeignKey())) {
Log log = _conf.getLog(JDBCConfiguration.LOG_JDBC); Log log = _conf.getLog(JDBCConfiguration.LOG_JDBC);
if (log.isWarnEnabled()) if (log.isWarnEnabled())
log.warn(_loc.get("cant-outer-fk", join.getForeignKey())); log.warn(_loc.get("cant-outer-fk",
join.getForeignKey()));
} else } else
join.setType(Join.TYPE_OUTER); join.setType(Join.TYPE_OUTER);
} }
@ -2092,13 +2089,13 @@ public class SelectImpl
*/ */
private void recordTableAlias(Table table, Object key, Integer alias) { private void recordTableAlias(Table table, Object key, Integer alias) {
if (_aliases == null) if (_aliases == null)
_aliases = new HashMap<Object,Object>(); _aliases = new HashMap();
_aliases.put(key, alias); _aliases.put(key, alias);
String tableString = _dict.getFullName(table, false) + " " String tableString = _dict.getFullName(table, false) + " "
+ toAlias(alias.intValue()); + toAlias(alias.intValue());
if (_tables == null) if (_tables == null)
_tables = new TreeMap<Object,String>(); _tables = new TreeMap();
_tables.put(alias, tableString); _tables.put(alias, tableString);
} }
@ -2112,9 +2109,9 @@ public class SelectImpl
int aliases = (fromParent || _parent == null) ? 0 : _parent.aliasSize(false, this); int aliases = (fromParent || _parent == null) ? 0 : _parent.aliasSize(false, this);
aliases += (_aliases == null) ? 0 : _aliases.size(); aliases += (_aliases == null) ? 0 : _aliases.size();
if (_subsels != null) { if (_subsels != null) {
for (Select sub : _subsels) { for (SelectImpl sub : _subsels) {
if (sub != fromSub) if (sub != fromSub)
aliases += ((SelectImpl)sub).aliasSize(true, null); aliases += sub.aliasSize(true, null);
} }
} }
return aliases; return aliases;
@ -2254,6 +2251,10 @@ public class SelectImpl
public String toString() { public String toString() {
return _path + "|" + _key; return _path + "|" + _key;
} }
Object getKey() {
return _key;
}
} }
/** /**
@ -2268,7 +2269,7 @@ public class SelectImpl
// position in selected columns list where we expect the next load // position in selected columns list where we expect the next load
private int _pos = 0; private int _pos = 0;
private Stack<PathJoins> _preJoins = null; private Stack _preJoins = null;
/** /**
* Constructor. * Constructor.
@ -2297,28 +2298,29 @@ public class SelectImpl
// eager results // eager results
if (_sel._eager == null || !_sel._eagerKeys.contains(key)) if (_sel._eager == null || !_sel._eagerKeys.contains(key))
return null; return null;
Map<Object,Object> map = SelectResult.this.getEagerMap(true); Map map = SelectResult.this.getEagerMap(true);
if (map == null) if (map == null)
return null; return null;
return map.get(SelectImpl.toEagerKey(key, getJoins(null))); return map.get(_sel.toEagerKey(key, getJoins(null)));
} }
public void putEager(FieldMapping key, Object res) { public void putEager(FieldMapping key, Object res) {
Map<Object,Object> map = SelectResult.this.getEagerMap(true); Map map = SelectResult.this.getEagerMap(true);
if (map == null) { if (map == null) {
map = new HashMap<Object,Object>(); map = new HashMap();
setEagerMap(map); setEagerMap(map);
} }
map.put(SelectImpl.toEagerKey(key, getJoins(null)), res); map.put(_sel.toEagerKey(key, getJoins(null)), res);
} }
public Object load(ClassMapping mapping, JDBCStore store, public Object load(ClassMapping mapping, JDBCStore store,
JDBCFetchConfiguration fetch, PathJoins joins) JDBCFetchConfiguration fetch, Joins joins)
throws SQLException { throws SQLException {
boolean hasJoins = joins != null && joins.path() != null; boolean hasJoins = joins != null
&& ((PathJoins) joins).path() != null;
if (hasJoins) { if (hasJoins) {
if (_preJoins == null) if (_preJoins == null)
_preJoins = new Stack<PathJoins>(); _preJoins = new Stack();
_preJoins.push(joins); _preJoins.push(joins);
} }
@ -2469,9 +2471,9 @@ public class SelectImpl
*/ */
private PathJoins getPreJoins() { private PathJoins getPreJoins() {
if (_preJoins != null && !_preJoins.isEmpty()) if (_preJoins != null && !_preJoins.isEmpty())
return _preJoins.peek(); return (PathJoins) _preJoins.peek();
if (_sel._preJoins != null && !_sel._preJoins.isEmpty()) if (_sel._preJoins != null && !_sel._preJoins.isEmpty())
return _sel._preJoins.peek(); return (PathJoins) _sel._preJoins.peek();
return null; return null;
} }
@ -2482,14 +2484,15 @@ public class SelectImpl
private String getColumnAlias(Column col, PathJoins pj) { private String getColumnAlias(Column col, PathJoins pj) {
String alias; String alias;
if (_sel._from != null) { if (_sel._from != null) {
alias = SelectImpl.toAlias(_sel._from.getTableIndex(col.getTable(), pj, false)); alias = _sel.toAlias(_sel._from.getTableIndex
(col.getTable(), pj, false));
if (alias == null) if (alias == null)
return null; return null;
if (_sel._dict.requiresAliasForSubselect) if (_sel._dict.requiresAliasForSubselect)
return FROM_SELECT_ALIAS + "." + alias + "_" + col; return FROM_SELECT_ALIAS + "." + alias + "_" + col;
return alias + "_" + col; return alias + "_" + col;
} }
alias = SelectImpl.toAlias(_sel.getTableIndex(col.getTable(), pj, false)); alias = _sel.toAlias(_sel.getTableIndex(col.getTable(), pj, false));
return (alias == null) ? null : alias + "." + col; return (alias == null) ? null : alias + "." + col;
} }
@ -2633,6 +2636,10 @@ public class SelectImpl
return this; return this;
} }
public String getVariable() {
return var;
}
public Joins setCorrelatedVariable(String var) { public Joins setCorrelatedVariable(String var) {
this.correlatedVar = var; this.correlatedVar = var;
return this; return this;
@ -2945,8 +2952,8 @@ public class SelectImpl
return; return;
Join j = null; Join j = null;
List<Join> removed = new ArrayList<Join>(5); List<Join> removed = new ArrayList<Join>(5);
for (Iterator<Join> itr = _joins.iterator(); itr.hasNext();) { for (Iterator itr = _joins.iterator(); itr.hasNext();) {
j = itr.next(); j = (Join) itr.next();
if (j.isNotMyJoin()) { if (j.isNotMyJoin()) {
addJoinsToParent(_sel._parent, j); addJoinsToParent(_sel._parent, j);
removed.add(j); removed.add(j);
@ -3015,12 +3022,12 @@ public class SelectImpl
* the alias of each selected id. * the alias of each selected id.
*/ */
protected static class Selects protected static class Selects
extends AbstractList<Object> { extends AbstractList {
protected List<Object> _ids = null; protected List _ids = null;
protected List<Object> _idents = null; protected List _idents = null;
protected Map<Object,Object> _aliases = null; protected Map _aliases = null;
protected Map<Object,String> _selectAs = null; protected Map _selectAs = null;
protected DBDictionary _dict = null; protected DBDictionary _dict = null;
/** /**
@ -3028,22 +3035,22 @@ public class SelectImpl
*/ */
public void addAll(Selects sels) { public void addAll(Selects sels) {
if (_ids == null && sels._ids != null) if (_ids == null && sels._ids != null)
_ids = new ArrayList<Object>(sels._ids); _ids = new ArrayList(sels._ids);
else if (sels._ids != null) else if (sels._ids != null)
_ids.addAll(sels._ids); _ids.addAll(sels._ids);
if (_idents == null && sels._idents != null) if (_idents == null && sels._idents != null)
_idents = new ArrayList<Object>(sels._idents); _idents = new ArrayList(sels._idents);
else if (sels._idents != null) else if (sels._idents != null)
_idents.addAll(sels._idents); _idents.addAll(sels._idents);
if (_aliases == null && sels._aliases != null) if (_aliases == null && sels._aliases != null)
_aliases = new HashMap<Object,Object>(sels._aliases); _aliases = new HashMap(sels._aliases);
else if (sels._aliases != null) else if (sels._aliases != null)
_aliases.putAll(sels._aliases); _aliases.putAll(sels._aliases);
if (_selectAs == null && sels._selectAs != null) if (_selectAs == null && sels._selectAs != null)
_selectAs = new HashMap<Object,String>(sels._selectAs); _selectAs = new HashMap(sels._selectAs);
else if (sels._selectAs != null) else if (sels._selectAs != null)
_selectAs.putAll(sels._selectAs); _selectAs.putAll(sels._selectAs);
} }
@ -3060,8 +3067,8 @@ public class SelectImpl
*/ */
public int setAlias(Object id, Object alias, boolean ident) { public int setAlias(Object id, Object alias, boolean ident) {
if (_ids == null) { if (_ids == null) {
_ids = new ArrayList<Object>(); _ids = new ArrayList();
_aliases = new HashMap<Object,Object>(); _aliases = new HashMap();
} }
int idx; int idx;
@ -3073,7 +3080,7 @@ public class SelectImpl
if (ident) { if (ident) {
if (_idents == null) if (_idents == null)
_idents = new ArrayList<Object>(3); _idents = new ArrayList(3);
_idents.add(id); _idents.add(id);
} }
} }
@ -3116,17 +3123,19 @@ public class SelectImpl
* A list representation of the aliases, in select order, with * A list representation of the aliases, in select order, with
* AS aliases present. * AS aliases present.
*/ */
public List<Object> getAliases(final boolean ident, final boolean inner) { public List getAliases(final boolean ident, final boolean inner) {
if (_ids == null) if (_ids == null)
return Collections.emptyList(); return Collections.EMPTY_LIST;
return new AbstractList<Object>() { return new AbstractList() {
public int size() { public int size() {
return (ident && _idents != null) ? _idents.size() : _ids.size(); return (ident && _idents != null) ? _idents.size()
: _ids.size();
} }
public Object get(int i) { public Object get(int i) {
Object id = (ident && _idents != null) ? _idents.get(i) : _ids.get(i); Object id = (ident && _idents != null) ? _idents.get(i)
: _ids.get(i);
Object alias = _aliases.get(id); Object alias = _aliases.get(id);
if (id instanceof Column && ((Column) id).isXML()) if (id instanceof Column && ((Column) id).isXML())
alias = alias + _dict.getStringVal; alias = alias + _dict.getStringVal;
@ -3144,7 +3153,8 @@ public class SelectImpl
if (ident && _idents != null) if (ident && _idents != null)
return as; return as;
if (alias instanceof SQLBuffer) if (alias instanceof SQLBuffer)
alias = new SQLBuffer((SQLBuffer) alias).append(" AS ").append(as); alias = new SQLBuffer((SQLBuffer) alias).
append(" AS ").append(as);
else else
alias = alias + " AS " + as; alias = alias + " AS " + as;
} }
@ -3158,7 +3168,7 @@ public class SelectImpl
*/ */
public void setSelectAs(Object id, String as) { public void setSelectAs(Object id, String as) {
if (_selectAs == null) if (_selectAs == null)
_selectAs = new HashMap<Object,String>((int) (5 * 1.33 + 1)); _selectAs = new HashMap((int) (5 * 1.33 + 1));
_selectAs.put(id, as); _selectAs.put(id, as);
} }
@ -3170,7 +3180,7 @@ public class SelectImpl
return; return;
Object id; Object id;
for (Iterator<Object> itr = _ids.iterator(); itr.hasNext();) { for (Iterator itr = _ids.iterator(); itr.hasNext();) {
id = itr.next(); id = itr.next();
if (id instanceof Placeholder) { if (id instanceof Placeholder) {
itr.remove(); itr.remove();
@ -3221,23 +3231,6 @@ public class SelectImpl
} }
} }
class EmptyJoinIterator implements Iterator<Join> {
@Override
public boolean hasNext() {
return false;
}
@Override
public Join next() {
return null;
}
@Override
public void remove() {
}
}
/** /**
* Common joins interface used internally. Cannot be made an inner class * Common joins interface used internally. Cannot be made an inner class
* because the outer class (Select) has to implement it. * because the outer class (Select) has to implement it.