Allow binary literals to be specified in a Java byte-array-like format

Allow you to write x'DEADBEEF' as {0xDE, 0xAD, 0xBE, 0xEF}.

For now I'm being quite restrictive here:

- byte literals must be written in hexadecimal not in decimal
- they must be exactly two digits in length

(I would like to allow decimal format but I think that would start to
collide with other rules with braces in the grammar.)
This commit is contained in:
gavinking 2020-02-05 16:04:53 +01:00 committed by Steve Ebersole
parent ddaff28838
commit cb3560de96
3 changed files with 27 additions and 4 deletions

View File

@ -501,7 +501,6 @@ nullifFunction
literal
: STRING_LITERAL
| BINARY_LITERAL
| INTEGER_LITERAL
| LONG_LITERAL
| BIG_INTEGER_LITERAL
@ -512,10 +511,16 @@ literal
| NULL
| TRUE
| FALSE
| binaryLiteral
| temporalLiteral
| generalizedLiteral
;
binaryLiteral
: BINARY_LITERAL
| LEFT_BRACE HEX_LITERAL (COMMA HEX_LITERAL)* RIGHT_BRACE
;
temporalLiteral
: dateTimeLiteral
| dateLiteral

View File

@ -1746,9 +1746,6 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
if ( ctx.literal().STRING_LITERAL() != null ) {
return stringLiteral( ctx.literal().STRING_LITERAL().getText() );
}
else if ( ctx.literal().BINARY_LITERAL() != null ) {
return binaryLiteral( ctx.literal().BINARY_LITERAL().getText() );
}
else if ( ctx.literal().INTEGER_LITERAL() != null ) {
return integerLiteral( ctx.literal().INTEGER_LITERAL().getText() );
}
@ -1780,6 +1777,22 @@ public class SemanticQueryBuilder extends HqlParserBaseVisitor implements SqmCre
return new SqmLiteralNull( creationContext.getQueryEngine().getCriteriaBuilder() );
}
if ( ctx.literal().binaryLiteral() != null ) {
if ( ctx.literal().binaryLiteral().BINARY_LITERAL() != null ) {
return binaryLiteral( ctx.literal().binaryLiteral().BINARY_LITERAL().getText() );
}
else {
StringBuilder text = new StringBuilder("x'");
for ( TerminalNode hex : ctx.literal().binaryLiteral().HEX_LITERAL() ) {
if ( hex.getText().length()!=4 ) {
throw new LiteralNumberFormatException( "not a byte: " + hex.getText() );
}
text.append( hex.getText().substring(2) );
}
return binaryLiteral( text.append("'").toString() );
}
}
if ( ctx.literal().temporalLiteral() != null ) {
return interpretTemporalLiteral( ctx.literal().temporalLiteral() );
}

View File

@ -37,6 +37,11 @@ public class LiteralTests {
assertThat( BINARY.toString(bytes1), is("deadbeef") );
byte[] bytes2 = (byte[]) session.createQuery( "select X'deadbeef'" ).getSingleResult();
assertThat( BINARY.toString(bytes2), is("deadbeef") );
byte[] bytes3 = (byte[]) session.createQuery( "select {0xDE, 0xAD, 0xBE, 0xEF}" ).getSingleResult();
assertThat( BINARY.toString(bytes3), is("deadbeef") );
byte[] bytes4 = (byte[]) session.createQuery( "select {0xde, 0xad, 0xbe, 0xef}'" ).getSingleResult();
assertThat( BINARY.toString(bytes4), is("deadbeef") );
}
);
}