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

Window functions in Exposed DSL #623

Closed
dsdolzhenko opened this issue Aug 14, 2019 · 6 comments · Fixed by #1651
Closed

Window functions in Exposed DSL #623

dsdolzhenko opened this issue Aug 14, 2019 · 6 comments · Fixed by #1651

Comments

@dsdolzhenko
Copy link
Contributor

I couldn't find a way to express a query containing a window function via Exposed DSL. Are there any plans to support window functions in Exposed DSL?

I could try to implement it if there are no objections.

@dsdolzhenko dsdolzhenko changed the title Window functions support in Exposed DSL Window functions in Exposed DSL Aug 14, 2019
@Tapac
Copy link
Contributor

Tapac commented Aug 14, 2019

Hi @dsdolzhenko, there are no plans right now to implement window functions, so it would be great if you could provide a PR.

@dsdolzhenko
Copy link
Contributor Author

Ok. I'll try to keep you posted.

@abishai
Copy link

abishai commented Nov 27, 2019

I'm interested in window functions too and they are part of SQL2003 standard. Anybody tried to use them in Exposed, maybe with some custom extension?

@ghost
Copy link

ghost commented Mar 9, 2021

I dont know if anyone can find this useful, but this is how I was able to reproduce a window function:

Original query:

SELECT  height,
extract(epoch from LAG(block_timestamp) OVER (order by height desc) ) - extract(epoch from block_timestamp) as block_creation_time
FROM block_cache
order by height desc
limit 10;

basic LAG function (can be customized to whatever types you need):

class Lag(val lag: Expression<DateTime>, val orderBy: Expression<Int>): Function<DateTime>(DateColumnType(true)) {
    override fun toQueryBuilder(queryBuilder: QueryBuilder) =
        queryBuilder { append("LAG(", lag,") OVER (order by ", orderBy, " desc)") }
}

I also created an extract(epoch...) function for my use:

class ExtractEpoch(val expr: Expression<DateTime>): Function<BigDecimal>(DecimalColumnType(10, 10)) {
    override fun toQueryBuilder(queryBuilder: QueryBuilder) =
        queryBuilder { append("extract(epoch from ", expr," )") }
}

In action:

fun getBlockCreationInterval(limit: Int) = transaction {
            val lag = Lag(BlockCacheTable.blockTimestamp, BlockCacheTable.height)
            val lagExtract = ExtractEpoch(lag)
            val baseExtract = ExtractEpoch(BlockCacheTable.blockTimestamp)
            val creationTime = lagExtract.minus(baseExtract)

            BlockCacheTable.slice(BlockCacheTable.height, creationTime)
                .selectAll()
                .orderBy(BlockCacheTable.height, SortOrder.DESC)
                .limit(limit)
                .map { Pair(it[BlockCacheTable.height], it[creationTime]) }
        }

@H4kt
Copy link

H4kt commented Oct 4, 2022

Any updates on this?
I would really like to see something like extract(epoch from ...) being as simple as other operations in exposed

@minxylynx
Copy link

minxylynx commented Nov 5, 2022

@H4kt This is what Ive used

Edit: The comment above yours is mine as well, from a different account.

custom function:

class ExtractHour(val expr: Expression<DateTime>) : Function<Int>(IntegerColumnType()) {
    override fun toQueryBuilder(queryBuilder: QueryBuilder) =
        queryBuilder { append("extract(hour from ", expr, " )") }
}

class ExtractDay(val expr: Expression<DateTime>) : Function<String>(VarCharColumnType(9)) {
    override fun toQueryBuilder(queryBuilder: QueryBuilder) =
        queryBuilder { append("to_char(", expr, ", 'DAY')") }
}

class ExtractDOW(val expr: Expression<DateTime>) : Function<Int>(IntegerColumnType()) {
    override fun toQueryBuilder(queryBuilder: QueryBuilder) =
        queryBuilder { append("extract(dow from ", expr, " )") }
}

usage:

            val blockTimestamp = BlockCacheHourlyTxCountsTable.blockTimestamp
            val dow = ExtractDOW(blockTimestamp)
            val day = ExtractDay(blockTimestamp)
            val hour = ExtractHour(blockTimestamp)
            val txSum = BlockCacheHourlyTxCountsTable.txCount.sum()
            val result = BlockCacheHourlyTxCountsTable
                .slice(dow, day, hour, txSum)
                .selectAll()
                .groupBy(dow)
                .groupBy(day)
                .groupBy(hour)
                .orderBy(dow, SortOrder.ASC)
                .orderBy(hour, SortOrder.ASC)
                .map {
                    TxHeatmapRaw(
                        it[dow],
                        it[day].trim(),
                        it[hour],
                        it[txSum]!!
                    )
                }

Epoch would look like

class ExtractEpoch(val expr: Expression<DateTime>) : Function<BigDecimal>(DecimalColumnType(10, 10)) {
    override fun toQueryBuilder(queryBuilder: QueryBuilder) =
        queryBuilder { append("extract(epoch from ", expr, " )") }
}

