protected ResultObjectProvider executeQuery(Executor ex,
ClassMetaData base,
ClassMetaData[] metas,
boolean subclasses,
ExpressionFactory[] facts,
QueryExpressions[] exps,
Object[] params,
Range range) {
if (metas.length > 1 && exps[0].isAggregate())
throw new UserException(Localizer.forPackage(JDBCStoreQuery.class).
get("mult-mapping-aggregate", Arrays.asList(metas)));
ClassMapping[] mappings = (ClassMapping[]) metas;
JDBCFetchConfiguration fetch = (JDBCFetchConfiguration)
ctx.getFetchConfiguration();
if (exps[0].fetchPaths != null) {
fetch.addFields(Arrays.asList(exps[0].fetchPaths));
fetch.addJoins(Arrays.asList(exps[0].fetchPaths));
}
if (exps[0].fetchInnerPaths != null)
fetch.addFetchInnerJoins(Arrays.asList(exps[0].fetchInnerPaths));
int eager = calculateEagerMode(exps[0], range.start, range.end);
int subclassMode = fetch.getSubclassFetchMode((ClassMapping) base);
DBDictionary dict = _store.getDBDictionary();
long start = (mappings.length == 1 && dict.supportsSelectStartIndex)
? range.start : 0L;
long end = (dict.supportsSelectEndIndex) ? range.end : Long.MAX_VALUE;
QueryExpressionsState[] states = new QueryExpressionsState[exps.length];
for (int i = 0; i < states.length; i++)
states[i] = new QueryExpressionsState();
ExpContext ctx = new ExpContext(_store, params, fetch);
// add selects with populate WHERE conditions to list
List sels = new ArrayList(mappings.length);
List selMappings = new ArrayList(mappings.length);
BitSet subclassBits = new BitSet();
BitSet nextBits = new BitSet();
boolean unionable = createWhereSelects(sels, mappings, selMappings,
subclasses, subclassBits, nextBits, facts, exps, states, ctx,
subclassMode)
&& subclassMode == JDBCFetchConfiguration.EAGER_JOIN
&& start == 0
&& end == Long.MAX_VALUE;
// we might want to use lrs settings if we can't use the range
if (sels.size() > 1)
start = 0L;
boolean lrs = range.lrs || (fetch.getFetchBatchSize() >= 0
&& (start != range.start || end != range.end));
ResultObjectProvider[] rops = null;
ResultObjectProvider rop = null;
if (unionable) {
Union union = _store.getSQLFactory().newUnion(
(Select[]) sels.toArray(new Select[sels.size()]));
BitSet[] paged = populateUnion(union, mappings, subclasses, facts,
exps, states, ctx, lrs, eager, start, end);
union.setLRS(lrs);
rop = executeUnion(union, mappings, exps, states, ctx, paged);
} else {
if (sels.size() > 1)
rops = new ResultObjectProvider[sels.size()];
Select sel;
BitSet paged;
for (int i = 0, idx = 0; i < sels.size(); i++) {
sel = (Select) sels.get(i);
paged = populateSelect(sel, (ClassMapping) selMappings.get(i),
subclassBits.get(i), (JDBCExpressionFactory) facts[idx],
exps[idx], states[idx], ctx, lrs, eager, start, end);
rop = executeSelect(sel, (ClassMapping) selMappings.get(i),
exps[idx], states[idx], ctx, paged, start, end);
if (rops != null)
rops[i] = rop;
if (nextBits.get(i))
idx++;
}
}
if (rops != null) {
if (exps[0].ascending.length == 0)
rop = new MergedResultObjectProvider(rops);
else {
rop = new OrderingMergedResultObjectProvider(rops,
exps[0].ascending, ex, this, params);
}
}
// need to fake result range?
if ((rops != null && range.end != Long.MAX_VALUE)
|| start != range.start || end != range.end)
rop = new RangeResultObjectProvider(rop, range.start, range.end);
return rop;
}
|
protected String[] getDataStoreActions(ClassMetaData base,
ClassMetaData[] metas,
boolean subclasses,
ExpressionFactory[] facts,
QueryExpressions[] exps,
Object[] params,
Range range) {
ClassMapping[] mappings = (ClassMapping[]) metas;
JDBCFetchConfiguration fetch = (JDBCFetchConfiguration) ctx.
getFetchConfiguration();
if (exps[0].fetchPaths != null) {
fetch.addFields(Arrays.asList(exps[0].fetchPaths));
fetch.addJoins(Arrays.asList(exps[0].fetchPaths));
}
if (exps[0].fetchInnerPaths != null)
fetch.addFetchInnerJoins(Arrays.asList(exps[0].fetchInnerPaths));
int eager = calculateEagerMode(exps[0], range.start, range.end);
eager = Math.min(eager, JDBCFetchConfiguration.EAGER_JOIN);
int subclassMode = fetch.getSubclassFetchMode((ClassMapping) base);
DBDictionary dict = _store.getDBDictionary();
long start = (mappings.length == 1 && dict.supportsSelectStartIndex)
? range.start : 0L;
long end = (dict.supportsSelectEndIndex) ? range.end : Long.MAX_VALUE;
QueryExpressionsState[] states = new QueryExpressionsState[exps.length];
for (int i = 0; i < states.length; i++)
states[i] = new QueryExpressionsState();
ExpContext ctx = new ExpContext(_store, params, fetch);
// add selects with populate WHERE conditions to list
List sels = new ArrayList(mappings.length);
List selMappings = new ArrayList(mappings.length);
BitSet subclassBits = new BitSet();
BitSet nextBits = new BitSet();
boolean unionable = createWhereSelects(sels, mappings, selMappings,
subclasses, subclassBits, nextBits, facts, exps, states, ctx,
subclassMode) && subclassMode == JDBCFetchConfiguration.EAGER_JOIN;
if (sels.size() > 1)
start = 0L;
if (unionable) {
Union union = _store.getSQLFactory().newUnion(
(Select[]) sels.toArray(new Select[sels.size()]));
populateUnion(union, mappings, subclasses, facts, exps, states, ctx,
false, eager, start, end);
if (union.isUnion())
return new String[] {union.toSelect(false, fetch).getSQL(true)};
sels = Arrays.asList(union.getSelects());
} else {
Select sel;
for (int i = 0, idx = 0; i < sels.size(); i++) {
sel = (Select) sels.get(i);
populateSelect(sel, (ClassMapping) selMappings.get(i),
subclassBits.get(i), (JDBCExpressionFactory) facts[idx],
exps[idx], states[idx], ctx, false, eager, start, end);
if (nextBits.get(i))
idx++;
}
}
String[] sql = new String[sels.size()];
for (int i = 0; i < sels.size(); i++)
sql[i] = ((Select) sels.get(i)).toSelect(false, fetch).getSQL(true);
return sql;
}
|