diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/CockroachDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/CockroachDialect.java index bbea3db392..975a2ee6ab 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/CockroachDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/CockroachDialect.java @@ -413,7 +413,6 @@ public class CockroachDialect extends Dialect { functionFactory.substr(); functionFactory.reverse(); functionFactory.repeat(); - functionFactory.md5(); functionFactory.sha1(); functionFactory.octetLength(); functionFactory.bitLength(); @@ -503,6 +502,9 @@ public class CockroachDialect extends Dialect { new PostgreSQLTruncFunction( true, functionContributions.getTypeConfiguration() ) ); functionContributions.getFunctionRegistry().registerAlternateKey( "truncate", "trunc" ); + + functionFactory.sha( "digest(?1, 'sha256')" ); + functionFactory.md5( "digest(?1, 'md5')" ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/DB2Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/DB2Dialect.java index d4541f5f82..c93ffc9c9f 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/DB2Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/DB2Dialect.java @@ -452,6 +452,9 @@ public class DB2Dialect extends Dialect { functionFactory.unnest_db2( getMaximumSeriesSize() ); functionFactory.generateSeries_recursive( getMaximumSeriesSize(), false, true ); + + functionFactory.sha( "hash(?1, 2)" ); + functionFactory.md5( "hash(?1, 0)" ); } /** diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java index 7774051fcd..d11938e4fb 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java @@ -368,6 +368,9 @@ public class H2Dialect extends Dialect { functionFactory.unnest_h2( getMaximumArraySize() ); functionFactory.generateSeries_h2( getMaximumSeriesSize() ); functionFactory.jsonTable_h2( getMaximumArraySize() ); + + functionFactory.sha( "hash('SHA-256', ?1)" ); + functionFactory.md5( "hash('MD5', ?1)" ); } /** diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/HANADialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/HANADialect.java index bf9bd39fc8..2672717fe2 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/HANADialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/HANADialect.java @@ -517,6 +517,9 @@ public class HANADialect extends Dialect { // functionFactory.xmlextract(); functionFactory.generateSeries_hana( getMaximumSeriesSize() ); + + functionFactory.sha( "hash_sha256(?1)" ); + functionFactory.md5( "hash_md5(?1)" ); } /** diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java index 56dba9f4e1..681052d5ad 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java @@ -590,7 +590,6 @@ public class MySQLDialect extends Dialect { functionFactory.space(); functionFactory.repeat(); functionFactory.pad_space(); - functionFactory.md5(); functionFactory.yearMonthDay(); functionFactory.hourMinuteSecond(); functionFactory.dayofweekmonthyear(); @@ -606,7 +605,6 @@ public class MySQLDialect extends Dialect { functionFactory.crc32(); functionFactory.sha1(); functionFactory.sha2(); - functionFactory.sha(); functionFactory.bitLength(); functionFactory.octetLength(); functionFactory.ascii(); @@ -688,6 +686,9 @@ public class MySQLDialect extends Dialect { if ( supportsRecursiveCTE() ) { functionFactory.generateSeries_recursive( getMaximumSeriesSize(), false, false ); } + + functionFactory.sha( "unhex(sha2(?1, 256))" ); + functionFactory.md5( "unhex(md5(?1))" ); } /** diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java index 9f5575a320..518d839fb0 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java @@ -440,6 +440,9 @@ public class OracleDialect extends Dialect { functionFactory.unnest_oracle(); functionFactory.generateSeries_recursive( getMaximumSeriesSize(), true, false ); functionFactory.jsonTable_oracle(); + + functionFactory.sha( "standard_hash(?1, 'SHA256')" ); + functionFactory.md5( "standard_hash(?1, 'MD5')" ); } /** diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java index 3707cee2bc..3e3c867bae 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java @@ -550,7 +550,6 @@ public class PostgreSQLDialect extends Dialect { functionFactory.pi(); functionFactory.trim2(); functionFactory.repeat(); - functionFactory.md5(); functionFactory.initcap(); functionFactory.substr(); functionFactory.substring_substr(); @@ -690,6 +689,9 @@ public class PostgreSQLDialect extends Dialect { functionFactory.unnest_postgresql(); } functionFactory.generateSeries( null, "ordinality", false ); + + functionFactory.sha( "sha256(?1)" ); + functionFactory.md5( "decode(md5(?1), 'hex')" ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/SQLServerDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/SQLServerDialect.java index c0480ddd41..4f73bc3f57 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/SQLServerDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/SQLServerDialect.java @@ -487,6 +487,9 @@ public class SQLServerDialect extends AbstractTransactSQLDialect { functionFactory.generateSeries_recursive( getMaximumSeriesSize(), false, false ); } } + + functionFactory.sha( "hashbytes('SHA2_256', ?1)" ); + functionFactory.md5( "hashbytes('MD5', ?1)" ); } /** diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/function/CommonFunctionFactory.java b/hibernate-core/src/main/java/org/hibernate/dialect/function/CommonFunctionFactory.java index 23a60ad3d1..9bf039e361 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/function/CommonFunctionFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/function/CommonFunctionFactory.java @@ -68,6 +68,7 @@ public class CommonFunctionFactory { private final BasicType booleanType; private final BasicType characterType; private final BasicType stringType; + private final BasicType binaryType; private final BasicType integerType; private final BasicType longType; private final BasicType doubleType; @@ -90,6 +91,7 @@ public class CommonFunctionFactory { characterType = basicTypeRegistry.resolve(StandardBasicTypes.CHARACTER); booleanType = basicTypeRegistry.resolve(StandardBasicTypes.BOOLEAN); stringType = basicTypeRegistry.resolve(StandardBasicTypes.STRING); + binaryType = basicTypeRegistry.resolve(StandardBasicTypes.BINARY); integerType = basicTypeRegistry.resolve(StandardBasicTypes.INTEGER); doubleType = basicTypeRegistry.resolve(StandardBasicTypes.DOUBLE); } @@ -813,6 +815,7 @@ public class CommonFunctionFactory { functionRegistry.registerAlternateKey( "repeat", "replicate" ); } + @Deprecated(since = "7") public void md5() { functionRegistry.namedDescriptorBuilder( "md5" ) .setInvariantType(stringType) @@ -2313,6 +2316,7 @@ public class CommonFunctionFactory { .register(); } + @Deprecated(since = "7") public void crc32() { functionRegistry.namedDescriptorBuilder( "crc32" ) .setInvariantType(integerType) @@ -2321,6 +2325,23 @@ public class CommonFunctionFactory { .register(); } + public void md5(String pattern) { + functionRegistry.patternDescriptorBuilder( "md5", pattern ) + .setInvariantType(binaryType) + .setParameterTypes( STRING ) + .setExactArgumentCount( 1 ) + .register(); + } + + public void sha(String pattern) { + functionRegistry.patternDescriptorBuilder( "sha", pattern ) + .setInvariantType(binaryType) + .setParameterTypes( STRING ) + .setExactArgumentCount( 1 ) + .register(); + } + + @Deprecated(since = "7") public void sha1() { functionRegistry.namedDescriptorBuilder( "sha1" ) .setInvariantType(stringType) @@ -2329,6 +2350,7 @@ public class CommonFunctionFactory { .register(); } + @Deprecated(since = "7") public void sha2() { functionRegistry.namedDescriptorBuilder( "sha2" ) .setInvariantType(stringType) @@ -2337,6 +2359,7 @@ public class CommonFunctionFactory { .register(); } + @Deprecated(since = "7") public void sha() { functionRegistry.namedDescriptorBuilder( "sha" ) .setInvariantType(stringType) diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FunctionTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FunctionTests.java index 7e4d09a242..da3a4fb554 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FunctionTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FunctionTests.java @@ -15,6 +15,7 @@ import org.hibernate.dialect.CockroachDialect; import org.hibernate.dialect.DB2Dialect; import org.hibernate.community.dialect.DerbyDialect; import org.hibernate.dialect.H2Dialect; +import org.hibernate.dialect.HANADialect; import org.hibernate.dialect.HSQLDialect; import org.hibernate.dialect.MariaDBDialect; import org.hibernate.dialect.MySQLDialect; @@ -47,6 +48,8 @@ import org.junit.jupiter.api.Test; import java.math.BigDecimal; import java.math.BigInteger; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.sql.Time; import java.sql.Timestamp; import java.time.Duration; @@ -2596,4 +2599,25 @@ public class FunctionTests { .getSingleResultOrNull(); }); } + + @Test + @RequiresDialect(PostgreSQLDialect.class) + @RequiresDialect(MySQLDialect.class) + @RequiresDialect(OracleDialect.class) + @RequiresDialect(DB2Dialect.class) + @RequiresDialect(SQLServerDialect.class) + @RequiresDialect(H2Dialect.class) + @RequiresDialect(HANADialect.class) + @RequiresDialect(CockroachDialect.class) + public void testSha256Function(SessionFactoryScope scope) { + scope.inTransaction(s -> { + byte[] bytes = s.createSelectionQuery("select sha('hello')", byte[].class).getSingleResult(); + try { + assertArrayEquals( MessageDigest.getInstance( "SHA-256" ).digest("hello".getBytes()), bytes ); + } + catch (NoSuchAlgorithmException e) { + throw new RuntimeException( e ); + } + }); + } }