Skip to content

Commit

Permalink
introduce standardized POWER() function
Browse files Browse the repository at this point in the history
  • Loading branch information
gavinking authored and sebersole committed May 8, 2019
1 parent 946b25a commit b8d1f06
Show file tree
Hide file tree
Showing 25 changed files with 211 additions and 32 deletions.
Expand Up @@ -196,6 +196,7 @@ OR : [oO] [rR];
ORDER : [oO] [rR] [dD] [eE] [rR];
OUTER : [oO] [uU] [tT] [eE] [rR];
POSITION : [pP] [oO] [sS] [iI] [tT] [iI] [oO] [nN];
POWER : [pP] [oO] [wW] [eE] [rR];
REPLACE : [rR] [eE] [pP] [lL] [aA] [cC] [eE];
RIGHT : [rR] [iI] [gG] [hH] [tT];
SECOND : [sS] [eE] [cC] [oO] [nN] [dD];
Expand Down
Expand Up @@ -582,6 +582,7 @@ standardFunction
| lnFunction
| expFunction
| modFunction
| powerFunction
| strFunction
| currentDateFunction
| currentTimeFunction
Expand Down Expand Up @@ -703,14 +704,22 @@ expFunction
: EXP LEFT_PAREN expression RIGHT_PAREN
;

powerFunction
: POWER LEFT_PAREN powerBaseArgument COMMA powerPowerArgument RIGHT_PAREN
;

powerBaseArgument
: expression
;

powerPowerArgument
: expression
;

modFunction
: MOD LEFT_PAREN modDividendArgument COMMA modDivisorArgument RIGHT_PAREN
;

strFunction
: STR LEFT_PAREN expression RIGHT_PAREN
;

modDividendArgument
: expression
;
Expand All @@ -719,6 +728,10 @@ modDivisorArgument
: expression
;

strFunction
: STR LEFT_PAREN expression RIGHT_PAREN
;

