Skip to content

Commit

Permalink
feat: Add ALL and ANY operators accepting array, subquery, or tab…
Browse files Browse the repository at this point in the history
…le parameters (#1886)

* Initially implement `allOp` and `anyOp` for `Iterable<T>` and add some simple tests which are not run yet

* Pass arrays instead of lists/iterables, getting `testEqAny` (for an array of strings) to work on PostgreSQL (`postgres` and `postgresNG`)

Cherry-picked from: 7dd846b

* Add an alternative custom function implementation of `ALL` and `ANY` and refactor to simplify the `AllAnyOp` implementation

As tested, it works for H2 as well in addition to PostgreSQL.

* Improve code, add comments, and skip tests on unsupported dialects

* Add a KDoc line

* Add some more KDocs, add an `eqAny` shortcut, and fix a typo

* Describe return types explicitly to conform to the contributing guidelines

* Run `apiDump` again

* Refactor and improve as requested by @bog-walk

Major changes:
1. support the `ALL` and `ANY` operators taking subquery arguments and table arguments, and the `IN` operator taking table arguments
1. remove some no longer needed code, simplify code, and rename some functions
1. add related tests
1. run `apiDump`

The operators (`IN`, `ANY`, and `ALL`) with table arguments are only supported by PostgreSQL and H2. MySQL claims supporting this but it does not work with the JDBC driver as tested. Those with subquery arguments are not supported by SQLite.

* Complete the remaining tests

* Fix code issues as requested by @bog-walk

* AutoCorrect by detekt rules
  • Loading branch information
ShreckYe authored Jan 3, 2024
1 parent 5a4275d commit 98df06d
Show file tree
Hide file tree
Showing 11 changed files with 342 additions and 5 deletions.
53 changes: 53 additions & 0 deletions exposed-core/api/exposed-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,7 @@ public abstract interface class org/jetbrains/exposed/sql/ISqlExpressionBuilder
public abstract fun inList (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;Ljava/lang/Iterable;)Lorg/jetbrains/exposed/sql/ops/InListOrNotInListBaseOp;
public abstract fun inListIds (Lorg/jetbrains/exposed/sql/Column;Ljava/lang/Iterable;)Lorg/jetbrains/exposed/sql/ops/InListOrNotInListBaseOp;
public abstract fun inSubQuery (Lorg/jetbrains/exposed/sql/Expression;Lorg/jetbrains/exposed/sql/AbstractQuery;)Lorg/jetbrains/exposed/sql/InSubQueryOp;
public abstract fun inTable (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;Lorg/jetbrains/exposed/sql/Table;)Lorg/jetbrains/exposed/sql/ops/InTableOp;
public abstract fun intToDecimal (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;)Lorg/jetbrains/exposed/sql/NoOpConversion;
public abstract fun isDistinctFrom (Lorg/jetbrains/exposed/sql/Expression;Lorg/jetbrains/exposed/sql/Expression;)Lorg/jetbrains/exposed/sql/IsDistinctFromOp;
public abstract fun isDistinctFrom (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;Ljava/lang/Comparable;)Lorg/jetbrains/exposed/sql/IsDistinctFromOp;
Expand Down Expand Up @@ -967,6 +968,7 @@ public abstract interface class org/jetbrains/exposed/sql/ISqlExpressionBuilder
public abstract fun notInList (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;Ljava/lang/Iterable;)Lorg/jetbrains/exposed/sql/ops/InListOrNotInListBaseOp;
public abstract fun notInListIds (Lorg/jetbrains/exposed/sql/Column;Ljava/lang/Iterable;)Lorg/jetbrains/exposed/sql/ops/InListOrNotInListBaseOp;
public abstract fun notInSubQuery (Lorg/jetbrains/exposed/sql/Expression;Lorg/jetbrains/exposed/sql/AbstractQuery;)Lorg/jetbrains/exposed/sql/NotInSubQueryOp;
public abstract fun notInTable (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;Lorg/jetbrains/exposed/sql/Table;)Lorg/jetbrains/exposed/sql/ops/InTableOp;
public abstract fun notLike (Lorg/jetbrains/exposed/sql/Expression;Ljava/lang/String;)Lorg/jetbrains/exposed/sql/LikeEscapeOp;
public abstract fun notLike (Lorg/jetbrains/exposed/sql/Expression;Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;)Lorg/jetbrains/exposed/sql/LikeEscapeOp;
public abstract fun notLike (Lorg/jetbrains/exposed/sql/Expression;Lorg/jetbrains/exposed/sql/LikePattern;)Lorg/jetbrains/exposed/sql/LikeEscapeOp;
Expand Down Expand Up @@ -1030,6 +1032,7 @@ public final class org/jetbrains/exposed/sql/ISqlExpressionBuilder$DefaultImpls
public static fun inList (Lorg/jetbrains/exposed/sql/ISqlExpressionBuilder;Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;Ljava/lang/Iterable;)Lorg/jetbrains/exposed/sql/ops/InListOrNotInListBaseOp;
public static fun inListIds (Lorg/jetbrains/exposed/sql/ISqlExpressionBuilder;Lorg/jetbrains/exposed/sql/Column;Ljava/lang/Iterable;)Lorg/jetbrains/exposed/sql/ops/InListOrNotInListBaseOp;
public static fun inSubQuery (Lorg/jetbrains/exposed/sql/ISqlExpressionBuilder;Lorg/jetbrains/exposed/sql/Expression;Lorg/jetbrains/exposed/sql/AbstractQuery;)Lorg/jetbrains/exposed/sql/InSubQueryOp;
public static fun inTable (Lorg/jetbrains/exposed/sql/ISqlExpressionBuilder;Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;Lorg/jetbrains/exposed/sql/Table;)Lorg/jetbrains/exposed/sql/ops/InTableOp;
public static fun intToDecimal (Lorg/jetbrains/exposed/sql/ISqlExpressionBuilder;Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;)Lorg/jetbrains/exposed/sql/NoOpConversion;
public static fun isDistinctFrom (Lorg/jetbrains/exposed/sql/ISqlExpressionBuilder;Lorg/jetbrains/exposed/sql/Expression;Lorg/jetbrains/exposed/sql/Expression;)Lorg/jetbrains/exposed/sql/IsDistinctFromOp;
public static fun isDistinctFrom (Lorg/jetbrains/exposed/sql/ISqlExpressionBuilder;Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;Ljava/lang/Comparable;)Lorg/jetbrains/exposed/sql/IsDistinctFromOp;
Expand Down Expand Up @@ -1074,6 +1077,7 @@ public final class org/jetbrains/exposed/sql/ISqlExpressionBuilder$DefaultImpls
public static fun notInList (Lorg/jetbrains/exposed/sql/ISqlExpressionBuilder;Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;Ljava/lang/Iterable;)Lorg/jetbrains/exposed/sql/ops/InListOrNotInListBaseOp;
public static fun notInListIds (Lorg/jetbrains/exposed/sql/ISqlExpressionBuilder;Lorg/jetbrains/exposed/sql/Column;Ljava/lang/Iterable;)Lorg/jetbrains/exposed/sql/ops/InListOrNotInListBaseOp;
public static fun notInSubQuery (Lorg/jetbrains/exposed/sql/ISqlExpressionBuilder;Lorg/jetbrains/exposed/sql/Expression;Lorg/jetbrains/exposed/sql/AbstractQuery;)Lorg/jetbrains/exposed/sql/NotInSubQueryOp;
public static fun notInTable (Lorg/jetbrains/exposed/sql/ISqlExpressionBuilder;Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;Lorg/jetbrains/exposed/sql/Table;)Lorg/jetbrains/exposed/sql/ops/InTableOp;
public static fun notLike (Lorg/jetbrains/exposed/sql/ISqlExpressionBuilder;Lorg/jetbrains/exposed/sql/Expression;Ljava/lang/String;)Lorg/jetbrains/exposed/sql/LikeEscapeOp;
public static fun notLike (Lorg/jetbrains/exposed/sql/ISqlExpressionBuilder;Lorg/jetbrains/exposed/sql/Expression;Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;)Lorg/jetbrains/exposed/sql/LikeEscapeOp;
public static fun notLike (Lorg/jetbrains/exposed/sql/ISqlExpressionBuilder;Lorg/jetbrains/exposed/sql/Expression;Lorg/jetbrains/exposed/sql/LikePattern;)Lorg/jetbrains/exposed/sql/LikeEscapeOp;
Expand Down Expand Up @@ -1734,6 +1738,12 @@ public final class org/jetbrains/exposed/sql/RowNumber : org/jetbrains/exposed/s
public final class org/jetbrains/exposed/sql/SQLExpressionBuilderKt {
public static final fun CustomLongFunction (Ljava/lang/String;[Lorg/jetbrains/exposed/sql/Expression;)Lorg/jetbrains/exposed/sql/CustomFunction;
public static final fun CustomStringFunction (Ljava/lang/String;[Lorg/jetbrains/exposed/sql/Expression;)Lorg/jetbrains/exposed/sql/CustomFunction;
public static final fun allFrom (Lorg/jetbrains/exposed/sql/AbstractQuery;)Lorg/jetbrains/exposed/sql/Op;
public static final fun allFrom (Lorg/jetbrains/exposed/sql/Table;)Lorg/jetbrains/exposed/sql/Op;
public static final fun allFrom ([Ljava/lang/Object;)Lorg/jetbrains/exposed/sql/Op;
public static final fun anyFrom (Lorg/jetbrains/exposed/sql/AbstractQuery;)Lorg/jetbrains/exposed/sql/Op;
public static final fun anyFrom (Lorg/jetbrains/exposed/sql/Table;)Lorg/jetbrains/exposed/sql/Op;
public static final fun anyFrom ([Ljava/lang/Object;)Lorg/jetbrains/exposed/sql/Op;
public static final fun avg (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;I)Lorg/jetbrains/exposed/sql/Avg;
public static synthetic fun avg$default (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;IILjava/lang/Object;)Lorg/jetbrains/exposed/sql/Avg;
public static final fun castTo (Lorg/jetbrains/exposed/sql/Expression;Lorg/jetbrains/exposed/sql/IColumnType;)Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;
Expand Down Expand Up @@ -1974,6 +1984,7 @@ public final class org/jetbrains/exposed/sql/SqlExpressionBuilder : org/jetbrain
public fun inList (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;Ljava/lang/Iterable;)Lorg/jetbrains/exposed/sql/ops/InListOrNotInListBaseOp;
public fun inListIds (Lorg/jetbrains/exposed/sql/Column;Ljava/lang/Iterable;)Lorg/jetbrains/exposed/sql/ops/InListOrNotInListBaseOp;
public fun inSubQuery (Lorg/jetbrains/exposed/sql/Expression;Lorg/jetbrains/exposed/sql/AbstractQuery;)Lorg/jetbrains/exposed/sql/InSubQueryOp;
public fun inTable (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;Lorg/jetbrains/exposed/sql/Table;)Lorg/jetbrains/exposed/sql/ops/InTableOp;
public fun intToDecimal (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;)Lorg/jetbrains/exposed/sql/NoOpConversion;
public fun isDistinctFrom (Lorg/jetbrains/exposed/sql/Expression;Lorg/jetbrains/exposed/sql/Expression;)Lorg/jetbrains/exposed/sql/IsDistinctFromOp;
public fun isDistinctFrom (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;Ljava/lang/Comparable;)Lorg/jetbrains/exposed/sql/IsDistinctFromOp;
Expand Down Expand Up @@ -2016,6 +2027,7 @@ public final class org/jetbrains/exposed/sql/SqlExpressionBuilder : org/jetbrain
public fun notInList (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;Ljava/lang/Iterable;)Lorg/jetbrains/exposed/sql/ops/InListOrNotInListBaseOp;
public fun notInListIds (Lorg/jetbrains/exposed/sql/Column;Ljava/lang/Iterable;)Lorg/jetbrains/exposed/sql/ops/InListOrNotInListBaseOp;
public fun notInSubQuery (Lorg/jetbrains/exposed/sql/Expression;Lorg/jetbrains/exposed/sql/AbstractQuery;)Lorg/jetbrains/exposed/sql/NotInSubQueryOp;
public fun notInTable (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;Lorg/jetbrains/exposed/sql/Table;)Lorg/jetbrains/exposed/sql/ops/InTableOp;
public fun notLike (Lorg/jetbrains/exposed/sql/Expression;Ljava/lang/String;)Lorg/jetbrains/exposed/sql/LikeEscapeOp;
public fun notLike (Lorg/jetbrains/exposed/sql/Expression;Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;)Lorg/jetbrains/exposed/sql/LikeEscapeOp;
public fun notLike (Lorg/jetbrains/exposed/sql/Expression;Lorg/jetbrains/exposed/sql/LikePattern;)Lorg/jetbrains/exposed/sql/LikeEscapeOp;
Expand Down Expand Up @@ -2391,6 +2403,11 @@ public final class org/jetbrains/exposed/sql/UnionAll : org/jetbrains/exposed/sq
public fun withDistinct (Z)Lorg/jetbrains/exposed/sql/SetOperation;
}

public final class org/jetbrains/exposed/sql/UntypedAndUnsizedArrayColumnType : org/jetbrains/exposed/sql/ColumnType {
public static final field INSTANCE Lorg/jetbrains/exposed/sql/UntypedAndUnsizedArrayColumnType;
public fun sqlType ()Ljava/lang/String;
}

public final class org/jetbrains/exposed/sql/UpperCase : org/jetbrains/exposed/sql/Function {
public fun <init> (Lorg/jetbrains/exposed/sql/Expression;)V
public final fun getExpr ()Lorg/jetbrains/exposed/sql/Expression;
Expand Down Expand Up @@ -2572,6 +2589,32 @@ public final class org/jetbrains/exposed/sql/functions/math/TanFunction : org/je
public fun <init> (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;)V
}

public final class org/jetbrains/exposed/sql/ops/AllAnyFromArrayOp : org/jetbrains/exposed/sql/ops/AllAnyFromBaseOp {
public fun <init> (Z[Ljava/lang/Object;)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 abstract class org/jetbrains/exposed/sql/ops/AllAnyFromBaseOp : org/jetbrains/exposed/sql/Op {
public fun <init> (ZLjava/lang/Object;)V
public final fun getSubSearch ()Ljava/lang/Object;
public final fun isAny ()Z
public abstract fun registerSubSearchArgument (Lorg/jetbrains/exposed/sql/QueryBuilder;Ljava/lang/Object;)V
public fun toQueryBuilder (Lorg/jetbrains/exposed/sql/QueryBuilder;)V
}

public final class org/jetbrains/exposed/sql/ops/AllAnyFromSubQueryOp : org/jetbrains/exposed/sql/ops/AllAnyFromBaseOp {
public fun <init> (ZLorg/jetbrains/exposed/sql/AbstractQuery;)V
public synthetic fun registerSubSearchArgument (Lorg/jetbrains/exposed/sql/QueryBuilder;Ljava/lang/Object;)V
public fun registerSubSearchArgument (Lorg/jetbrains/exposed/sql/QueryBuilder;Lorg/jetbrains/exposed/sql/AbstractQuery;)V
}

public final class org/jetbrains/exposed/sql/ops/AllAnyFromTableOp : org/jetbrains/exposed/sql/ops/AllAnyFromBaseOp {
public fun <init> (ZLorg/jetbrains/exposed/sql/Table;)V
public synthetic fun registerSubSearchArgument (Lorg/jetbrains/exposed/sql/QueryBuilder;Ljava/lang/Object;)V
public fun registerSubSearchArgument (Lorg/jetbrains/exposed/sql/QueryBuilder;Lorg/jetbrains/exposed/sql/Table;)V
}

public abstract class org/jetbrains/exposed/sql/ops/InListOrNotInListBaseOp : org/jetbrains/exposed/sql/Op, org/jetbrains/exposed/sql/ComplexExpression {
public fun <init> (Ljava/lang/Object;Ljava/lang/Iterable;Z)V
public synthetic fun <init> (Ljava/lang/Object;Ljava/lang/Iterable;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
Expand All @@ -2583,6 +2626,15 @@ public abstract class org/jetbrains/exposed/sql/ops/InListOrNotInListBaseOp : or
public fun toQueryBuilder (Lorg/jetbrains/exposed/sql/QueryBuilder;)V
}

public final class org/jetbrains/exposed/sql/ops/InTableOp : org/jetbrains/exposed/sql/Op, org/jetbrains/exposed/sql/ComplexExpression {
public fun <init> (Lorg/jetbrains/exposed/sql/Expression;Lorg/jetbrains/exposed/sql/Table;Z)V
public synthetic fun <init> (Lorg/jetbrains/exposed/sql/Expression;Lorg/jetbrains/exposed/sql/Table;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun getExpr ()Lorg/jetbrains/exposed/sql/Expression;
public final fun getTable ()Lorg/jetbrains/exposed/sql/Table;
public final fun isInTable ()Z
public fun toQueryBuilder (Lorg/jetbrains/exposed/sql/QueryBuilder;)V
}

public final class org/jetbrains/exposed/sql/ops/PairInListOp : org/jetbrains/exposed/sql/ops/InListOrNotInListBaseOp {
public fun <init> (Lkotlin/Pair;Ljava/lang/Iterable;Z)V
public synthetic fun <init> (Lkotlin/Pair;Ljava/lang/Iterable;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
Expand Down Expand Up @@ -3150,6 +3202,7 @@ public abstract class org/jetbrains/exposed/sql/vendors/DataTypeProvider {
public fun ubyteType ()Ljava/lang/String;
public fun uintegerType ()Ljava/lang/String;
public fun ulongType ()Ljava/lang/String;
public fun untypedAndUnsizedArrayType ()Ljava/lang/String;
public fun ushortType ()Ljava/lang/String;
public fun uuidToDB (Ljava/util/UUID;)Ljava/lang/Object;
public fun uuidType ()Ljava/lang/String;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -997,6 +997,11 @@ class CustomEnumerationColumnType<T : Enum<T>>(
override fun nonNullValueToString(value: Any): String = super.nonNullValueToString(notNullValueToDB(value))
}

object UntypedAndUnsizedArrayColumnType : ColumnType() {
override fun sqlType(): String =
currentDialect.dataTypeProvider.untypedAndUnsizedArrayType()
}

// Date/Time columns

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ package org.jetbrains.exposed.sql
import org.jetbrains.exposed.dao.id.EntityID
import org.jetbrains.exposed.dao.id.EntityIDFunctionProvider
import org.jetbrains.exposed.dao.id.IdTable
import org.jetbrains.exposed.sql.ops.InListOrNotInListBaseOp
import org.jetbrains.exposed.sql.ops.PairInListOp
import org.jetbrains.exposed.sql.ops.SingleValueInListOp
import org.jetbrains.exposed.sql.ops.TripleInListOp
import org.jetbrains.exposed.sql.ops.*
import org.jetbrains.exposed.sql.vendors.FunctionProvider
import org.jetbrains.exposed.sql.vendors.currentDialect
import java.math.BigDecimal
Expand Down Expand Up @@ -112,6 +109,26 @@ fun <T : Any?> ExpressionWithColumnType<T>.varPop(scale: Int = 2): VarPop<T> = V
*/
fun <T : Any?> ExpressionWithColumnType<T>.varSamp(scale: Int = 2): VarSamp<T> = VarSamp(this, scale)

// Array Comparisons

/** Returns this subquery wrapped in the `ANY` operator. This function is not supported by the SQLite dialect. */
fun <T> anyFrom(subQuery: AbstractQuery<*>): Op<T> = AllAnyFromSubQueryOp(true, subQuery)

/** Returns this array of data wrapped in the `ANY` operator. This function is only supported by PostgreSQL and H2 dialects. */
fun <T> anyFrom(array: Array<T>): Op<T> = AllAnyFromArrayOp(true, array)

/** Returns this table wrapped in the `ANY` operator. This function is only supported by MySQL, PostgreSQL, and H2 dialects. */
fun <T> anyFrom(table: Table): Op<T> = AllAnyFromTableOp(true, table)

/** Returns this subquery wrapped in the `ALL` operator. This function is not supported by the SQLite dialect. */
fun <T> allFrom(subQuery: AbstractQuery<*>): Op<T> = AllAnyFromSubQueryOp(false, subQuery)

/** Returns this array of data wrapped in the `ALL` operator. This function is only supported by PostgreSQL and H2 dialects. */
fun <T> allFrom(array: Array<T>): Op<T> = AllAnyFromArrayOp(false, array)

/** Returns this table wrapped in the `ALL` operator. This function is only supported by MySQL, PostgreSQL, and H2 dialects. */
fun <T> allFrom(table: Table): Op<T> = AllAnyFromTableOp(false, table)

// Sequence Manipulation Functions

/** Advances this sequence and returns the new value. */
Expand Down Expand Up @@ -606,7 +623,7 @@ interface ISqlExpressionBuilder {

// Array Comparisons

/** Checks if this expression is equals to any element from [list]. */
/** Checks if this expression is equal to any element from [list]. */
infix fun <T> ExpressionWithColumnType<T>.inList(list: Iterable<T>): InListOrNotInListBaseOp<T> = SingleValueInListOp(this, list, isInList = true)

/**
Expand Down Expand Up @@ -663,6 +680,14 @@ interface ISqlExpressionBuilder {
return SingleValueInListOp(this, list.map { EntityIDFunctionProvider.createEntityID(it, idTable) }, isInList = false)
}

// "IN (TABLE ...)" comparisons

/** Checks if this expression is equal to any element from the column of [table] with only a single column. This function is only supported by MySQL, PostgreSQL, and H2 dialects. */
infix fun <T> ExpressionWithColumnType<T>.inTable(table: Table): InTableOp = InTableOp(this, table, true)

/** Checks if this expression is not equal to any element from the column of [table] with only a single column. This function is only supported by MySQL, PostgreSQL, and H2 dialects. */
infix fun <T> ExpressionWithColumnType<T>.notInTable(table: Table): InTableOp = InTableOp(this, table, false)

// Misc.

/** Returns the specified [value] as a query parameter of type [T]. */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package org.jetbrains.exposed.sql.ops

import org.jetbrains.exposed.sql.AbstractQuery
import org.jetbrains.exposed.sql.Op
import org.jetbrains.exposed.sql.QueryBuilder
import org.jetbrains.exposed.sql.Table
import org.jetbrains.exposed.sql.UntypedAndUnsizedArrayColumnType

abstract class AllAnyFromBaseOp<T, SubSearch>(val isAny: Boolean, val subSearch: SubSearch) : Op<T>() {
override fun toQueryBuilder(queryBuilder: QueryBuilder) = queryBuilder {
+(if (isAny) "ANY" else "ALL")
+" ("
registerSubSearchArgument(subSearch)
+')'
}

abstract fun QueryBuilder.registerSubSearchArgument(subSearch: SubSearch)
}

class AllAnyFromSubQueryOp<T>(isAny: Boolean, subQuery: AbstractQuery<*>) : AllAnyFromBaseOp<T, AbstractQuery<*>>(isAny, subQuery) {
override fun QueryBuilder.registerSubSearchArgument(subSearch: AbstractQuery<*>) {
subSearch.prepareSQL(this)
}
}

/** This function is only supported by PostgreSQL and H2 dialects. */
class AllAnyFromArrayOp<T>(isAny: Boolean, array: Array<T>) : AllAnyFromBaseOp<T, Array<T>>(isAny, array) {
override fun QueryBuilder.registerSubSearchArgument(subSearch: Array<T>) =
registerArgument(UntypedAndUnsizedArrayColumnType, subSearch)
}

/** This function is only supported by PostgreSQL and H2 dialects. */
class AllAnyFromTableOp<T>(isAny: Boolean, table: Table) : AllAnyFromBaseOp<T, Table>(isAny, table) {
override fun QueryBuilder.registerSubSearchArgument(subSearch: Table) {
+"TABLE "
+subSearch.tableName
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.jetbrains.exposed.sql.ops

import org.jetbrains.exposed.sql.ComplexExpression
import org.jetbrains.exposed.sql.Expression
import org.jetbrains.exposed.sql.Op
import org.jetbrains.exposed.sql.QueryBuilder
import org.jetbrains.exposed.sql.Table

/** This function is only supported by PostgreSQL and H2 dialects. */
class InTableOp(
val expr: Expression<*>,
/** the table to check against. */
val table: Table,
/** Returns `true` if the check is inverted, `false` otherwise. */
val isInTable: Boolean = true
) : Op<Boolean>(), ComplexExpression {
override fun toQueryBuilder(queryBuilder: QueryBuilder) = queryBuilder {
+expr
+" "
+if (isInTable) "" else "NOT "
+"IN ("
+"TABLE "
+table.tableName
+')'
}
}
Loading

0 comments on commit 98df06d

Please sign in to comment.