Skip to content

Commit

Permalink
refactor: Make call to registerArgument function type-safe in AllAn…
Browse files Browse the repository at this point in the history
…yFromArrayOp.kt

When calling the `registerArgument` function in the overriden `registerSubSearchArgument` function in `AllAnyFromArrayOp`, there is a type mismatch between `sqlType` and `argument`'s type because there is a compile-time guarantee that ArrayColumnType only receives a value of type `List` and not `Array`. This mismatch results in a compilation error when trying to guarantee type-safety with the refactor of IColumnType. Therefore, this is a necessary preparation step for the refactor of IColumnType to make it and its subclasses type-safe.

To avoid introducing a breaking change, the functions `anyFrom` and `allFrom` in SQLExpressionBuilder.kt retain the same signature, but convert the `Array` to a `List`. In addition, these two functions were overloaded with ones that accept `List` instead of `Array`.
  • Loading branch information
joc-a committed Feb 28, 2024
1 parent 3215927 commit b70b683
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 6 deletions.
4 changes: 2 additions & 2 deletions exposed-core/api/exposed-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -2696,9 +2696,9 @@ public final class org/jetbrains/exposed/sql/functions/math/TanFunction : org/je
}

public final class org/jetbrains/exposed/sql/ops/AllAnyFromArrayOp : org/jetbrains/exposed/sql/ops/AllAnyFromBaseOp {
public fun <init> (Z[Ljava/lang/Object;Lorg/jetbrains/exposed/sql/ColumnType;)V
public fun <init> (ZLjava/util/List;Lorg/jetbrains/exposed/sql/ColumnType;)V
public synthetic fun registerSubSearchArgument (Lorg/jetbrains/exposed/sql/QueryBuilder;Ljava/lang/Object;)V
public fun registerSubSearchArgument (Lorg/jetbrains/exposed/sql/QueryBuilder;[Ljava/lang/Object;)V
public fun registerSubSearchArgument (Lorg/jetbrains/exposed/sql/QueryBuilder;Ljava/util/List;)V
}

public abstract class org/jetbrains/exposed/sql/ops/AllAnyFromBaseOp : org/jetbrains/exposed/sql/Op {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,21 @@ inline fun <reified T : Any> anyFrom(array: Array<T>, delegateType: ColumnType?
// emptyArray() without type info generates ARRAY[]
@OptIn(InternalApi::class)
val columnType = delegateType ?: resolveColumnType(T::class, if (array.isEmpty()) TextColumnType() else null)
return AllAnyFromArrayOp(true, array.toList(), columnType)
}

/**
* Returns this list of data wrapped in the `ANY` operator. This function is only supported by PostgreSQL and H2 dialects.
*
* **Note** If [delegateType] is left `null`, the base column type associated with storing elements of type [T] will be
* resolved according to the internal mapping of the element's type in [resolveColumnType].
*
* @throws IllegalStateException If no column type mapping is found and a [delegateType] is not provided.
*/
inline fun <reified T : Any> anyFrom(array: List<T>, delegateType: ColumnType? = null): Op<T> {
// emptyList() without type info generates ARRAY[]
@OptIn(InternalApi::class)
val columnType = delegateType ?: resolveColumnType(T::class, if (array.isEmpty()) TextColumnType() else null)
return AllAnyFromArrayOp(true, array, columnType)
}

Expand All @@ -152,6 +167,21 @@ inline fun <reified T : Any> allFrom(array: Array<T>, delegateType: ColumnType?
// emptyArray() without type info generates ARRAY[]
@OptIn(InternalApi::class)
val columnType = delegateType ?: resolveColumnType(T::class, if (array.isEmpty()) TextColumnType() else null)
return AllAnyFromArrayOp(false, array.toList(), columnType)
}

/**
* Returns this list of data wrapped in the `ALL` operator. This function is only supported by PostgreSQL and H2 dialects.
*
* **Note** If [delegateType] is left `null`, the base column type associated with storing elements of type [T] will be
* resolved according to the internal mapping of the element's type in [resolveColumnType].
*
* @throws IllegalStateException If no column type mapping is found and a [delegateType] is not provided.
*/
inline fun <reified T : Any> allFrom(array: List<T>, delegateType: ColumnType? = null): Op<T> {
// emptyList() without type info generates ARRAY[]
@OptIn(InternalApi::class)
val columnType = delegateType ?: resolveColumnType(T::class, if (array.isEmpty()) TextColumnType() else null)
return AllAnyFromArrayOp(false, array, columnType)
}

Expand All @@ -177,7 +207,7 @@ infix operator fun <E, T : List<E>?> ExpressionWithColumnType<T>.get(index: Int)
* @sample org.jetbrains.exposed.sql.tests.shared.types.ArrayColumnTypeTests.testSelectUsingArraySlice
*/
fun <E, T : List<E>?> ExpressionWithColumnType<T>.slice(lower: Int? = null, upper: Int? = null): ArraySlice<E, T> =
ArraySlice(this, lower, upper, ArrayColumnType((this.columnType as ArrayColumnType).delegate))
ArraySlice(this, lower, upper, this.columnType as ArrayColumnType)

// Sequence Manipulation Functions

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ class AllAnyFromSubQueryOp<T>(
*/
class AllAnyFromArrayOp<T : Any>(
isAny: Boolean,
array: Array<T>,
array: List<T>,
private val delegateType: ColumnType
) : AllAnyFromBaseOp<T, Array<T>>(isAny, array) {
override fun QueryBuilder.registerSubSearchArgument(subSearch: Array<T>) {
) : AllAnyFromBaseOp<T, List<T>>(isAny, array) {
override fun QueryBuilder.registerSubSearchArgument(subSearch: List<T>) {
registerArgument(ArrayColumnType(delegateType), subSearch)
}
}
Expand Down

0 comments on commit b70b683

Please sign in to comment.