currentDateFunction
: CURRENT_DATE (LEFT_PAREN RIGHT_PAREN)?
;
Expand Down Expand Up @@ -840,6 +853,7 @@ identifier
| ORDER
| OUTER
| POSITION
| POWER
| REPLACE
| RIGHT
| SELECT
Expand Down
Expand Up @@ -339,7 +339,6 @@ public void initializeFunctionRegistry(QueryEngine queryEngine) {
queryEngine.getSqmFunctionRegistry().registerNamed( "least" );
queryEngine.getSqmFunctionRegistry().registerNamed( "log", StandardSpiBasicTypes.DOUBLE );

queryEngine.getSqmFunctionRegistry().registerNamed( "power" );
queryEngine.getSqmFunctionRegistry().registerNamed( "round" );
queryEngine.getSqmFunctionRegistry().registerNamed( "sign", StandardSpiBasicTypes.INTEGER );
queryEngine.getSqmFunctionRegistry().registerNamed( "sin", StandardSpiBasicTypes.DOUBLE );
Expand Down
Expand Up @@ -179,7 +179,6 @@ public void initializeFunctionRegistry(QueryEngine queryEngine) {

queryEngine.getSqmFunctionRegistry().registerNamed( "substr", StandardSpiBasicTypes.STRING );

queryEngine.getSqmFunctionRegistry().registerNamed( "power" );
queryEngine.getSqmFunctionRegistry().registerNamed( "stddev" );
queryEngine.getSqmFunctionRegistry().registerNamed( "variance" );
queryEngine.getSqmFunctionRegistry().registerNamed( "trunc" );
Expand Down
Expand Up @@ -344,7 +344,6 @@ protected void commonFunctionRegistrations(QueryEngine queryEngine) {
queryEngine.getSqmFunctionRegistry().registerVarArgs( "%pattern", StandardSpiBasicTypes.STRING, "", "%pattern", "" );
queryEngine.getSqmFunctionRegistry().wrapInJdbcEscape( "pi", queryEngine.getSqmFunctionRegistry().registerNamed( "pi", StandardSpiBasicTypes.DOUBLE ) );
queryEngine.getSqmFunctionRegistry().registerNamed( "$piece", StandardSpiBasicTypes.STRING );
queryEngine.getSqmFunctionRegistry().registerNamed( "power", StandardSpiBasicTypes.STRING );
queryEngine.getSqmFunctionRegistry().wrapInJdbcEscape( "quarter", queryEngine.getSqmFunctionRegistry().registerNamed( "quarter", StandardSpiBasicTypes.INTEGER ) );
queryEngine.getSqmFunctionRegistry().registerNamed( "repeat", StandardSpiBasicTypes.STRING );
queryEngine.getSqmFunctionRegistry().registerNamed( "replicate", StandardSpiBasicTypes.STRING );
Expand Down
Expand Up @@ -273,6 +273,7 @@ protected Dialect() {
* * character_length
* * ln
* * exp
* * power
*
* And several additional "standard" functions:
*
Expand Down
Expand Up @@ -208,11 +208,6 @@ public void initializeFunctionRegistry(QueryEngine queryEngine) {
.setInvariantType( StandardSpiBasicTypes.DOUBLE )
.register();

queryEngine.getSqmFunctionRegistry().namedTemplateBuilder( "power" )
.setExactArgumentCount( 2 )
.setInvariantType( StandardSpiBasicTypes.DOUBLE )
.register();

CommonFunctionFactory.radians( queryEngine );

queryEngine.getSqmFunctionRegistry().namedTemplateBuilder( "rand" )
Expand Down
Expand Up @@ -286,11 +286,6 @@ public void initializeFunctionRegistry(QueryEngine queryEngine) {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Numeric functions

queryEngine.getSqmFunctionRegistry().namedTemplateBuilder( "power" )
.setExactArgumentCount( 2 )
.setInvariantType( StandardSpiBasicTypes.DOUBLE )
.register();

queryEngine.getSqmFunctionRegistry().noArgsBuilder( "random" )
.setUseParenthesesWhenNoArgs( true )
.setInvariantType( StandardSpiBasicTypes.LONG )
Expand Down
Expand Up @@ -100,7 +100,6 @@ public void initializeFunctionRegistry(QueryEngine queryEngine) {
queryEngine.getSqmFunctionRegistry().registerNamed( "dtan", StandardSpiBasicTypes.DOUBLE );
queryEngine.getSqmFunctionRegistry().registerNamed( "tan", StandardSpiBasicTypes.DOUBLE );
queryEngine.getSqmFunctionRegistry().registerNamed( "dpower" );
queryEngine.getSqmFunctionRegistry().registerNamed( "power" );

queryEngine.getSqmFunctionRegistry().registerNamed( "date", StandardSpiBasicTypes.DATE );
queryEngine.getSqmFunctionRegistry().registerNamed( "dayofweek", StandardSpiBasicTypes.INTEGER );
Expand Down
Expand Up @@ -277,10 +277,6 @@ public void initializeFunctionRegistry(QueryEngine queryEngine) {
.setExactArgumentCount( 2 )
.register();
CommonFunctionFactory.log( queryEngine );
queryEngine.getSqmFunctionRegistry().namedTemplateBuilder( "power" )
.setInvariantType( StandardSpiBasicTypes.FLOAT )
.setExactArgumentCount( 2 )
.register();

// Multi-param date dialect functions...
queryEngine.getSqmFunctionRegistry().namedTemplateBuilder( "add_months" )
Expand Down
Expand Up @@ -226,10 +226,6 @@ public void initializeFunctionRegistry(QueryEngine queryEngine) {
.setExactArgumentCount( 1 )
.register();
CommonFunctionFactory.log( queryEngine );
queryEngine.getSqmFunctionRegistry().namedTemplateBuilder( "power" )
.setInvariantType( StandardSpiBasicTypes.FLOAT )
.setExactArgumentCount( 2 )
.register();

// Multi-param date dialect functions...
queryEngine.getSqmFunctionRegistry().namedTemplateBuilder( "add_months" )
Expand Down
Expand Up @@ -273,10 +273,6 @@ public void initializeFunctionRegistry(QueryEngine queryEngine) {
.setExactArgumentCount( 2 )
.register();
CommonFunctionFactory.log( queryEngine );
queryEngine.getSqmFunctionRegistry().namedTemplateBuilder( "power" )
.setInvariantType( StandardSpiBasicTypes.FLOAT )
.setExactArgumentCount( 2 )
.register();
}

@Override
Expand Down
Expand Up @@ -243,7 +243,6 @@ public void initializeFunctionRegistry(QueryEngine queryEngine) {

queryEngine.getSqmFunctionRegistry().registerNamed( "atan2", StandardSpiBasicTypes.DOUBLE );
queryEngine.getSqmFunctionRegistry().registerNamed( "nvl" );
queryEngine.getSqmFunctionRegistry().registerNamed( "power", StandardSpiBasicTypes.DOUBLE );
}


Expand Down
Expand Up @@ -65,7 +65,6 @@ public void initializeFunctionRegistry(QueryEngine queryEngine) {

queryEngine.getSqmFunctionRegistry().registerNamed( "log", StandardSpiBasicTypes.DOUBLE );
queryEngine.getSqmFunctionRegistry().registerNoArgs( "pi", StandardSpiBasicTypes.DOUBLE );
queryEngine.getSqmFunctionRegistry().registerNamed( "power" );
queryEngine.getSqmFunctionRegistry().registerNamed( "acos", StandardSpiBasicTypes.DOUBLE );
queryEngine.getSqmFunctionRegistry().registerNamed( "asin", StandardSpiBasicTypes.DOUBLE );
queryEngine.getSqmFunctionRegistry().registerNamed( "atan", StandardSpiBasicTypes.DOUBLE );
Expand Down
Expand Up @@ -1876,6 +1876,22 @@ public SqmExpression visitModFunction(HqlParser.ModFunctionContext ctx) {
);
}

@Override
public SqmExpression visitPowerFunction(HqlParser.PowerFunctionContext ctx) {
//noinspection unchecked
return generateTwoArgFunction(
SqmModFunction.NAME,
(sqmFunctionTemplate, arg1, arg2) -> sqmFunctionTemplate.makeSqmFunctionExpression(
asList( arg1, arg2 ),
(AllowableFunctionReturnType) arg1.getExpressableType(),
creationContext.getQueryEngine()
),
(arg1, arg2) -> new SqmModFunction( arg1, arg2, (AllowableFunctionReturnType) arg1.getExpressableType(), creationContext.getNodeBuilder() ),
ctx.powerBaseArgument().expression(),
ctx.powerPowerArgument().expression()
);
}

@Override
public SqmExpression visitSqrtFunction(HqlParser.SqrtFunctionContext ctx) {
//noinspection unchecked
Expand Down
Expand Up @@ -63,6 +63,7 @@
import org.hibernate.query.sqm.tree.expression.function.SqmMinFunction;
import org.hibernate.query.sqm.tree.expression.function.SqmModFunction;
import org.hibernate.query.sqm.tree.expression.function.SqmNullifFunction;
import org.hibernate.query.sqm.tree.expression.function.SqmPowerFunction;
import org.hibernate.query.sqm.tree.expression.function.SqmReplaceFunction;
import org.hibernate.query.sqm.tree.expression.function.SqmSqrtFunction;
import org.hibernate.query.sqm.tree.expression.function.SqmStrFunction;
Expand Down Expand Up @@ -590,6 +591,11 @@ public T visitModFunction(SqmModFunction function) {
return (T) function;
}

@Override
public T visitPowerFunction(SqmPowerFunction function) {
return (T) function;
}

@Override
public T visitNullifFunction(SqmNullifFunction expression) {
return (T) expression;
Expand Down
Expand Up @@ -76,6 +76,7 @@
import org.hibernate.query.sqm.tree.expression.function.SqmMinFunction;
import org.hibernate.query.sqm.tree.expression.function.SqmModFunction;
import org.hibernate.query.sqm.tree.expression.function.SqmNullifFunction;
import org.hibernate.query.sqm.tree.expression.function.SqmPowerFunction;
import org.hibernate.query.sqm.tree.expression.function.SqmReplaceFunction;
import org.hibernate.query.sqm.tree.expression.function.SqmSqrtFunction;
import org.hibernate.query.sqm.tree.expression.function.SqmStrFunction;
Expand Down Expand Up @@ -153,6 +154,7 @@
import org.hibernate.sql.ast.tree.expression.ModFunction;
import org.hibernate.sql.ast.tree.expression.NonStandardFunction;
import org.hibernate.sql.ast.tree.expression.NullifFunction;
import org.hibernate.sql.ast.tree.expression.PowerFunction;
import org.hibernate.sql.ast.tree.expression.QueryLiteral;
import org.hibernate.sql.ast.tree.expression.ReplaceFunction;
import org.hibernate.sql.ast.tree.expression.SqlTuple;
Expand Down Expand Up @@ -1156,6 +1158,24 @@ public Object visitModFunction(SqmModFunction function) {
}
}

@Override
public Object visitPowerFunction(SqmPowerFunction function) {
shallownessStack.push( Shallowness.FUNCTION );

final Expression base = toSqlExpression( function.getBase().accept( this ) );
final Expression power = toSqlExpression( function.getPower().accept( this ) );
try {
return new PowerFunction(
base,
power,
function.getExpressableType().getSqlExpressableType()
);
}
finally {
shallownessStack.pop();
}
}

@Override
public Object visitSubstringFunction(SqmSubstringFunction expression) {
shallownessStack.push( Shallowness.FUNCTION );
Expand Down
Expand Up @@ -62,6 +62,7 @@
import org.hibernate.query.sqm.tree.expression.function.SqmMinFunction;
import org.hibernate.query.sqm.tree.expression.function.SqmModFunction;
import org.hibernate.query.sqm.tree.expression.function.SqmNullifFunction;
import org.hibernate.query.sqm.tree.expression.function.SqmPowerFunction;
import org.hibernate.query.sqm.tree.expression.function.SqmReplaceFunction;
import org.hibernate.query.sqm.tree.expression.function.SqmSqrtFunction;
import org.hibernate.query.sqm.tree.expression.function.SqmStrFunction;
Expand Down Expand Up @@ -346,4 +347,6 @@ default T visitJpaCompoundSelection(SqmJpaCompoundSelection selection) {
T visitExpFunction(SqmExpFunction<?> tSqmExpFunction);

T visitLnFunction(SqmLnFunction<?> tSqmLnFunction);

T visitPowerFunction(SqmPowerFunction<?> tSqmPowerFunction);
}
Expand Up @@ -65,6 +65,7 @@
import org.hibernate.query.sqm.tree.expression.function.SqmMinFunction;
import org.hibernate.query.sqm.tree.expression.function.SqmModFunction;
import org.hibernate.query.sqm.tree.expression.function.SqmNullifFunction;
import org.hibernate.query.sqm.tree.expression.function.SqmPowerFunction;
import org.hibernate.query.sqm.tree.expression.function.SqmReplaceFunction;
import org.hibernate.query.sqm.tree.expression.function.SqmSqrtFunction;
import org.hibernate.query.sqm.tree.expression.function.SqmStrFunction;
Expand Down Expand Up @@ -710,6 +711,11 @@ public Object visitModFunction(SqmModFunction sqmModFunction) {
return null;
}

@Override
public Object visitPowerFunction(SqmPowerFunction sqmModFunction) {
return null;
}

@Override
public Object visitNullifFunction(SqmNullifFunction expression) {
return null;
Expand Down
@@ -0,0 +1,68 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.query.sqm.tree.expression.function;

import org.hibernate.metamodel.model.domain.spi.AllowableFunctionReturnType;
import org.hibernate.query.sqm.NodeBuilder;
import org.hibernate.query.sqm.consume.spi.SemanticQueryWalker;
import org.hibernate.query.sqm.tree.expression.SqmExpression;

import java.util.Locale;

/**
* @author Gavin King
*/
public class SqmPowerFunction<T> extends AbstractSqmFunction<T> {
public static final String NAME = "power";

private final SqmExpression base;
private final SqmExpression power;

public SqmPowerFunction(
SqmExpression<?> base,
SqmExpression<?> power,
AllowableFunctionReturnType<T> resultType,
NodeBuilder nodeBuilder) {
super( resultType, nodeBuilder );
this.base = base;
this.power = power;
}

public SqmExpression getBase() {
return base;
}

public SqmExpression getPower() {
return power;
}

@Override
public String getFunctionName() {
return NAME;
}

@Override
public boolean hasArguments() {
return true;
}

@Override
public <T> T accept(SemanticQueryWalker<T> walker) {
return walker.visitPowerFunction( this );
}

@Override
public String asLoggableText() {
return String.format(
Locale.ROOT,
"%s( %s, %s )",
NAME,
base.asLoggableText(),
power.asLoggableText()
);
}
}
Expand Up @@ -48,6 +48,7 @@
import org.hibernate.sql.ast.tree.expression.NonStandardFunction;
import org.hibernate.sql.ast.tree.expression.NullifFunction;
import org.hibernate.sql.ast.tree.expression.PositionalParameter;
import org.hibernate.sql.ast.tree.expression.PowerFunction;
import org.hibernate.sql.ast.tree.expression.QueryLiteral;
import org.hibernate.sql.ast.tree.expression.ReplaceFunction;
import org.hibernate.sql.ast.tree.expression.SqlTuple;
Expand Down Expand Up @@ -697,6 +698,11 @@ public void visitModFunction(ModFunction function) {

}

@Override
public void visitPowerFunction(PowerFunction function) {

}

@Override
public void visitNullifFunction(NullifFunction function) {

Expand Down
Expand Up @@ -633,6 +633,16 @@ public void visitModFunction(ModFunction function) {
sqlAppender.appendSql( CLOSE_PARENTHESIS );
}

@Override
@SuppressWarnings("unchecked")
public void visitPowerFunction(PowerFunction function) {
sqlAppender.appendSql( "power(" );
function.getBase().accept( this );
sqlAppender.appendSql( COMA_SEPARATOR );
function.getPower().accept( this );
sqlAppender.appendSql( CLOSE_PARENTHESIS );
}

@Override
@SuppressWarnings("unchecked")
public void visitSqrtFunction(SqrtFunction function) {
Expand Down

0 comments on commit b8d1f06

Please sign in to comment.