Legohuman pushed a commit to Legohuman/Exposed that referenced this issue Dec 18, 2022
-Support of partition by and order by clauses
-Support of window frame clause (without EXCLUDE)
-Factories for common window functions
-Support for using aggregate functions as window functions
Legohuman pushed a commit to Legohuman/Exposed that referenced this issue Dec 30, 2022
Legohuman pushed a commit to Legohuman/Exposed that referenced this issue Jun 28, 2023
-Support of partition by and order by clauses
-Support of window frame clause (without EXCLUDE)
-Factories for common window functions
-Support for using aggregate functions as window functions
Legohuman pushed a commit to Legohuman/Exposed that referenced this issue Jun 28, 2023
Legohuman pushed a commit to Legohuman/Exposed that referenced this issue Jun 28, 2023
Window function definitions moved from top-level to ISqlExpressionBuilder
to eliminate their irrelevant appearance in code completion.
Legohuman pushed a commit to Legohuman/Exposed that referenced this issue Jun 28, 2023
@bog-walk bog-walk linked a pull request Jul 7, 2023 that will close this issue
Legohuman pushed a commit to Legohuman/Exposed that referenced this issue Jul 7, 2023
-Support of partition by and order by clauses
-Support of window frame clause (without EXCLUDE)
-Factories for common window functions
-Support for using aggregate functions as window functions
Legohuman pushed a commit to Legohuman/Exposed that referenced this issue Jul 7, 2023
Legohuman pushed a commit to Legohuman/Exposed that referenced this issue Jul 7, 2023
Window function definitions moved from top-level to ISqlExpressionBuilder
to eliminate their irrelevant appearance in code completion.
Legohuman pushed a commit to Legohuman/Exposed that referenced this issue Jul 7, 2023
Legohuman pushed a commit to Legohuman/Exposed that referenced this issue Jul 7, 2023
Legohuman pushed a commit to Legohuman/Exposed that referenced this issue Jul 7, 2023
This flag was used only in tests. Its value was false only for MySql < 8
which is covered by DatabaseTestsBase.kt Transaction.isOldMySql
Legohuman pushed a commit to Legohuman/Exposed that referenced this issue Jul 7, 2023
This flag was used only in tests. Its value was false only for MySql < 8
which is covered by DatabaseTestsBase.kt Transaction.isOldMySql
@e5l e5l closed this as completed in #1651 Jul 7, 2023
e5l pushed a commit that referenced this issue Jul 7, 2023
* #623 Add support of window functions in Exposed DSL

-Support of partition by and order by clauses
-Support of window frame clause (without EXCLUDE)
-Factories for common window functions
-Support for using aggregate functions as window functions

* #623 Fix linter warnings

* Better name for NthValue class 'index' argument

Change argument to 'n' to conform with the most DB docs

Co-authored-by: Jocelyne <38375996+joc-a@users.noreply.github.com>

* Better name for nthValue function 'index' argument

Change argument to 'n' to conform with the most DB docs

Co-authored-by: Jocelyne <38375996+joc-a@users.noreply.github.com>

* #623 Refactor window function definition

Window function definitions moved from top-level to ISqlExpressionBuilder
to eliminate their irrelevant appearance in code completion.

* #623 Dump window functions related API changes

* #623 Fix smart cast warning by replacing not-null assertion with null-safe call

* #623 remove redundant DatabaseDialect.supportsWindowFunctions

This flag was used only in tests. Its value was false only for MySql < 8
which is covered by DatabaseTestsBase.kt Transaction.isOldMySql

---------

Co-authored-by: Dmitry Levin <dlevin@anylogic.com>
Co-authored-by: Jocelyne <38375996+joc-a@users.noreply.github.com>
saral pushed a commit to saral/Exposed that referenced this issue Oct 3, 2023
…ns#1651)

* JetBrains#623 Add support of window functions in Exposed DSL

-Support of partition by and order by clauses
-Support of window frame clause (without EXCLUDE)
-Factories for common window functions
-Support for using aggregate functions as window functions

* JetBrains#623 Fix linter warnings

* Better name for NthValue class 'index' argument

Change argument to 'n' to conform with the most DB docs

Co-authored-by: Jocelyne <38375996+joc-a@users.noreply.github.com>

* Better name for nthValue function 'index' argument

Change argument to 'n' to conform with the most DB docs

Co-authored-by: Jocelyne <38375996+joc-a@users.noreply.github.com>

* JetBrains#623 Refactor window function definition

Window function definitions moved from top-level to ISqlExpressionBuilder
to eliminate their irrelevant appearance in code completion.

* JetBrains#623 Dump window functions related API changes

* JetBrains#623 Fix smart cast warning by replacing not-null assertion with null-safe call

* JetBrains#623 remove redundant DatabaseDialect.supportsWindowFunctions

This flag was used only in tests. Its value was false only for MySql < 8
which is covered by DatabaseTestsBase.kt Transaction.isOldMySql

---------

Co-authored-by: Dmitry Levin <dlevin@anylogic.com>
Co-authored-by: Jocelyne <38375996+joc-a@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants