use of org.eclipse.persistence.internal.expressions.SQLSelectStatement in project eclipselink by eclipse-ee4j.
the class DirectMapMapping method initializeSelectionStatement.
@Override
protected void initializeSelectionStatement(AbstractSession session) {
if (this.selectionQuery.isReadAllQuery()) {
((ReadAllQuery) this.selectionQuery).addAdditionalField(getDirectField().clone());
} else {
SQLSelectStatement statement = (SQLSelectStatement) this.selectionQuery.getSQLStatement();
statement.addTable(getReferenceTable());
statement.addField(getDirectField().clone());
getContainerPolicy().addAdditionalFieldsToQuery(this.selectionQuery, getAdditionalFieldsBaseExpression(this.selectionQuery));
statement.normalize(session, null);
}
if (this.selectionQuery.isDirectReadQuery()) {
((DirectReadQuery) this.selectionQuery).setResultType(DataReadQuery.MAP);
}
}
use of org.eclipse.persistence.internal.expressions.SQLSelectStatement in project eclipselink by eclipse-ee4j.
the class DirectCollectionMapping method initializeSelectionStatement.
protected void initializeSelectionStatement(AbstractSession session) {
SQLSelectStatement statement = new SQLSelectStatement();
statement.addTable(getReferenceTable());
statement.addField(getDirectField().clone());
statement.setWhereClause(getSelectionCriteria());
statement.setOrderByExpressions(orderByExpressions);
getSelectionQuery().setSQLStatement(statement);
getContainerPolicy().addAdditionalFieldsToQuery(selectionQuery, getAdditionalFieldsBaseExpression(getSelectionQuery()));
statement.normalize(session, null);
}
use of org.eclipse.persistence.internal.expressions.SQLSelectStatement in project eclipselink by eclipse-ee4j.
the class DirectCollectionMapping method prepareNestedBatchQuery.
/**
* INTERNAL:
* Clone and prepare the selection query as a nested batch read query.
* This is used for nested batch reading.
*/
@Override
public ReadQuery prepareNestedBatchQuery(ObjectLevelReadQuery query) {
// For CR#2646-S.M. In case of inheritance the descriptor to use may not be that
// of the source query (the base class descriptor), but that of the subclass, if the
// attribute is only of the subclass. Thus in this case use the descriptor from the mapping.
// Also: for Bug 5478648 - Do not switch the descriptor if the query's descriptor is an aggregate
ClassDescriptor descriptorToUse = query.getDescriptor();
if ((descriptorToUse != this.descriptor) && (!descriptorToUse.getMappings().contains(this)) && (!this.descriptor.isDescriptorTypeAggregate())) {
descriptorToUse = this.descriptor;
}
DataReadQuery batchQuery = new DataReadQuery();
batchQuery.setName(getAttributeName());
// Join the query where clause with the mappings,
// this will cause a join that should bring in all of the target objects.
ExpressionBuilder builder;
Expression originalSelectionCriteria = null;
// 2612538 - the default size of Map (32) is appropriate
Map<Expression, Expression> clonedExpressions = new IdentityHashMap<>();
builder = new ExpressionBuilder();
// For flashback.
if (query.hasAsOfClause()) {
builder.asOf(query.getAsOfClause());
}
Expression batchSelectionCriteria = null;
// Build the batch query, either using joining, or an exist sub-select.
BatchFetchType batchType = query.getBatchFetchPolicy().getType();
if (this.batchFetchType != null) {
batchType = this.batchFetchType;
}
if (batchType == BatchFetchType.EXISTS) {
// Using a EXISTS sub-select (WHERE EXIST (<original-query> AND <mapping-join> AND <mapping-join>)
ExpressionBuilder subBuilder = new ExpressionBuilder(descriptorToUse.getJavaClass());
subBuilder.setQueryClassAndDescriptor(descriptorToUse.getJavaClass(), descriptorToUse);
ReportQuery subQuery = new ReportQuery(descriptorToUse.getJavaClass(), subBuilder);
subQuery.setDescriptor(descriptorToUse);
subQuery.setShouldRetrieveFirstPrimaryKey(true);
Expression subCriteria = subBuilder.twist(getSelectionCriteria(), builder);
if (query.getSelectionCriteria() != null) {
// For bug 2612567, any query can have batch attributes, so the
// original selection criteria can be quite complex, with multiple
// builders (i.e. for parallel selects).
// Now uses cloneUsing(newBase) instead of rebuildOn(newBase).
subCriteria = query.getSelectionCriteria().cloneUsing(subBuilder).and(subCriteria);
}
subQuery.setSelectionCriteria(subCriteria);
batchSelectionCriteria = builder.exists(subQuery);
} else if (batchType == BatchFetchType.IN) {
// Using a IN with foreign key values (WHERE FK IN :QUERY_BATCH_PARAMETER)
batchSelectionCriteria = buildBatchCriteria(builder, query);
} else {
// otherwise the original query will be corrupted.
if (query.getSelectionCriteria() != null) {
originalSelectionCriteria = query.getSelectionCriteria().copiedVersionFrom(clonedExpressions);
builder = originalSelectionCriteria.getBuilder();
}
// Using a join, (WHERE <orginal-query-criteria> AND <mapping-join>)
if (this.selectionQuery.isReadAllQuery()) {
batchSelectionCriteria = builder.twist(this.selectionQuery.getSelectionCriteria(), builder);
} else {
batchSelectionCriteria = builder.twist(this.selectionQuery.getSQLStatement().getWhereClause(), builder);
}
// For 2729729, rebuildOn is not needed as the base is still the same.
if (originalSelectionCriteria != null) {
batchSelectionCriteria = batchSelectionCriteria.and(originalSelectionCriteria);
}
if (descriptorToUse.getQueryManager().getAdditionalJoinExpression() != null) {
batchSelectionCriteria = batchSelectionCriteria.and(query.getDescriptor().getQueryManager().getAdditionalJoinExpression().rebuildOn(builder));
}
if (this.historyPolicy != null) {
if (query.getSession().getAsOfClause() != null) {
builder.asOf(query.getSession().getAsOfClause());
} else if (builder.getAsOfClause() == null) {
builder.asOf(AsOfClause.NO_CLAUSE);
}
batchSelectionCriteria = batchSelectionCriteria.and(this.historyPolicy.additionalHistoryExpression(builder, builder));
}
}
SQLSelectStatement batchStatement = new SQLSelectStatement();
for (DatabaseField keyField : getReferenceKeyFields()) {
batchStatement.addField(builder.getTable(this.referenceTable).getField(keyField));
}
batchStatement.addField(builder.getTable(this.referenceTable).getField(this.directField));
batchStatement.setWhereClause(batchSelectionCriteria);
batchQuery.setSQLStatement(batchStatement);
this.containerPolicy.addAdditionalFieldsToQuery(batchQuery, getAdditionalFieldsBaseExpression(batchQuery));
batchStatement.normalize(query.getSession(), descriptorToUse, clonedExpressions);
return batchQuery;
}
use of org.eclipse.persistence.internal.expressions.SQLSelectStatement in project eclipselink by eclipse-ee4j.
the class DirectCollectionMapping method valueFromRow.
/**
* INTERNAL:
* Return the value of the reference attribute or a value holder.
* Check whether the mapping's attribute should be optimized through batch and joining.
* Overridden to support flashback/historical queries.
*/
@Override
public Object valueFromRow(AbstractRecord row, JoinedAttributeManager joinManager, ObjectBuildingQuery sourceQuery, CacheKey cacheKey, AbstractSession session, boolean isTargetProtected, Boolean[] wasCacheUsed) throws DatabaseException {
if (this.descriptor.getCachePolicy().isProtectedIsolation()) {
if (this.isCacheable && isTargetProtected && cacheKey != null) {
// cachekey will be null when isolating to uow
// used cached collection
Object result = null;
Object cached = cacheKey.getObject();
if (cached != null) {
if (wasCacheUsed != null) {
wasCacheUsed[0] = Boolean.TRUE;
}
return this.getAttributeValueFromObject(cached);
}
return result;
} else if (!this.isCacheable && !isTargetProtected && cacheKey != null) {
return this.indirectionPolicy.buildIndirectObject(new ValueHolder<>(null));
}
}
if (row.hasSopObject()) {
return getAttributeValueFromObject(row.getSopObject());
}
if (sourceQuery.isObjectLevelReadQuery() && (((ObjectLevelReadQuery) sourceQuery).isAttributeBatchRead(this.descriptor, getAttributeName()) || (sourceQuery.isReadAllQuery() && shouldUseBatchReading()))) {
return batchedValueFromRow(row, (ObjectLevelReadQuery) sourceQuery, cacheKey);
}
if (shouldUseValueFromRowWithJoin(joinManager, sourceQuery)) {
return valueFromRowInternalWithJoin(row, joinManager, sourceQuery, cacheKey, session, isTargetProtected);
}
// if the query uses batch reading, return a special value holder
// or retrieve the object from the query property.
ReadQuery targetQuery = getSelectionQuery();
boolean extendingPessimisticLockScope = isExtendingPessimisticLockScope(sourceQuery) && extendPessimisticLockScope == ExtendPessimisticLockScope.TARGET_QUERY;
if ((getHistoryPolicy() != null) || (sourceQuery.getSession().getAsOfClause() != null) || ((sourceQuery.isObjectLevelReadQuery() && ((ObjectLevelReadQuery) sourceQuery).hasAsOfClause()) && (sourceQuery.shouldCascadeAllParts() || (sourceQuery.shouldCascadePrivateParts() && isPrivateOwned()) || (sourceQuery.shouldCascadeByMapping() && this.cascadeRefresh))) || extendingPessimisticLockScope) {
targetQuery = (ReadQuery) targetQuery.clone();
// Code copied roughly from initializeSelectionStatement.
SQLSelectStatement statement = new SQLSelectStatement();
statement.addTable(getReferenceTable());
statement.addField(getDirectField().clone());
if (isDirectMapMapping()) {
statement.addField(((DirectMapMapping) this).getDirectKeyField().clone());
}
statement.setWhereClause((Expression) getSelectionCriteria().clone());
if (sourceQuery.isObjectLevelReadQuery()) {
statement.getBuilder().asOf(((ObjectLevelReadQuery) sourceQuery).getAsOfClause());
}
if (extendingPessimisticLockScope) {
statement.setLockingClause(new ForUpdateClause(sourceQuery.getLockMode()));
}
if (getHistoryPolicy() != null) {
ExpressionBuilder builder = statement.getBuilder();
if (sourceQuery.getSession().getAsOfClause() != null) {
builder.asOf(sourceQuery.getSession().getAsOfClause());
} else if (builder.getAsOfClause() == null) {
builder.asOf(AsOfClause.NO_CLAUSE);
}
Expression temporalExpression = getHistoryPolicy().additionalHistoryExpression(builder, builder);
statement.setWhereClause(statement.getWhereClause().and(temporalExpression));
if (builder.hasAsOfClause()) {
statement.getTables().set(0, getHistoryPolicy().getHistoricalTables().get(0));
}
}
statement.normalize(sourceQuery.getSession(), null);
targetQuery.setSQLStatement(statement);
}
return getIndirectionPolicy().valueFromQuery(targetQuery, row, sourceQuery.getSession());
}
use of org.eclipse.persistence.internal.expressions.SQLSelectStatement in project eclipselink by eclipse-ee4j.
the class LOBValueWriter method buildSelectStatementForLocator.
/**
* Build the select statement for selecting the locator
*/
private SQLSelectStatement buildSelectStatementForLocator(WriteObjectQuery writeQuery, DatabaseCall call, AbstractSession session) {
SQLSelectStatement selectStatement = new SQLSelectStatement();
Vector<DatabaseTable> tables = writeQuery.getDescriptor().getTables();
selectStatement.setTables(tables);
// rather than get ALL fields from the descriptor, only use the LOB-related fields to build the minimal SELECT statement.
selectStatement.setFields(call.getContexts().getFields());
// the where clause setting here is sufficient if the object does not map to multiple tables.
selectStatement.setWhereClause(writeQuery.getDescriptor().getObjectBuilder().buildPrimaryKeyExpressionFromObject(writeQuery.getObject(), session));
// need pessimistic locking for the locator select
selectStatement.setLockingClause(ForUpdateClause.newInstance(ObjectBuildingQuery.LOCK));
if (tables.size() > 1) {
// the primary key expression from the primary table
Expression expression = selectStatement.getWhereClause();
// additional join from the non-primary tables
Expression additionalJoin = writeQuery.getDescriptor().getQueryManager().getAdditionalJoinExpression();
if (additionalJoin != null) {
expression = expression.and(additionalJoin);
}
// where clause now contains extra joins across all tables
selectStatement.setWhereClause(expression);
}
// normalize the statement at the end, such as assign alias to all tables, and build sorting statement
selectStatement.normalize(session, writeQuery.getDescriptor());
return selectStatement;
}
Aggregations