Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add set operations #402

Closed
acrane13 opened this issue Oct 9, 2018 · 6 comments
Closed

Add set operations #402

acrane13 opened this issue Oct 9, 2018 · 6 comments
Assignees

Comments

@acrane13
Copy link

acrane13 commented Oct 9, 2018

It would be useful to have the set operations added:

union, union all, minus, intersect

I realize this can be handled with multiple select statements and then process the resulting lists, but they are more efficient in the database

@xJoeWoo
Copy link
Contributor

xJoeWoo commented Oct 16, 2018

Agree, I surprisingly found there's no union operation in Exposed.

@Tapac Tapac self-assigned this Dec 27, 2018
@gronnbeck
Copy link

Is this being worked on? No movement on this issue for a long time. At the moment I drop into SQL to write UNION queries.

@NikolayMetchev
Copy link

NikolayMetchev commented Apr 30, 2020

Here is my attempt at UnionAll. turned out to be quite hairy. It can be improved slightly if Query.arguments() specifies it return type explicitly and matches the interface signature:

class UnionAll(vararg val queries: Query) : Query(queries[0].set, null) {
    override fun arguments(): List<ArrayList<Pair<IColumnType, Any?>>> {
        val allArgs = queries.map { it.arguments() }
        var answer: List<ArrayList<Pair<IColumnType, Any?>>> = listOf()
        allArgs.forEach {
            answer = answer.zipLongest(it) { a, b ->
                a + b
            }
        }
        return answer
    }

    override fun prepareSQL(transaction: Transaction): String =
        queries.joinToString( " UNION ALL ") { it.prepareSQL(transaction) }
}

private operator fun <T> Collection<T>?.plus(other: Collection<T>?) : ArrayList<T> {
    val result = ArrayList<T>(this?.size + other?.size)
    if (this != null) {
        result.addAll(this)
    }
    if (other != null) {
        result.addAll(other)
    }
    return result
}

private operator fun Int?.plus(other: Int?) = when {
    this == null && other == null -> 10
    this == null -> other!!
    other == null -> this
    else -> this + other
}

private inline fun <T, R, V> Iterable<T>.zipLongest(other: Iterable<R>, transform: (a: T?, b: R?) -> V): List<V> {
    val first = iterator()
    val second = other.iterator()
    val list = ArrayList<V>(minOf(collectionSizeOrDefault(10), other.collectionSizeOrDefault(10)))
    while (first.hasNext() || second.hasNext()) {
        if (first.hasNext() && second.hasNext()) {
            list.add(transform(first.next(), second.next()))
        } else if (first.hasNext()) {
            list.add(transform(first.next(), null))
        } else {
            list.add(transform(null, second.next()))
        }
    }
    return list
}

private fun <T> Iterable<T>.collectionSizeOrDefault(default: Int): Int = if (this is Collection<*>) this.size else default

@rogue-one
Copy link

any update on this?.. mysql doesn't support full outer join and I will have to rely on union operation to implement the full outer join.. lack of this operation basically means no full outer join in mysql as well ..

@edeak
Copy link

edeak commented Jan 15, 2021

@Tapac Do you guys have any updates on this?

@Tapac
Copy link
Contributor

Tapac commented Apr 19, 2021

UNION and UNION ALL supported

Tapac added a commit that referenced this issue Sep 19, 2021
…` from testing against PSQL as it returns "unexpected" result
@Tapac Tapac closed this as completed Sep 21, 2021
SchweinchenFuntik pushed a commit to SchweinchenFuntik/Exposed that referenced this issue Oct 23, 2021
SchweinchenFuntik pushed a commit to SchweinchenFuntik/Exposed that referenced this issue Oct 23, 2021
SchweinchenFuntik pushed a commit to SchweinchenFuntik/Exposed that referenced this issue Oct 23, 2021
SchweinchenFuntik pushed a commit to SchweinchenFuntik/Exposed that referenced this issue Oct 23, 2021
SchweinchenFuntik pushed a commit to SchweinchenFuntik/Exposed that referenced this issue Oct 23, 2021
…e queries` from testing against PSQL as it returns "unexpected" result
SchweinchenFuntik pushed a commit to SchweinchenFuntik/Exposed that referenced this issue Oct 23, 2021
SchweinchenFuntik pushed a commit to SchweinchenFuntik/Exposed that referenced this issue Oct 23, 2021
SchweinchenFuntik pushed a commit to SchweinchenFuntik/Exposed that referenced this issue Oct 23, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants