Browse Source
Example: Expressions.cast(table_user.column("name"),"VARCHAR2")
Also adds a toString to AbstractSegment to avoid stack overflows.
Closes #1066
Original pull request: #1071.
pull/1078/head
7 changed files with 179 additions and 16 deletions
@ -0,0 +1,60 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2021 the original author or authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.springframework.data.relational.core.sql; |
||||||
|
|
||||||
|
import org.springframework.util.Assert; |
||||||
|
|
||||||
|
/** |
||||||
|
* Represents a CAST expression like {@code CAST(something AS JSON}. |
||||||
|
* |
||||||
|
* @author Jens Schauder |
||||||
|
* @since 2.3 |
||||||
|
*/ |
||||||
|
public class Cast extends AbstractSegment implements Expression { |
||||||
|
|
||||||
|
private final String targetType; |
||||||
|
private final Expression expression; |
||||||
|
|
||||||
|
private Cast(Expression expression, String targetType) { |
||||||
|
|
||||||
|
super(expression); |
||||||
|
|
||||||
|
Assert.notNull(targetType, "Cast target must not be null!"); |
||||||
|
|
||||||
|
this.expression = expression; |
||||||
|
this.targetType = targetType; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Creates a new CAST expression. |
||||||
|
* |
||||||
|
* @param expression the expression to cast. Must not be {@literal null}. |
||||||
|
* @param targetType the type to cast to. Must not be {@literal null}. |
||||||
|
* @return guaranteed to be not {@literal null}. |
||||||
|
*/ |
||||||
|
static Expression create(Expression expression, String targetType) { |
||||||
|
return new Cast(expression, targetType); |
||||||
|
} |
||||||
|
|
||||||
|
public String getTargetType() { |
||||||
|
return targetType; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return "CAST(" + expression + " AS " + targetType + ")"; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,77 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2021 the original author or authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.springframework.data.relational.core.sql.render; |
||||||
|
|
||||||
|
import java.util.StringJoiner; |
||||||
|
|
||||||
|
import org.springframework.data.relational.core.sql.Cast; |
||||||
|
import org.springframework.data.relational.core.sql.Visitable; |
||||||
|
import org.springframework.lang.Nullable; |
||||||
|
import org.springframework.util.Assert; |
||||||
|
|
||||||
|
/** |
||||||
|
* Renders a CAST expression, by delegating to an {@link ExpressionVisitor} and building the expression out of the |
||||||
|
* rendered parts. |
||||||
|
* |
||||||
|
* @author Jens Schauder |
||||||
|
* @since 2.3 |
||||||
|
*/ |
||||||
|
class CastVisitor extends TypedSubtreeVisitor<Cast> implements PartRenderer { |
||||||
|
|
||||||
|
private final RenderContext context; |
||||||
|
@Nullable private StringJoiner joiner; |
||||||
|
@Nullable private ExpressionVisitor expressionVisitor; |
||||||
|
|
||||||
|
CastVisitor(RenderContext context) { |
||||||
|
|
||||||
|
this.context = context; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
Delegation enterMatched(Cast cast) { |
||||||
|
|
||||||
|
joiner = new StringJoiner(", ", "CAST(", " AS " + cast.getTargetType() + ")"); |
||||||
|
|
||||||
|
return super.enterMatched(cast); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
Delegation enterNested(Visitable segment) { |
||||||
|
|
||||||
|
expressionVisitor = new ExpressionVisitor(context, ExpressionVisitor.AliasHandling.IGNORE); |
||||||
|
return Delegation.delegateTo(expressionVisitor); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
Delegation leaveNested(Visitable segment) { |
||||||
|
|
||||||
|
Assert.state(joiner != null, "Joiner must not be null."); |
||||||
|
Assert.state(expressionVisitor != null, "ExpressionVisitor must not be null."); |
||||||
|
|
||||||
|
joiner.add(expressionVisitor.getRenderedPart()); |
||||||
|
return super.leaveNested(segment); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public CharSequence getRenderedPart() { |
||||||
|
|
||||||
|
if (joiner == null) { |
||||||
|
throw new IllegalStateException("Joiner must not be null."); |
||||||
|
} |
||||||
|
|
||||||
|
return joiner.toString(); |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue