Skip to content

Commit

Permalink
fix: EXPOSED-302 Count with alias fails if table name includes schema
Browse files Browse the repository at this point in the history
Attempting to use count() in a query that requires an alias (for example, with
DISTINCT, GROUP BY, or LIMIT clauses) throws a syntax exception if the table name
includes the schema name.

This occurs because the alias name created in count() concatenates the full table
name with a dot character. The alias now uses the table name without a schema prefix
and sanitized of quotations if present.
  • Loading branch information
bog-walk committed Feb 23, 2024
1 parent f8ca8ef commit f332b50
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ open class Query(override var set: FieldSet, where: Op<Boolean>?) : AbstractQuer
override fun count(): Long {
return if (distinct || groupedByColumns.isNotEmpty() || limit != null) {
fun Column<*>.makeAlias() =
alias(transaction.db.identifierManager.quoteIfNecessary("${table.tableName}_$name"))
alias(transaction.db.identifierManager.quoteIfNecessary("${table.tableNameWithoutSchemeSanitized}_$name"))

val originalSet = set
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package org.jetbrains.exposed.sql.tests.shared.dml

import org.jetbrains.exposed.sql.alias
import org.jetbrains.exposed.sql.max
import org.jetbrains.exposed.sql.selectAll
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.tests.DatabaseTestsBase
import org.jetbrains.exposed.sql.tests.currentDialectTest
import org.jetbrains.exposed.sql.tests.shared.*
import org.jetbrains.exposed.sql.vendors.SQLServerDialect
import org.junit.Test

class CountTests : DatabaseTestsBase() {
Expand All @@ -24,7 +24,7 @@ class CountTests : DatabaseTestsBase() {

@Test
fun `test that count() returns right value for Query with group by`() {
withCitiesAndUsers { _, user, userData ->
withCitiesAndUsers { _, _, userData ->
val uniqueUsersInData = userData.select(userData.user_id).withDistinct().count()
val sameQueryWithGrouping = userData.select(userData.value.max()).groupBy(userData.user_id).count()
assertEquals(uniqueUsersInData, sameQueryWithGrouping)
Expand All @@ -41,4 +41,29 @@ class CountTests : DatabaseTestsBase() {
assertEquals(1L, OrgMemberships.selectAll().count())
}
}

@Test
fun testCountAliasWithTableSchema() {
val custom = prepareSchemaForTest("custom")
val tester = object : Table("custom.tester") {
val amount = integer("amount")
}

withSchemas(custom) {
SchemaUtils.create(tester)

repeat(3) {
tester.insert {
it[amount] = 99
}
}

// count alias is generated for any query with distinct/groupBy/limit & throws if schema name included
assertEquals(1, tester.select(tester.amount).withDistinct().count())

if (currentDialectTest is SQLServerDialect) {
SchemaUtils.drop(tester)
}
}
}
}

0 comments on commit f332b50

Please sign in to comment.