Skip to content

Commit

Permalink
HHH-17435 --wip-- fix single quote escape
Browse files Browse the repository at this point in the history
  • Loading branch information
mbladel committed Jan 4, 2024
1 parent 1453efc commit c3d8c82
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -139,19 +139,20 @@ public int getDefaultStatementBatchSize() {

@Override
public String trimPattern(TrimSpec specification, char character) {
final String charString = trimCharString( character );
switch ( specification ) {
case BOTH:
return character == ' '
return charString == null
? "trim(?1)"
: "trim(?1, '" + character + "')";
: "trim(?1, " + charString + ")";
case LEADING:
return character == ' '
return charString == null
? "ltrim(?1)"
: "ltrim(?1,'" + character + "')";
: "ltrim(?1," + charString + ")";
case TRAILING:
return character == ' '
return charString == null
? "rtrim(?1)"
: "rtrim(?1,'" + character + "')";
: "rtrim(?1," + charString + ")";
}

return super.trimPattern( specification, character );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,19 +392,20 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
@Override
public String trimPattern(TrimSpec specification, char character) {
if ( getVersion().isSameOrAfter( 16 ) ) {
final String charString = trimCharString( character );
switch ( specification ) {
case BOTH:
return character == ' '
return charString == null
? "trim(?1)"
: "trim('" + character + "' from ?1)";
: "trim(" + charString + " from ?1)";
case LEADING:
return character == ' '
return charString == null
? "ltrim(?1)"
: "ltrim(?1,'" + character + "')";
: "ltrim(?1," + charString + ")";
case TRAILING:
return character == ' '
return charString == null
? "rtrim(?1)"
: "rtrim(?1,'" + character + "')";
: "rtrim(?1," + charString + ")";
}
throw new UnsupportedOperationException( "Unsupported specification: " + specification );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,19 +354,20 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio

@Override
public String trimPattern(TrimSpec specification, char character) {
final String charString = trimCharString( character );
switch ( specification ) {
case BOTH:
return character == ' '
return charString == null
? "trim(?1)"
: "trim(?1,'" + character + "')";
: "trim(?1," + charString + ")";
case LEADING:
return character == ' '
return charString == null
? "ltrim(?1)"
: "ltrim(?1,'" + character + "')";
: "ltrim(?1," + charString + ")";
case TRAILING:
return character == ' '
return charString == null
? "rtrim(?1)"
: "rtrim(?1,'" + character + "')";
: "rtrim(?1," + charString + ")";
}
throw new UnsupportedOperationException( "Unsupported specification: " + specification );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,23 +171,23 @@ public String trimPattern(TrimSpec specification, char character) {
}

public static String replaceLtrimRtrim(TrimSpec specification, char character) {
boolean blank = character == ' ';
final String charString = trimCharString( character );
switch ( specification ) {
case LEADING:
return blank
return charString == null
? "ltrim(?1)"
: "replace(replace(ltrim(replace(replace(?1,' ','#%#%'),'@',' ')),' ','@'),'#%#%',' ')"
.replace('@', character);
.replace("@", charString);
case TRAILING:
return blank
return charString == null
? "rtrim(?1)"
: "replace(replace(rtrim(replace(replace(?1,' ','#%#%'),'@',' ')),' ','@'),'#%#%',' ')"
.replace('@', character);
.replace("@", charString);
default:
return blank
return charString == null
? "ltrim(rtrim(?1))"
: "replace(replace(ltrim(rtrim(replace(replace(?1,' ','#%#%'),'@',' '))),' ','@'),'#%#%',' ')"
.replace('@', character);
.replace("@", charString);
}
}

Expand Down
25 changes: 22 additions & 3 deletions hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java
Original file line number Diff line number Diff line change
Expand Up @@ -1485,10 +1485,29 @@ public String castPattern(CastType from, CastType to) {
* @param specification {@code leading} or {@code trailing}
* @param character the character to trim
*/
@Deprecated
public String trimPattern(TrimSpec specification, char character) {
return character == ' '
? "trim(" + specification + " from ?1)"
: "trim(" + specification + " '" + character + "' from ?1)";
final String charString = trimCharString( character );
return "trim(" + specification + ( charString == null ? "" : " " + charString ) + " from ?1)";
}

public String trimPattern(TrimSpec specification, boolean customCharacter) {
return "trim(" + specification + (customCharacter ? " ?2" : "" ) + " from ?1)";
}

protected static String trimCharString(char character) {
final String charString;
switch (character) {
case ' ':
charString = null;
break;
case '\'':
charString = "''''";
break;
default:
charString = "'" + character + "'";
}
return charString;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -401,19 +401,20 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
@Override
public String trimPattern(TrimSpec specification, char character) {
if ( getVersion().isSameOrAfter( 16 ) ) {
final String charString = trimCharString( character );
switch ( specification ) {
case BOTH:
return character == ' '
return charString == null
? "trim(?1)"
: "trim('" + character + "' from ?1)";
: "trim(" + charString + " from ?1)";
case LEADING:
return character == ' '
return charString == null
? "ltrim(?1)"
: "ltrim(?1,'" + character + "')";
: "ltrim(?1," + charString + ")";
case TRAILING:
return character == ' '
return charString == null
? "rtrim(?1)"
: "rtrim(?1,'" + character + "')";
: "rtrim(?1," + charString + ")";
}
throw new UnsupportedOperationException( "Unsupported specification: " + specification );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4782,7 +4782,7 @@ public SqmLiteral<Character> visitPadCharacter(HqlParser.PadCharacterContext ctx
public SqmExpression<?> visitTrimFunction(HqlParser.TrimFunctionContext ctx) {
final SqmExpression<?> source = (SqmExpression<?>) ctx.expression().accept( this );
final SqmTrimSpecification trimSpec = visitTrimSpecification( ctx.trimSpecification() );;
final SqmLiteral<Character> trimChar = visitTrimCharacter( ctx.trimCharacter() );
final SqmExpression<?> trimChar = visitTrimCharacter( ctx.trimCharacter() );

return getFunctionDescriptor("trim").generateSqmExpression(
asList(
Expand Down Expand Up @@ -4816,20 +4816,25 @@ private static TrimSpec trimSpec(HqlParser.TrimSpecificationContext ctx) {
}

@Override
public SqmLiteral<Character> visitTrimCharacter(HqlParser.TrimCharacterContext ctx) {
final String trimCharText = ctx != null
? unquoteStringLiteral( ctx.getText() )
: " "; // JPA says space is the default

if ( trimCharText.length() != 1 ) {
throw new SemanticException( "Trim character for trim() function must be single character, found '" + trimCharText + "'" );
public SqmExpression<?> visitTrimCharacter(HqlParser.TrimCharacterContext ctx) {
if ( ctx == null ) {
// JPA says space is the default
return new SqmLiteral<>(
" ",
resolveExpressibleTypeBasic( String.class ),
creationContext.getNodeBuilder()
);
}
else {
final Object trimChar = ctx.getChild( 0 ).accept( this );
if ( trimChar instanceof SqmLiteral<?> ) {
final String trimCharText = unquoteStringLiteral( ctx.getText() );
if ( trimCharText.length() != 1 ) {
throw new SemanticException( "Trim character for trim() function must be single character, found '" + trimCharText + "'" );
}
}
return (SqmExpression<?>) trimChar;
}

return new SqmLiteral<>(
trimCharText.charAt( 0 ),
resolveExpressibleTypeBasic( Character.class ),
creationContext.getNodeBuilder()
);
}

@Override
Expand Down

0 comments on commit c3d8c82

Please sign in to comment.