HHH-16392 Add column qualifier support to Dialect
This commit is contained in:
parent
094f243413
commit
792a355865
|
@ -24,6 +24,7 @@ import org.hibernate.boot.model.FunctionContributions;
|
|||
import org.hibernate.boot.model.TypeContributions;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.dialect.BooleanDecoder;
|
||||
import org.hibernate.dialect.DmlTargetColumnQualifierSupport;
|
||||
import org.hibernate.dialect.DatabaseVersion;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.dialect.OracleBooleanJdbcType;
|
||||
|
@ -96,7 +97,6 @@ import org.hibernate.type.SqlTypes;
|
|||
import org.hibernate.type.StandardBasicTypes;
|
||||
import org.hibernate.type.descriptor.java.PrimitiveByteArrayJavaType;
|
||||
import org.hibernate.type.descriptor.jdbc.AggregateJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.ArrayJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.BlobJdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.OracleJsonBlobJdbcType;
|
||||
|
@ -1443,4 +1443,9 @@ public class OracleLegacyDialect extends Dialect {
|
|||
public String rowId(String rowId) {
|
||||
return "rowid";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DmlTargetColumnQualifierSupport getDmlTargetColumnQualifierSupport() {
|
||||
return DmlTargetColumnQualifierSupport.TABLE_ALIAS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -514,14 +514,6 @@ public class OracleLegacySqlAstTranslator<T extends JdbcOperation> extends Abstr
|
|||
return getDialect().supportsFetchClause( FetchClauseType.ROWS_ONLY );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean renderNamedTableReference(NamedTableReference tableReference, LockMode lockMode) {
|
||||
appendSql( tableReference.getTableExpression() );
|
||||
registerAffectedTable( tableReference );
|
||||
renderTableReferenceIdentificationVariable( tableReference );
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void visitSetAssignment(Assignment assignment) {
|
||||
final List<ColumnReference> columnReferences = assignment.getAssignable().getColumnReferences();
|
||||
|
@ -549,15 +541,4 @@ public class OracleLegacySqlAstTranslator<T extends JdbcOperation> extends Abstr
|
|||
assignment.getAssignedValue().accept( this );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitColumnReference(ColumnReference columnReference) {
|
||||
columnReference.appendReadExpression( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitAggregateColumnWriteExpression(AggregateColumnWriteExpression aggregateColumnWriteExpression) {
|
||||
aggregateColumnWriteExpression.appendWriteExpression( this, this );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5247,4 +5247,13 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
|||
public String getRowIdColumnString(String rowId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the minimum {@link DmlTargetColumnQualifierSupport} required by this dialect.
|
||||
*
|
||||
* @return the column qualifier support required by this dialect
|
||||
*/
|
||||
public DmlTargetColumnQualifierSupport getDmlTargetColumnQualifierSupport() {
|
||||
return DmlTargetColumnQualifierSupport.NONE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
/**
|
||||
* Indicates the level of qualifier support used by
|
||||
* the dialect when referencing a column.
|
||||
*
|
||||
* @author Marco Belladelli
|
||||
*/
|
||||
public enum DmlTargetColumnQualifierSupport {
|
||||
/**
|
||||
* Qualify the column using the table expression,
|
||||
* ignoring a possible table alias.
|
||||
*/
|
||||
TABLE_EXPRESSION,
|
||||
|
||||
/**
|
||||
* Qualify the column using the table alias, whenever available,
|
||||
* and fallback to the table expression.
|
||||
*/
|
||||
TABLE_ALIAS,
|
||||
|
||||
/**
|
||||
* No need to explicitly qualify the column.
|
||||
*/
|
||||
NONE;
|
||||
}
|
|
@ -1449,4 +1449,9 @@ public class OracleDialect extends Dialect {
|
|||
final OracleSqlAstTranslator<?> translator = new OracleSqlAstTranslator<>( factory, optionalTableUpdate );
|
||||
return translator.createMergeOperation( optionalTableUpdate );
|
||||
}
|
||||
|
||||
@Override
|
||||
public DmlTargetColumnQualifierSupport getDmlTargetColumnQualifierSupport() {
|
||||
return DmlTargetColumnQualifierSupport.TABLE_ALIAS;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -512,14 +512,6 @@ public class OracleSqlAstTranslator<T extends JdbcOperation> extends SqlAstTrans
|
|||
return getDialect().supportsFetchClause( FetchClauseType.ROWS_ONLY );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean renderNamedTableReference(NamedTableReference tableReference, LockMode lockMode) {
|
||||
appendSql( tableReference.getTableExpression() );
|
||||
registerAffectedTable( tableReference );
|
||||
renderTableReferenceIdentificationVariable( tableReference );
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void visitSetAssignment(Assignment assignment) {
|
||||
final List<ColumnReference> columnReferences = assignment.getAssignable().getColumnReferences();
|
||||
|
@ -548,16 +540,6 @@ public class OracleSqlAstTranslator<T extends JdbcOperation> extends SqlAstTrans
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitColumnReference(ColumnReference columnReference) {
|
||||
columnReference.appendReadExpression( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitAggregateColumnWriteExpression(AggregateColumnWriteExpression aggregateColumnWriteExpression) {
|
||||
aggregateColumnWriteExpression.appendWriteExpression( this, this );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderMergeTargetAlias() {
|
||||
appendSql( " t" );
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.hibernate.Internal;
|
|||
import org.hibernate.LockMode;
|
||||
import org.hibernate.QueryException;
|
||||
import org.hibernate.boot.model.process.internal.InferredBasicValueResolver;
|
||||
import org.hibernate.dialect.DmlTargetColumnQualifierSupport;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.dialect.function.TimestampaddFunction;
|
||||
import org.hibernate.dialect.function.TimestampdiffFunction;
|
||||
|
@ -831,7 +832,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
(filterPredicate) -> additionalRestrictions = combinePredicates( additionalRestrictions, filterPredicate),
|
||||
entityDescriptor,
|
||||
rootTableGroup,
|
||||
AbstractSqlAstTranslator.rendersTableReferenceAlias( Clause.UPDATE ),
|
||||
getDialect().getDmlTargetColumnQualifierSupport() == DmlTargetColumnQualifierSupport.TABLE_ALIAS,
|
||||
getLoadQueryInfluencers(),
|
||||
this
|
||||
);
|
||||
|
@ -1088,7 +1089,7 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
(filterPredicate) -> additionalRestrictions = combinePredicates( additionalRestrictions, filterPredicate),
|
||||
entityDescriptor,
|
||||
rootTableGroup,
|
||||
AbstractSqlAstTranslator.rendersTableReferenceAlias( Clause.DELETE ),
|
||||
getDialect().getDmlTargetColumnQualifierSupport() == DmlTargetColumnQualifierSupport.TABLE_ALIAS,
|
||||
getLoadQueryInfluencers(),
|
||||
this
|
||||
);
|
||||
|
|
|
@ -27,6 +27,7 @@ import java.util.function.Supplier;
|
|||
import org.hibernate.LockMode;
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.QueryException;
|
||||
import org.hibernate.dialect.DmlTargetColumnQualifierSupport;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.dialect.RowLockStrategy;
|
||||
import org.hibernate.dialect.SelectItemReferenceStrategy;
|
||||
|
@ -5478,13 +5479,13 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
}
|
||||
}
|
||||
|
||||
public static boolean rendersTableReferenceAlias(Clause clause) {
|
||||
protected boolean rendersTableReferenceAlias(Clause clause) {
|
||||
// todo (6.0) : For now we just skip the alias rendering in the delete and update clauses
|
||||
// We need some dialect support if we want to support joins in delete and update statements
|
||||
switch ( clause ) {
|
||||
case DELETE:
|
||||
case UPDATE:
|
||||
return false;
|
||||
return getDialect().getDmlTargetColumnQualifierSupport() == DmlTargetColumnQualifierSupport.TABLE_ALIAS;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -6018,19 +6019,24 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
public void visitColumnReference(ColumnReference columnReference) {
|
||||
final String dmlTargetTableAlias = getDmlTargetTableAlias();
|
||||
if ( dmlTargetTableAlias != null && dmlTargetTableAlias.equals( columnReference.getQualifier() ) ) {
|
||||
// todo (6.0) : use the Dialect to determine how to handle column references
|
||||
// - specifically should they use the table-alias, the table-expression
|
||||
// or neither for its qualifier
|
||||
|
||||
final String tableExpression = getCurrentDmlStatement().getTargetTable().getTableExpression();
|
||||
// Qualify the column reference with the table expression only in subqueries
|
||||
final boolean qualifyColumn = !queryPartStack.isEmpty();
|
||||
final DmlTargetColumnQualifierSupport qualifierSupport = getDialect().getDmlTargetColumnQualifierSupport();
|
||||
final String qualifier;
|
||||
if ( qualifierSupport == DmlTargetColumnQualifierSupport.TABLE_ALIAS ) {
|
||||
qualifier = dmlTargetTableAlias;
|
||||
}
|
||||
// Qualify the column reference with the table expression also when in subqueries
|
||||
else if ( qualifierSupport != DmlTargetColumnQualifierSupport.NONE || !queryPartStack.isEmpty() ) {
|
||||
qualifier = getCurrentDmlStatement().getTargetTable().getTableExpression();
|
||||
}
|
||||
else {
|
||||
qualifier = null;
|
||||
}
|
||||
if ( columnReference.isColumnExpressionFormula() ) {
|
||||
// For formulas, we have to replace the qualifier as the alias was already rendered into the formula
|
||||
// This is fine for now as this is only temporary anyway until we render aliases for table references
|
||||
final String replacement;
|
||||
if ( qualifyColumn ) {
|
||||
replacement = "$1" + tableExpression + ".$3";
|
||||
if ( qualifier != null ) {
|
||||
replacement = "$1" + qualifier + ".$3";
|
||||
}
|
||||
else {
|
||||
replacement = "$1$3";
|
||||
|
@ -6041,7 +6047,7 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
);
|
||||
}
|
||||
else {
|
||||
columnReference.appendReadExpression( this, qualifyColumn ? tableExpression : null );
|
||||
columnReference.appendReadExpression( this, qualifier );
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -6054,10 +6060,19 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
final String dmlTargetTableAlias = getDmlTargetTableAlias();
|
||||
final ColumnReference columnReference = aggregateColumnWriteExpression.getColumnReference();
|
||||
if ( dmlTargetTableAlias != null && dmlTargetTableAlias.equals( columnReference.getQualifier() ) ) {
|
||||
final String tableExpression = getCurrentDmlStatement().getTargetTable().getTableExpression();
|
||||
// Qualify the column reference with the table expression only in subqueries
|
||||
final boolean qualifyColumn = !queryPartStack.isEmpty();
|
||||
aggregateColumnWriteExpression.appendWriteExpression( this, this, qualifyColumn ? tableExpression : null );
|
||||
final DmlTargetColumnQualifierSupport qualifierSupport = getDialect().getDmlTargetColumnQualifierSupport();
|
||||
final String qualifier;
|
||||
if ( qualifierSupport == DmlTargetColumnQualifierSupport.TABLE_ALIAS ) {
|
||||
qualifier = dmlTargetTableAlias;
|
||||
}
|
||||
// Qualify the column reference with the table expression also when in subqueries
|
||||
else if ( qualifierSupport != DmlTargetColumnQualifierSupport.NONE || !queryPartStack.isEmpty() ) {
|
||||
qualifier = getCurrentDmlStatement().getTargetTable().getTableExpression();
|
||||
}
|
||||
else {
|
||||
qualifier = null;
|
||||
}
|
||||
aggregateColumnWriteExpression.appendWriteExpression( this, this, qualifier );
|
||||
}
|
||||
else {
|
||||
aggregateColumnWriteExpression.appendWriteExpression( this, this );
|
||||
|
|
Loading…
Reference in New Issue