HHH-10754 - Add support for PARTITION keyword in @Formula

This commit is contained in:
Vlad Mihalcea 2016-05-24 11:51:30 +03:00
parent f18a749c12
commit a3207ca5a8
9 changed files with 205 additions and 8 deletions

View File

@ -275,4 +275,8 @@ abstract class AbstractTransactSQLDialect extends Dialect {
return new AbstractTransactSQLIdentityColumnSupport();
}
@Override
public boolean supportsPartitionBy() {
return true;
}
}

View File

@ -347,4 +347,8 @@ public class CUBRIDDialect extends Dialect {
return new CUBRIDIdentityColumnSupport();
}
@Override
public boolean supportsPartitionBy() {
return true;
}
}

View File

@ -559,4 +559,9 @@ public class DB2Dialect extends Dialect {
public IdentityColumnSupport getIdentityColumnSupport() {
return new DB2IdentityColumnSupport();
}
@Override
public boolean supportsPartitionBy() {
return true;
}
}

View File

@ -233,6 +233,10 @@ public abstract class Dialect implements ConversionContext {
registerHibernateType( Types.CLOB, StandardBasicTypes.CLOB.getName() );
registerHibernateType( Types.REAL, StandardBasicTypes.FLOAT.getName() );
if(supportsPartitionBy()) {
registerKeyword( "PARTITION" );
}
uniqueDelegate = new DefaultUniqueDelegate( this );
}
@ -2747,4 +2751,15 @@ public abstract class Dialect implements ConversionContext {
public void augmentRecognizedTableTypes(List<String> tableTypesList) {
// noihing to do
}
/**
* Does the underlying database support partition by
*
* @return boolean
*
* @since 5.2
*/
public boolean supportsPartitionBy() {
return false;
}
}

View File

@ -6,6 +6,13 @@
*/
package org.hibernate.dialect;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.List;
import java.util.Locale;
import org.hibernate.JDBCException;
import org.hibernate.QueryTimeoutException;
import org.hibernate.annotations.common.util.StringHelper;
@ -40,13 +47,6 @@ import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.sql.BitTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.List;
import java.util.Locale;
/**
* A dialect for Oracle 8i.
*
@ -672,4 +672,9 @@ public class Oracle8iDialect extends Dialect {
public boolean canCreateSchema() {
return false;
}
@Override
public boolean supportsPartitionBy() {
return true;
}
}

View File

@ -0,0 +1,20 @@
/*
* 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;
/**
* An SQL dialect for Postgres 9.1 and later, adds support for PARTITION BY as a keyword.
*
* @author Mark Robinson
*/
public class PostgreSQL91Dialect extends PostgreSQL9Dialect {
@Override
public boolean supportsPartitionBy() {
return true;
}
}

View File

@ -13,7 +13,7 @@ import java.sql.Types;
*
* @author Mark Robinson
*/
public class PostgreSQL92Dialect extends PostgreSQL9Dialect {
public class PostgreSQL92Dialect extends PostgreSQL91Dialect {
/**
* Constructs a PostgreSQL92Dialect

View File

@ -0,0 +1,138 @@
/*
* 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.test.annotations.formula;
import java.io.Serializable;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.annotations.Formula;
import org.hibernate.dialect.Oracle8iDialect;
import org.hibernate.dialect.PostgreSQL91Dialect;
import org.hibernate.dialect.SQLServer2005Dialect;
import org.hibernate.testing.DialectCheck;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.RequiresDialectFeature;
import org.hibernate.testing.RequiresDialects;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/**
* @author Vlad Mihalcea
*/
@RequiresDialectFeature( jiraKey = "HHH-10754", value = DialectChecks.SupportPartitionBy.class)
public class FormulaWithPartitionByTest extends BaseCoreFunctionalTestCase {
@Test
@TestForIssue(jiraKey = "HHH-10754")
public void testFormulaAnnotationWithPartitionBy() {
Session session = openSession();
Transaction transaction = session.beginTransaction();
DisplayItem displayItem20_1 = new DisplayItem();
displayItem20_1.setId( 1 );
displayItem20_1.setDiscountCode( "20" );
displayItem20_1.setDiscountValue( 12.34d );
DisplayItem displayItem20_2 = new DisplayItem();
displayItem20_2.setId( 2 );
displayItem20_2.setDiscountCode( "20" );
displayItem20_2.setDiscountValue( 15.89 );
DisplayItem displayItem100 = new DisplayItem();
displayItem100.setId( 3 );
displayItem100.setDiscountCode( "100" );
displayItem100.setDiscountValue( 12.5 );
session.persist( displayItem20_1 );
session.persist( displayItem20_2 );
session.persist( displayItem100 );
transaction.commit();
session.close();
session = openSession();
transaction = session.beginTransaction();
List<DisplayItem> displayItems = session.createQuery( "select di from DisplayItem di order by di.id", DisplayItem.class).getResultList();
assertNotNull( displayItems );
assertEquals( displayItems.size(), 3 );
assertEquals( 1, displayItems.get( 0 ).getItemsByCode().intValue() );
assertEquals( 2, displayItems.get( 1 ).getItemsByCode().intValue() );
assertEquals( 1, displayItems.get( 2 ).getItemsByCode().intValue() );
transaction.commit();
session.close();
}
@Override
public Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {DisplayItem.class};
}
@Entity(name = "DisplayItem")
public static class DisplayItem implements Serializable {
@Id
private Integer id;
@Column(name = "DISCOUNT_CODE")
private String discountCode;
@Column(name = "DISCOUNT_VALUE")
private Double discountValue;
@Formula("ROW_NUMBER() OVER( PARTITION BY DISCOUNT_CODE ORDER BY SIGN(DISCOUNT_VALUE) DESC )")
private Integer itemsByCode;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDiscountCode() {
return discountCode;
}
public void setDiscountCode(String discountCode) {
this.discountCode = discountCode;
}
public Integer getItemsByCode() {
return itemsByCode;
}
public void setItemsByCode(Integer itemsByCode) {
this.itemsByCode = itemsByCode;
}
public Double getDiscountValue() {
return discountValue;
}
public void setDiscountValue(Double discountValue) {
this.discountValue = discountValue;
}
}
}

View File

@ -195,4 +195,10 @@ abstract public class DialectChecks {
return !dialect.useFollowOnLocking();
}
}
public static class SupportPartitionBy implements DialectCheck {
public boolean isMatch(Dialect dialect) {
return dialect.supportsPartitionBy();
}
}
}