Skip to content

Commit

Permalink
fix: EXPOSED-424 ClassCastException exception when using `fetchBatche…
Browse files Browse the repository at this point in the history
…dResults` with `alias` (#2140)

* fix: EXPOSED-424 ClassCastException exception when using `fetchBatchedResults` with `alias`

* chore: Reduce code duplication
  • Loading branch information
joc-a authored Jul 2, 2024
1 parent 9756454 commit 80d2df4
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ interface ISqlExpressionBuilder {
/** Checks if this [EntityID] expression is less than some [t] value. */
@JvmName("lessEntityID")
infix fun <T : Comparable<T>> Column<EntityID<T>>.less(t: T): LessOp =
LessOp(this, wrap(EntityID(t, (this.foreignKey?.targetTable ?: this.table) as IdTable<T>)))
LessOp(this, wrap(EntityID(t, this.idTable())))

/** Checks if this [EntityID] expression is less than some [other] expression. */
infix fun <T : Comparable<T>, E : EntityID<T>?, V : T?> ExpressionWithColumnType<E>.less(
Expand All @@ -417,7 +417,7 @@ interface ISqlExpressionBuilder {
/** Checks if this [EntityID] expression is less than or equal to some [t] value */
@JvmName("lessEqEntityID")
infix fun <T : Comparable<T>> Column<EntityID<T>>.lessEq(t: T): LessEqOp =
LessEqOp(this, wrap(EntityID(t, (this.foreignKey?.targetTable ?: this.table) as IdTable<T>)))
LessEqOp(this, wrap(EntityID(t, this.idTable())))

/** Checks if this [EntityID] expression is less than or equal to some [other] expression */
infix fun <T : Comparable<T>, E : EntityID<T>?, V : T?> ExpressionWithColumnType<E>.lessEq(
Expand All @@ -441,7 +441,7 @@ interface ISqlExpressionBuilder {
/** Checks if this [EntityID] expression is greater than some [t] value. */
@JvmName("greaterEntityID")
infix fun <T : Comparable<T>> Column<EntityID<T>>.greater(t: T): GreaterOp =
GreaterOp(this, wrap(EntityID(t, (this.foreignKey?.targetTable ?: this.table) as IdTable<T>)))
GreaterOp(this, wrap(EntityID(t, this.idTable())))

/** Checks if this [EntityID] expression is greater than some [other] expression. */
infix fun <T : Comparable<T>, E : EntityID<T>?, V : T?> ExpressionWithColumnType<E>.greater(
Expand All @@ -465,7 +465,7 @@ interface ISqlExpressionBuilder {
/** Checks if this [EntityID] expression is greater than or equal to some [t] value */
@JvmName("greaterEqEntityID")
infix fun <T : Comparable<T>> Column<EntityID<T>>.greaterEq(t: T): GreaterEqOp =
GreaterEqOp(this, wrap(EntityID(t, (this.foreignKey?.targetTable ?: this.table) as IdTable<T>)))
GreaterEqOp(this, wrap(EntityID(t, this.idTable())))

/** Checks if this [EntityID] expression is greater than or equal to some [other] expression */
infix fun <T : Comparable<T>, E : EntityID<T>?, V : T?> ExpressionWithColumnType<E>.greaterEq(
Expand All @@ -484,11 +484,7 @@ interface ISqlExpressionBuilder {

/** Returns `true` if this [EntityID] expression is between the values [from] and [to], `false` otherwise. */
fun <T : Comparable<T>, E : EntityID<T>?> Column<E>.between(from: T, to: T): Between =
Between(
this,
wrap(EntityID(from, (this.foreignKey?.targetTable ?: this.table) as IdTable<T>)),
wrap(EntityID(to, (this.foreignKey?.targetTable ?: this.table) as IdTable<T>))
)
Between(this, wrap(EntityID(from, this.idTable())), wrap(EntityID(to, this.idTable())))

/** Returns `true` if this expression is null, `false` otherwise. */
fun <T> Expression<T>.isNull(): IsNullOp = IsNullOp(this)
Expand All @@ -506,7 +502,7 @@ interface ISqlExpressionBuilder {
/** Checks if this expression is equal to some [t] value, with `null` treated as a comparable value */
@JvmName("isNotDistinctFromEntityID")
infix fun <T : Comparable<T>> Column<EntityID<T>>.isNotDistinctFrom(t: T): IsNotDistinctFromOp =
IsNotDistinctFromOp(this, wrap(EntityID(t, (this.foreignKey?.targetTable ?: this.table) as IdTable<T>)))
IsNotDistinctFromOp(this, wrap(EntityID(t, this.idTable())))

/** Checks if this [EntityID] expression is equal to some [other] expression */
infix fun <T : Comparable<T>, E : EntityID<T>?, V : T?> ExpressionWithColumnType<E>.isNotDistinctFrom(
Expand All @@ -528,7 +524,7 @@ interface ISqlExpressionBuilder {
/** Checks if this expression is not equal to some [t] value, with `null` treated as a comparable value */
@JvmName("isDistinctFromEntityID")
infix fun <T : Comparable<T>> Column<EntityID<T>>.isDistinctFrom(t: T): IsDistinctFromOp =
IsDistinctFromOp(this, wrap(EntityID(t, (this.foreignKey?.targetTable ?: this.table) as IdTable<T>)))
IsDistinctFromOp(this, wrap(EntityID(t, this.idTable())))

/** Checks if this [EntityID] expression is not equal to some [other] expression */
infix fun <T : Comparable<T>, E : EntityID<T>?, V : T?> ExpressionWithColumnType<E>.isDistinctFrom(
Expand Down Expand Up @@ -933,6 +929,12 @@ interface ISqlExpressionBuilder {

fun ExpressionWithColumnType<Int>.intToDecimal(): NoOpConversion<Int, BigDecimal> =
NoOpConversion(this, DecimalColumnType(precision = 15, scale = 0))

private fun <T : Comparable<T>, E : EntityID<T>> Column<out E?>.idTable(): IdTable<T> =
when (val table = this.foreignKey?.targetTable ?: this.table) {
is Alias<*> -> table.delegate
else -> table
} as IdTable<T>
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package org.jetbrains.exposed.sql.tests.shared.dml

import org.jetbrains.exposed.dao.id.IntIdTable
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.ReferenceOption
import org.jetbrains.exposed.sql.SortOrder
import org.jetbrains.exposed.sql.alias
import org.jetbrains.exposed.sql.batchInsert
import org.jetbrains.exposed.sql.insert
import org.jetbrains.exposed.sql.selectAll
import org.jetbrains.exposed.sql.tests.DatabaseTestsBase
import org.jetbrains.exposed.sql.tests.shared.assertEqualLists
import org.junit.Test
Expand Down Expand Up @@ -117,4 +122,16 @@ class FetchBatchedResultsTests : DatabaseTestsBase() {
(tester2 innerJoin tester1).selectAll().fetchBatchedResults(10_000).flatten()
}
}

@Test
fun testFetchBatchedResultsWithAlias() {
val tester = object : IntIdTable("tester") {
val name = varchar("name", 1)
}
withTables(tester) {
tester.insert { it[name] = "a" }
tester.insert { it[name] = "b" }
tester.alias("tester_alias").selectAll().fetchBatchedResults(1).flatten()
}
}
}

0 comments on commit 80d2df4

Please sign in to comment.