use of org.hibernate.param.ParameterSpecification in project hibernate-orm by hibernate.
the class AbstractTableBasedBulkIdHandler method processWhereClause.
/**
* Interprets the {@code WHERE} clause from the user-defined update/delete query
*
* @param whereClause The user-defined {@code WHERE} clause
*
* @return The bulk-id-ready {@code WHERE} clause representation
*/
@SuppressWarnings("unchecked")
protected ProcessedWhereClause processWhereClause(AST whereClause) {
if (whereClause.getNumberOfChildren() != 0) {
// ids that will be returned and inserted into the id table...
try {
SqlGenerator sqlGenerator = new SqlGenerator(sessionFactory);
sqlGenerator.whereClause(whereClause);
// strip the " where "
String userWhereClause = sqlGenerator.getSQL().substring(7);
List<ParameterSpecification> idSelectParameterSpecifications = sqlGenerator.getCollectedParameters();
return new ProcessedWhereClause(userWhereClause, idSelectParameterSpecifications);
} catch (RecognitionException e) {
throw new HibernateException("Unable to generate id select for DML operation", e);
}
} else {
return ProcessedWhereClause.NO_WHERE_CLAUSE;
}
}
use of org.hibernate.param.ParameterSpecification in project hibernate-orm by hibernate.
the class TableBasedDeleteHandlerImpl method execute.
@Override
public int execute(SharedSessionContractImplementor session, QueryParameters queryParameters) {
prepareForUse(targetedPersister, session);
try {
PreparedStatement ps = null;
int resultCount = 0;
try {
try {
ps = session.getJdbcCoordinator().getStatementPreparer().prepareStatement(idInsertSelect, false);
int position = 1;
position += handlePrependedParametersOnIdSelection(ps, session, position);
for (ParameterSpecification parameterSpecification : idSelectParameterSpecifications) {
position += parameterSpecification.bind(ps, queryParameters, session, position);
}
resultCount = session.getJdbcCoordinator().getResultSetReturn().executeUpdate(ps);
} finally {
if (ps != null) {
session.getJdbcCoordinator().getLogicalConnection().getResourceRegistry().release(ps);
session.getJdbcCoordinator().afterStatementExecution();
}
}
} catch (SQLException e) {
throw session.getJdbcServices().getSqlExceptionHelper().convert(e, "could not insert/select ids for bulk delete", idInsertSelect);
}
// Start performing the deletes
for (String delete : deletes) {
try {
try {
ps = session.getJdbcCoordinator().getStatementPreparer().prepareStatement(delete, false);
handleAddedParametersOnDelete(ps, session);
session.getJdbcCoordinator().getResultSetReturn().executeUpdate(ps);
} finally {
if (ps != null) {
session.getJdbcCoordinator().getLogicalConnection().getResourceRegistry().release(ps);
session.getJdbcCoordinator().afterStatementExecution();
}
}
} catch (SQLException e) {
throw session.getJdbcServices().getSqlExceptionHelper().convert(e, "error performing bulk delete", delete);
}
}
return resultCount;
} finally {
releaseFromUse(targetedPersister, session);
}
}
use of org.hibernate.param.ParameterSpecification in project hibernate-orm by hibernate.
the class TableBasedUpdateHandlerImpl method execute.
@Override
public int execute(SharedSessionContractImplementor session, QueryParameters queryParameters) {
prepareForUse(targetedPersister, session);
try {
// First, save off the pertinent ids, as the return value
PreparedStatement ps = null;
int resultCount = 0;
try {
try {
ps = session.getJdbcCoordinator().getStatementPreparer().prepareStatement(idInsertSelect, false);
int position = 1;
position += handlePrependedParametersOnIdSelection(ps, session, position);
for (ParameterSpecification parameterSpecification : idSelectParameterSpecifications) {
position += parameterSpecification.bind(ps, queryParameters, session, position);
}
resultCount = session.getJdbcCoordinator().getResultSetReturn().executeUpdate(ps);
} finally {
if (ps != null) {
session.getJdbcCoordinator().getLogicalConnection().getResourceRegistry().release(ps);
session.getJdbcCoordinator().afterStatementExecution();
}
}
} catch (SQLException e) {
throw session.getJdbcServices().getSqlExceptionHelper().convert(e, "could not insert/select ids for bulk update", idInsertSelect);
}
// Start performing the updates
for (int i = 0; i < updates.length; i++) {
if (updates[i] == null) {
continue;
}
try {
try {
ps = session.getJdbcCoordinator().getStatementPreparer().prepareStatement(updates[i], false);
if (assignmentParameterSpecifications[i] != null) {
// jdbc params are 1-based
int position = 1;
for (int x = 0; x < assignmentParameterSpecifications[i].length; x++) {
position += assignmentParameterSpecifications[i][x].bind(ps, queryParameters, session, position);
}
handleAddedParametersOnUpdate(ps, session, position);
}
session.getJdbcCoordinator().getResultSetReturn().executeUpdate(ps);
} finally {
if (ps != null) {
session.getJdbcCoordinator().getLogicalConnection().getResourceRegistry().release(ps);
session.getJdbcCoordinator().afterStatementExecution();
}
}
} catch (SQLException e) {
throw session.getJdbcServices().getSqlExceptionHelper().convert(e, "error performing bulk update", updates[i]);
}
}
return resultCount;
} finally {
releaseFromUse(targetedPersister, session);
}
}
use of org.hibernate.param.ParameterSpecification in project hibernate-orm by hibernate.
the class InLogicOperatorNode method mutateRowValueConstructorSyntaxInInListSyntax.
/**
* Mutate the subtree relating to a row-value-constructor in "in" list to instead use
* a series of ORen and ANDed predicates. This allows multi-column type comparisons
* and explicit row-value-constructor in "in" list syntax even on databases which do
* not support row-value-constructor in "in" list.
* <p/>
* For example, here we'd mutate "... where (col1, col2) in ( ('val1', 'val2'), ('val3', 'val4') ) ..." to
* "... where (col1 = 'val1' and col2 = 'val2') or (col1 = 'val3' and val2 = 'val4') ..."
*
* @param lhsColumnSpan The number of elements in the row value constructor list.
*/
private void mutateRowValueConstructorSyntaxInInListSyntax(int lhsColumnSpan, int rhsColumnSpan) {
String[] lhsElementTexts = extractMutationTexts(getLeftHandOperand(), lhsColumnSpan);
Node rhsNode = (Node) getInList().getFirstChild();
ParameterSpecification lhsEmbeddedCompositeParameterSpecification = getLeftHandOperand() == null || (!ParameterNode.class.isInstance(getLeftHandOperand())) ? null : ((ParameterNode) getLeftHandOperand()).getHqlParameterSpecification();
final boolean negated = getType() == HqlSqlTokenTypes.NOT_IN;
if (rhsNode != null && rhsNode.getNextSibling() == null) {
/**
* only one element in the vector grouping.
* <code> where (a,b) in ( (1,2) ) </code> this will be mutated to
* <code>where a=1 and b=2 </code>
*/
String[] rhsElementTexts = extractMutationTexts(rhsNode, rhsColumnSpan);
setType(negated ? HqlTokenTypes.OR : HqlSqlTokenTypes.AND);
setText(negated ? "or" : "and");
ParameterSpecification rhsEmbeddedCompositeParameterSpecification = rhsNode == null || (!ParameterNode.class.isInstance(rhsNode)) ? null : ((ParameterNode) rhsNode).getHqlParameterSpecification();
translate(lhsColumnSpan, negated ? HqlSqlTokenTypes.NE : HqlSqlTokenTypes.EQ, negated ? "<>" : "=", lhsElementTexts, rhsElementTexts, lhsEmbeddedCompositeParameterSpecification, rhsEmbeddedCompositeParameterSpecification, this);
} else {
List andElementsNodeList = new ArrayList();
while (rhsNode != null) {
String[] rhsElementTexts = extractMutationTexts(rhsNode, rhsColumnSpan);
AST group = getASTFactory().create(negated ? HqlSqlTokenTypes.OR : HqlSqlTokenTypes.AND, negated ? "or" : "and");
ParameterSpecification rhsEmbeddedCompositeParameterSpecification = rhsNode == null || (!ParameterNode.class.isInstance(rhsNode)) ? null : ((ParameterNode) rhsNode).getHqlParameterSpecification();
translate(lhsColumnSpan, negated ? HqlSqlTokenTypes.NE : HqlSqlTokenTypes.EQ, negated ? "<>" : "=", lhsElementTexts, rhsElementTexts, lhsEmbeddedCompositeParameterSpecification, rhsEmbeddedCompositeParameterSpecification, group);
andElementsNodeList.add(group);
rhsNode = (Node) rhsNode.getNextSibling();
}
setType(negated ? HqlSqlTokenTypes.AND : HqlSqlTokenTypes.OR);
setText(negated ? "and" : "or");
AST curNode = this;
for (int i = andElementsNodeList.size() - 1; i > 1; i--) {
AST group = getASTFactory().create(negated ? HqlSqlTokenTypes.AND : HqlSqlTokenTypes.OR, negated ? "and" : "or");
curNode.setFirstChild(group);
curNode = group;
AST and = (AST) andElementsNodeList.get(i);
group.setNextSibling(and);
}
AST node0 = (AST) andElementsNodeList.get(0);
AST node1 = (AST) andElementsNodeList.get(1);
node0.setNextSibling(node1);
curNode.setFirstChild(node0);
}
}
use of org.hibernate.param.ParameterSpecification in project hibernate-orm by hibernate.
the class IndexNode method resolve.
@Override
public void resolve(boolean generateJoin, boolean implicitJoin, String classAlias, AST parent, AST parentPredicate) throws SemanticException {
if (isResolved()) {
return;
}
FromReferenceNode collectionNode = (FromReferenceNode) getFirstChild();
SessionFactoryHelper sessionFactoryHelper = getSessionFactoryHelper();
// Fully resolve the map reference, create implicit joins.
collectionNode.resolveIndex(this);
Type type = collectionNode.getDataType();
if (!type.isCollectionType()) {
throw new SemanticException("The [] operator cannot be applied to type " + type.toString());
}
String collectionRole = ((CollectionType) type).getRole();
QueryableCollection queryableCollection = sessionFactoryHelper.requireQueryableCollection(collectionRole);
if (!queryableCollection.hasIndex()) {
throw new QueryException("unindexed fromElement beforeQuery []: " + collectionNode.getPath());
}
// Generate the inner join -- The elements need to be joined to the collection they are in.
FromElement fromElement = collectionNode.getFromElement();
String elementTable = fromElement.getTableAlias();
FromClause fromClause = fromElement.getFromClause();
String path = collectionNode.getPath();
FromElement elem = fromClause.findCollectionJoin(path);
if (elem == null) {
FromElementFactory factory = new FromElementFactory(fromClause, fromElement, path);
elem = factory.createCollectionElementsJoin(queryableCollection, elementTable);
LOG.debugf("No FROM element found for the elements of collection join path %s, created %s", path, elem);
} else {
LOG.debugf("FROM element found for collection join path %s", path);
}
// The 'from element' that represents the elements of the collection.
setFromElement(fromElement);
// Add the condition to the join sequence that qualifies the indexed element.
AST selector = collectionNode.getNextSibling();
if (selector == null) {
throw new QueryException("No index value!");
}
// Sometimes use the element table alias, sometimes use the... umm... collection table alias (many to many)
String collectionTableAlias = elementTable;
if (elem.getCollectionTableAlias() != null) {
collectionTableAlias = elem.getCollectionTableAlias();
}
// TODO: get SQL rendering out of here, create an AST for the join expressions.
// Use the SQL generator grammar to generate the SQL text for the index expression.
JoinSequence joinSequence = fromElement.getJoinSequence();
String[] indexCols = queryableCollection.getIndexColumnNames();
if (indexCols.length != 1) {
throw new QueryException("composite-index appears in []: " + collectionNode.getPath());
}
SqlGenerator gen = new SqlGenerator(getSessionFactoryHelper().getFactory());
try {
//TODO: used to be exprNoParens! was this needed?
gen.simpleExpr(selector);
} catch (RecognitionException e) {
throw new QueryException(e.getMessage(), e);
}
String selectorExpression = gen.getSQL();
joinSequence.addCondition(collectionTableAlias + '.' + indexCols[0] + " = " + selectorExpression);
List<ParameterSpecification> paramSpecs = gen.getCollectedParameters();
if (paramSpecs != null) {
switch(paramSpecs.size()) {
case 0:
// nothing to do
break;
case 1:
ParameterSpecification paramSpec = paramSpecs.get(0);
paramSpec.setExpectedType(queryableCollection.getIndexType());
fromElement.setIndexCollectionSelectorParamSpec(paramSpec);
break;
default:
fromElement.setIndexCollectionSelectorParamSpec(new AggregatedIndexCollectionSelectorParameterSpecifications(paramSpecs));
break;
}
}
// Now, set the text for this node. It should be the element columns.
String[] elementColumns = queryableCollection.getElementColumnNames(elementTable);
setText(elementColumns[0]);
setResolved();
}
Aggregations