fix: EXPOSED-1040 Support SELECT without FROM table clause - #2902
fix: EXPOSED-1040 Support SELECT without FROM table clause#2902Leonid Stashevsky (e5l) wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Adds first-class support for “tableless” SELECT statements (i.e., SELECT 1 without an explicit FROM) across Exposed’s JDBC and R2DBC APIs, including convenience terminals for fetching a single projected value and documentation/tests to lock in the behavior.
Changes:
- Introduces top-level tableless
select(...)overloads (JDBC + R2DBC) backed byTable.Dual, plusselectValue(...)terminals. - Adds a generic
literal(value)helper inexposed-corefor wrapping common scalar Kotlin/Java values as SQL literals, plus tests. - Updates user documentation and changelog; refreshes SQL Server docker image tag used in dev/test infra.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| exposed-tests/src/test/kotlin/org/jetbrains/exposed/v1/tests/shared/types/LiteralOpTests.kt | New tests for literal(value) type resolution, decimal precision/scale, and unsupported types. |
| exposed-tests/src/test/kotlin/org/jetbrains/exposed/v1/tests/shared/dml/SelectExpressionTest.kt | New JDBC tests covering tableless selects, selectValue, set ops, derived table usage, and edge cases. |
| exposed-tests/src/test/kotlin/org/jetbrains/exposed/v1/tests/shared/dml/DualTableTest.kt | Removes old Table.Dual-focused test, superseded by tableless select tests. |
| exposed-r2dbc/src/main/kotlin/org/jetbrains/exposed/v1/r2dbc/Queries.kt | Adds tableless select(...) overloads and suspending selectValue(...) terminals for R2DBC. |
| exposed-r2dbc/api/exposed-r2dbc.api | Public API surface update for the new R2DBC query helpers. |
| exposed-r2dbc-tests/src/test/kotlin/org/jetbrains/exposed/v1/r2dbc/sql/tests/shared/dml/SelectExpressionTest.kt | New R2DBC tests validating tableless select and selectValue behavior. |
| exposed-r2dbc-tests/src/test/kotlin/org/jetbrains/exposed/v1/r2dbc/sql/tests/shared/dml/DualTableTest.kt | Removes old R2DBC Table.Dual test, superseded by tableless select tests. |
| exposed-jdbc/src/main/kotlin/org/jetbrains/exposed/v1/jdbc/Queries.kt | Adds tableless select(...) overloads and selectValue(...) terminals for JDBC. |
| exposed-jdbc/api/exposed-jdbc.api | Public API surface update for the new JDBC query helpers. |
| exposed-core/src/main/kotlin/org/jetbrains/exposed/v1/core/LiteralOp.kt | Adds literal(value) auto-resolver for common scalar types (+ UUID support). |
| exposed-core/src/main/kotlin/org/jetbrains/exposed/v1/core/BinaryLiteralColumnType.kt | Internal column type to render ByteArray literals using blob/hex formatting rules. |
| exposed-core/api/exposed-core.api | Public API surface update for the new literal(value) function. |
| documentation-website/Writerside/topics/DSL-Querying-data.topic | Adds a “Tableless SELECT queries” documentation chapter with examples and caveats. |
| CHANGELOG.md | Adds feature entry describing tableless select + selectValue + literal. |
| buildScripts/docker/docker-compose-sqlserver.yml | Updates SQL Server container image tag. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
9828588 to
e1658fc
Compare
Chantal Loncle (bog-walk)
left a comment
There was a problem hiding this comment.
Please also check failing tests on some db?
There was a problem hiding this comment.
It makes sense for a test that relies solely on exposed-core to only have a single (JDBC) test suite.
Please still tag it using something like @Tag(NOT_APPLICABLE_TO_R2DBC) so we know why there is a test number discrepancy between JDBC & R2DBC (and why it doesn't need to be added).
There was a problem hiding this comment.
No issue with this class except I do wonder how differently the output is compared to what we already have. There is a current top-level .asLiteral() that returns a LiteralOp and it also has a special branch for ByteArray + BasicBinaryColumnType --> source code
Would literal(byteArrayOf(0x01, 0x7F)) provide the same result as column.asLiteral(byteArrayOf(0x01, 0x7F))?
I haven't checked, just wondering, but hopefully it does?
There was a problem hiding this comment.
it's interesting that we preferred the string literal, let me explore
There was a problem hiding this comment.
The existing asLiteral works not correct when the non-utf8 bytes are present in the array. Here is the simple test:
@Test
fun testBinaryDefaultPreservesNonUtf8Bytes() {
val expected = byteArrayOf(0x89.toByte(), 0x50, 0x4E, 0x47)
val table = object : Table("binary_default_test") {
val payload = binary("payload").default(expected)
}
withTables(table) {
table.insert {}
val actual = table.selectAll().single()[table.payload]
assertContentEquals(expected, actual)
}
}It follows the path default(bytes) -> asLiteral(bytes) -> dbDefaultToString(...). I will update the asLiteral to also follow hex serialization instead of utf-8
0cb3e97 to
9ad2abd
Compare
Description
Introduce select expression which allows to use select statement without column set.
Type of Change
Please mark the relevant options with an "X":
Updates/remove existing public API methods:
Affected databases:
Checklist
Related Issues
EXPOSED-1040 Support SELECT without FROM table clause