From 8bd8a2af98327bd3f50b4e20a9e5b0ed937fd9c6 Mon Sep 17 00:00:00 2001 From: solonovamax Date: Thu, 9 Jan 2025 15:01:03 -0500 Subject: [PATCH] feat: Apply suggested changes - Inherit from Function instead of Op - Make both functions accept varargs - Don't use an infix function for the expression builder Signed-off-by: solonovamax --- .../org/jetbrains/exposed/sql/Function.kt | 38 ++++++++++++++ .../kotlin/org/jetbrains/exposed/sql/Op.kt | 24 --------- .../exposed/sql/SQLExpressionBuilder.kt | 49 ++++++++++++++++--- .../exposed/sql/vendors/FunctionProvider.kt | 18 ++++--- .../exposed/sql/vendors/SQLiteDialect.kt | 12 +++-- 5 files changed, 97 insertions(+), 44 deletions(-) diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Function.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Function.kt index c8e5ccd091..40cfee0eb2 100644 --- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Function.kt +++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Function.kt @@ -65,6 +65,44 @@ class Random( } } +/** + * Represents an SQL operator that returns the greatest (maximum, largest + * value) of [expr1], [expr2], and [others]. + * + * **Note:** The semantics of this function when applied to null values + * or values of multiple types depends on the vendor. Please check the + * documentation for your respective database. + */ +class Greatest( + val expr1: Expression, + val expr2: Expression, + columnType: IColumnType, + vararg val others: Expression +) : Function(columnType) { + override fun toQueryBuilder(queryBuilder: QueryBuilder): Unit = queryBuilder { + currentDialect.functionProvider.greatest(queryBuilder, expr1, expr2, *others) + } +} + +/** + * Represents an SQL operator that returns the least (minimum, smallest + * value) of [expr1], [expr2], and [others]. + * + * **Note:** The semantics of this function when applied to null values + * or values of multiple types depends on the vendor. Please check the + * documentation for your respective database. + */ +class Least( + val expr1: Expression, + val expr2: Expression, + columnType: IColumnType, + vararg val others: Expression +) : Function(columnType) { + override fun toQueryBuilder(queryBuilder: QueryBuilder): Unit = queryBuilder { + currentDialect.functionProvider.least(queryBuilder, expr1, expr2, *others) + } +} + // String Functions /** diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Op.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Op.kt index 4d0dc52fe5..7cb136c30c 100644 --- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Op.kt +++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/Op.kt @@ -299,30 +299,6 @@ class IsDistinctFromOp( } } -/** - * Represents an SQL operator that returns the greatest (maximum) of [expr1] and [expr2]. - */ -class GreatestOp( - val expr1: Expression, - val expr2: Expression, -) : Op() { - override fun toQueryBuilder(queryBuilder: QueryBuilder): Unit = queryBuilder { - currentDialect.functionProvider.greatest(expr1, expr2, queryBuilder) - } -} - -/** - * Represents an SQL operator that returns the least (minimum) of [expr1] and [expr2]. - */ -class LeastOp( - val expr1: Expression, - val expr2: Expression, -) : Op() { - override fun toQueryBuilder(queryBuilder: QueryBuilder): Unit = queryBuilder { - currentDialect.functionProvider.least(expr1, expr2, queryBuilder) - } -} - // Mathematical Operators /** diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/SQLExpressionBuilder.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/SQLExpressionBuilder.kt index 8bd7992f1b..3d176d480f 100644 --- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/SQLExpressionBuilder.kt +++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/SQLExpressionBuilder.kt @@ -580,24 +580,57 @@ interface ISqlExpressionBuilder { ): IsDistinctFromOp = IsDistinctFromOp(this, other) /** - * The greatest (maximum) of this expression and [t]. + * The greatest (maximum, largest value) of [expr1], [expr2], and [others]. + * + * **Note:** The semantics of this function when applied to null values + * or values of multiple types depends on the vendor. Please check the + * documentation for your respective database. */ - infix fun ExpressionWithColumnType.greatest(t: T): GreatestOp = GreatestOp(this, wrap(t)) + fun greatest( + expr1: ExpressionWithColumnType, + expr2: Expression, + vararg others: Expression, + ): Greatest = Greatest(expr1, expr2, expr1.columnType, *others) /** - * The greatest (maximum) of this expression and [other]. + * The greatest (maximum, largest value) of [literal], [expr1], and + * [others]. + * + * **Note:** The semantics of this function when applied to null values + * or values of multiple types depends on the vendor. Please check the + * documentation for your respective database. */ - infix fun ExpressionWithColumnType.greatest(other: Expression): GreatestOp = GreatestOp(this, other) + fun greatest( + literal: T, + expr1: ExpressionWithColumnType, + vararg others: Expression, + ): Greatest = Greatest(expr1.wrap(literal), expr1, expr1.columnType, *others) /** - * The least (minimum) of this expression and [t]. + * The least (minimum, smallest value) of [expr1], [expr2], and [others]. + * + * **Note:** The semantics of this function when applied to null values + * or values of multiple types depends on the vendor. Please check the + * documentation for your respective database. */ - infix fun ExpressionWithColumnType.least(t: T): LeastOp = LeastOp(this, wrap(t)) + fun least( + expr1: ExpressionWithColumnType, + expr2: Expression, + vararg others: Expression, + ): Least = Least(expr1, expr2, expr1.columnType, *others) /** - * The least (minimum) of this expression and [other]. + * The least (minimum, smallest value) of [literal], [expr1], and [others]. + * + * **Note:** The semantics of this function when applied to null values + * or values of multiple types depends on the vendor. Please check the + * documentation for your respective database. */ - infix fun ExpressionWithColumnType.least(other: Expression): LeastOp = LeastOp(this, other) + fun least( + literal: T, + expr1: ExpressionWithColumnType, + vararg others: Expression, + ): Least = Least(expr1.wrap(literal), expr1, expr1.columnType, *others) // Mathematical Operators diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/FunctionProvider.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/FunctionProvider.kt index 601eb7ba3e..b6e083d4d5 100644 --- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/FunctionProvider.kt +++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/FunctionProvider.kt @@ -37,23 +37,25 @@ abstract class FunctionProvider { /** * SQL function that returns the greatest (maximum) of two values. * - * @param expr1 The first value. - * @param expr2 The second value. * @param queryBuilder Query builder to append the SQL function to. + * @param expr The expressions to compare. */ - open fun greatest(expr1: Expression, expr2: Expression, queryBuilder: QueryBuilder): Unit = queryBuilder { - append("GREATEST(", expr1, ", ", expr2, ")") + open fun greatest(queryBuilder: QueryBuilder, vararg expr: Expression): Unit = queryBuilder { + append("GREATEST(") + expr.appendTo { +it } + append(")") } /** * SQL function that returns the least (minimum) of two values. * - * @param expr1 The first value. - * @param expr2 The second value. * @param queryBuilder Query builder to append the SQL function to. + * @param expr The expressions to compare. */ - open fun least(expr1: Expression, expr2: Expression, queryBuilder: QueryBuilder): Unit = queryBuilder { - append("LEAST(", expr1, ", ", expr2, ")") + open fun least(queryBuilder: QueryBuilder, vararg expr: Expression): Unit = queryBuilder { + append("LEAST(") + expr.appendTo { +it } + append(")") } // String functions diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/SQLiteDialect.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/SQLiteDialect.kt index ad000b1cb9..99596697ae 100644 --- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/SQLiteDialect.kt +++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/vendors/SQLiteDialect.kt @@ -25,12 +25,16 @@ internal object SQLiteDataTypeProvider : DataTypeProvider() { @Suppress("TooManyFunctions") internal object SQLiteFunctionProvider : FunctionProvider() { - override fun greatest(expr1: Expression, expr2: Expression, queryBuilder: QueryBuilder) = queryBuilder { - append("MAX(", expr1, ", ", expr2, ")") + override fun greatest(queryBuilder: QueryBuilder, vararg expr: Expression) = queryBuilder { + append("MAX(") + expr.appendTo { +it } + append(")") } - override fun least(expr1: Expression, expr2: Expression, queryBuilder: QueryBuilder) = queryBuilder { - append("MIN(", expr1, ", ", expr2, ")") + override fun least(queryBuilder: QueryBuilder, vararg expr: Expression) = queryBuilder { + append("MIN(") + expr.appendTo { +it } + append(")") } override fun charLength(expr: Expression, queryBuilder: QueryBuilder) = queryBuilder {