HHH-18892 add hex() function

This commit is contained in:
Gavin King 2024-12-03 21:18:01 +01:00
parent c73a12ced6
commit 1a5db3bf42
14 changed files with 38 additions and 1 deletions

View File

@ -841,6 +841,7 @@ Naturally, there are a good number of functions for working with strings.
| `replace()` | Replace every occurrence of a pattern in a string | `replace(str, patt, rep)` | ✔ / ✖
| `repeat()` | Concatenate a string with itself multiple times | `repeat(str, times)` | ✖ / ✖
| `collate()` | Select a collation | `collate(p.name as collation)` | ✖ / ✖
| `hex()` | Encode a binary value as a hexadecimal string | `hex(image.bytes)` | ✖ / ✖
|===
Let's take a closer look at just some of these.

View File

@ -503,6 +503,7 @@ public class CockroachDialect extends Dialect {
);
functionContributions.getFunctionRegistry().registerAlternateKey( "truncate", "trunc" );
functionFactory.hex( "encode(?1, 'hex')" );
functionFactory.sha( "digest(?1, 'sha256')" );
functionFactory.md5( "digest(?1, 'md5')" );
}

View File

@ -453,6 +453,7 @@ public class DB2Dialect extends Dialect {
functionFactory.unnest_db2( getMaximumSeriesSize() );
functionFactory.generateSeries_recursive( getMaximumSeriesSize(), false, true );
functionFactory.hex( "hex(?1)" );
functionFactory.sha( "hash(?1, 2)" );
functionFactory.md5( "hash(?1, 0)" );
}

View File

@ -369,6 +369,7 @@ public class H2Dialect extends Dialect {
functionFactory.generateSeries_h2( getMaximumSeriesSize() );
functionFactory.jsonTable_h2( getMaximumArraySize() );
functionFactory.hex( "rawtohex(?1)" );
functionFactory.sha( "hash('SHA-256', ?1)" );
functionFactory.md5( "hash('MD5', ?1)" );
}

View File

@ -518,6 +518,7 @@ public class HANADialect extends Dialect {
// functionFactory.xmlextract();
functionFactory.generateSeries_hana( getMaximumSeriesSize() );
functionFactory.hex( "to_hex(?1)" );
functionFactory.sha( "hash_sha256(?1)" );
functionFactory.md5( "hash_md5(?1)" );
}

View File

@ -222,6 +222,8 @@ public class HSQLDialect extends Dialect {
functionContributions.getTypeConfiguration(),
SqlAstNodeRenderingMode.NO_PLAIN_PARAMETER
) );
functionFactory.hex( "hex(?1)" );
}
/**

View File

@ -687,6 +687,7 @@ public class MySQLDialect extends Dialect {
functionFactory.generateSeries_recursive( getMaximumSeriesSize(), false, false );
}
functionFactory.hex( "hex(?1)" );
functionFactory.sha( "unhex(sha2(?1, 256))" );
functionFactory.md5( "unhex(md5(?1))" );
}

View File

@ -441,6 +441,7 @@ public class OracleDialect extends Dialect {
functionFactory.generateSeries_recursive( getMaximumSeriesSize(), true, false );
functionFactory.jsonTable_oracle();
functionFactory.hex( "rawtohex(?1)" );
functionFactory.sha( "standard_hash(?1, 'SHA256')" );
functionFactory.md5( "standard_hash(?1, 'MD5')" );
}

View File

@ -690,6 +690,7 @@ public class PostgreSQLDialect extends Dialect {
}
functionFactory.generateSeries( null, "ordinality", false );
functionFactory.hex( "encode(?1, 'hex')" );
functionFactory.sha( "sha256(?1)" );
functionFactory.md5( "decode(md5(?1), 'hex')" );
}

View File

@ -488,6 +488,7 @@ public class SQLServerDialect extends AbstractTransactSQLDialect {
}
}
functionFactory.hex( "convert(varchar(MAX), ?1, 2)" );
functionFactory.sha( "hashbytes('SHA2_256', ?1)" );
functionFactory.md5( "hashbytes('MD5', ?1)" );
}

View File

@ -389,7 +389,8 @@ public class CommonFunctionFactory {
}
/**
* CockroachDB lacks implicit casting: https://github.com/cockroachdb/cockroach/issues/89965
* CockroachDB lacks
* <a href="https://github.com/cockroachdb/cockroach/issues/89965">implicit casting</a>
*/
public void median_percentileCont_castDouble() {
functionRegistry.patternDescriptorBuilder(
@ -2325,6 +2326,14 @@ public class CommonFunctionFactory {
.register();
}
public void hex(String pattern) {
functionRegistry.patternDescriptorBuilder( "hex", pattern )
.setInvariantType(stringType)
.setParameterTypes( BINARY )
.setExactArgumentCount( 1 )
.register();
}
public void md5(String pattern) {
functionRegistry.patternDescriptorBuilder( "md5", pattern )
.setInvariantType(binaryType)

View File

@ -248,6 +248,7 @@ public class ArgumentTypesValidator implements ArgumentsValidator {
case TEMPORAL -> jdbcType.isTemporal();
case DATE -> jdbcType.hasDatePart();
case TIME -> jdbcType.hasTimePart();
case BINARY -> jdbcType.isBinary();
case SPATIAL -> jdbcType.isSpatial();
case JSON -> jdbcType.isJson();
case IMPLICIT_JSON -> jdbcType.isImplicitJson();

View File

@ -48,6 +48,10 @@ public enum FunctionParameterType {
* a logical expression (predicate)
*/
BOOLEAN,
/**
* @see org.hibernate.type.SqlTypes#isBinaryType(int)
*/
BINARY,
/**
* Indicates a parameter that accepts any type
*/

View File

@ -23,6 +23,7 @@ import org.hibernate.dialect.OracleDialect;
import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.dialect.PostgresPlusDialect;
import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.dialect.SybaseASEDialect;
import org.hibernate.dialect.SybaseDialect;
import org.hibernate.dialect.TiDBDialect;
import org.hibernate.query.sqm.produce.function.FunctionArgumentException;
@ -62,6 +63,7 @@ import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
@ -2627,4 +2629,14 @@ public class FunctionTests {
}
});
}
@Test
@SkipForDialect(dialectClass = SybaseASEDialect.class)
public void testHexFunction(SessionFactoryScope scope) {
scope.inTransaction(s -> {
assertEquals( "DEADBEEF",
s.createSelectionQuery("select hex({0xDE, 0xAD, 0xBE, 0xEF})", String.class)
.getSingleResult().toUpperCase( Locale.ROOT ) );
});
}
}