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 f2126da180..88e7115662 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 @@ -126,68 +126,6 @@ inline fun ExpressionWithColumnType<*>.jsonExtract(vararg path return JsonExtract(this, path = path, toScalar, this.columnType, columnType) } -// Window Functions - -/** Returns the number of the current row within its partition, counting from 1. */ -fun rowNumber(): RowNumber = RowNumber() - -/** Returns the rank of the current row, with gaps; that is, the row_number of the first row in its peer group. */ -fun rank(): Rank = Rank() - -/** Returns the rank of the current row, without gaps; this function effectively counts peer groups. */ -fun denseRank(): DenseRank = DenseRank() - -/** - * Returns the relative rank of the current row, that is (rank - 1) / (total partition rows - 1). - * The value thus ranges from 0 to 1 inclusive. - */ -fun percentRank(): PercentRank = PercentRank() - -/** - * Returns the cumulative distribution, that is (number of partition rows preceding or peers with current row) / - * (total partition rows). The value thus ranges from 1/N to 1. - */ -fun cumeDist(): CumeDist = CumeDist() - -/** Returns an integer ranging from 1 to the [numBuckets], dividing the partition as equally as possible. */ -fun ntile(numBuckets: ExpressionWithColumnType): Ntile = Ntile(numBuckets) - -/** - * Returns value evaluated at the row that is [offset] rows before the current row within the partition; - * if there is no such row, instead returns [defaultValue]. - * Both [offset] and [defaultValue] are evaluated with respect to the current row. - */ -fun ExpressionWithColumnType.lag( - offset: ExpressionWithColumnType = intLiteral(1), - defaultValue: ExpressionWithColumnType? = null -): Lag = Lag(this, offset, defaultValue) - -/** - * Returns value evaluated at the row that is [offset] rows after the current row within the partition; - * if there is no such row, instead returns [defaultValue]. - * Both [offset] and [defaultValue] are evaluated with respect to the current row. - */ -fun ExpressionWithColumnType.lead( - offset: ExpressionWithColumnType = intLiteral(1), - defaultValue: ExpressionWithColumnType? = null -): Lead = Lead(this, offset, defaultValue) - -/** - * Returns value evaluated at the row that is the first row of the window frame. - */ -fun ExpressionWithColumnType.firstValue(): FirstValue = FirstValue(this) - -/** - * Returns value evaluated at the row that is the last row of the window frame. - */ -fun ExpressionWithColumnType.lastValue(): LastValue = LastValue(this) - -/** - * Returns value evaluated at the row that is the [n]'th row of the window frame - * (counting from 1); null if no such row. - */ -fun ExpressionWithColumnType.nthValue(n: ExpressionWithColumnType): NthValue = NthValue(this, n) - // Sequence Manipulation Functions /** Advances this sequence and returns the new value. */ @@ -588,6 +526,68 @@ interface ISqlExpressionBuilder { caseSensitive: Boolean = true ): RegexpOp = RegexpOp(this, pattern, caseSensitive) + // Window Functions + + /** Returns the number of the current row within its partition, counting from 1. */ + fun rowNumber(): RowNumber = RowNumber() + + /** Returns the rank of the current row, with gaps; that is, the row_number of the first row in its peer group. */ + fun rank(): Rank = Rank() + + /** Returns the rank of the current row, without gaps; this function effectively counts peer groups. */ + fun denseRank(): DenseRank = DenseRank() + + /** + * Returns the relative rank of the current row, that is (rank - 1) / (total partition rows - 1). + * The value thus ranges from 0 to 1 inclusive. + */ + fun percentRank(): PercentRank = PercentRank() + + /** + * Returns the cumulative distribution, that is (number of partition rows preceding or peers with current row) / + * (total partition rows). The value thus ranges from 1/N to 1. + */ + fun cumeDist(): CumeDist = CumeDist() + + /** Returns an integer ranging from 1 to the [numBuckets], dividing the partition as equally as possible. */ + fun ntile(numBuckets: ExpressionWithColumnType): Ntile = Ntile(numBuckets) + + /** + * Returns value evaluated at the row that is [offset] rows before the current row within the partition; + * if there is no such row, instead returns [defaultValue]. + * Both [offset] and [defaultValue] are evaluated with respect to the current row. + */ + fun ExpressionWithColumnType.lag( + offset: ExpressionWithColumnType = intLiteral(1), + defaultValue: ExpressionWithColumnType? = null + ): Lag = Lag(this, offset, defaultValue) + + /** + * Returns value evaluated at the row that is [offset] rows after the current row within the partition; + * if there is no such row, instead returns [defaultValue]. + * Both [offset] and [defaultValue] are evaluated with respect to the current row. + */ + fun ExpressionWithColumnType.lead( + offset: ExpressionWithColumnType = intLiteral(1), + defaultValue: ExpressionWithColumnType? = null + ): Lead = Lead(this, offset, defaultValue) + + /** + * Returns value evaluated at the row that is the first row of the window frame. + */ + fun ExpressionWithColumnType.firstValue(): FirstValue = FirstValue(this) + + /** + * Returns value evaluated at the row that is the last row of the window frame. + */ + fun ExpressionWithColumnType.lastValue(): LastValue = LastValue(this) + + /** + * Returns value evaluated at the row that is the [n]'th row of the window frame + * (counting from 1); null if no such row. + */ + fun ExpressionWithColumnType.nthValue(n: ExpressionWithColumnType): NthValue = NthValue(this, n) + // JSON Conditions /** diff --git a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/functions/WindowFunctionsTests.kt b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/functions/WindowFunctionsTests.kt index fed13d4841..377c4e46f6 100644 --- a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/functions/WindowFunctionsTests.kt +++ b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/functions/WindowFunctionsTests.kt @@ -1,8 +1,19 @@ package org.jetbrains.exposed.sql.tests.shared.functions import org.jetbrains.exposed.sql.* +import org.jetbrains.exposed.sql.SqlExpressionBuilder.cumeDist +import org.jetbrains.exposed.sql.SqlExpressionBuilder.denseRank +import org.jetbrains.exposed.sql.SqlExpressionBuilder.firstValue +import org.jetbrains.exposed.sql.SqlExpressionBuilder.lag +import org.jetbrains.exposed.sql.SqlExpressionBuilder.lastValue +import org.jetbrains.exposed.sql.SqlExpressionBuilder.lead import org.jetbrains.exposed.sql.SqlExpressionBuilder.minus +import org.jetbrains.exposed.sql.SqlExpressionBuilder.nthValue +import org.jetbrains.exposed.sql.SqlExpressionBuilder.ntile +import org.jetbrains.exposed.sql.SqlExpressionBuilder.percentRank import org.jetbrains.exposed.sql.SqlExpressionBuilder.plus +import org.jetbrains.exposed.sql.SqlExpressionBuilder.rank +import org.jetbrains.exposed.sql.SqlExpressionBuilder.rowNumber import org.jetbrains.exposed.sql.tests.DatabaseTestsBase import org.jetbrains.exposed.sql.tests.TestDB.* import org.jetbrains.exposed.sql.tests.TestDB.Companion.allH2TestDB