Skip to content

Commit 86c623b

Browse files
authored
Escape table in returning clause (#80)
Similar issue to one i recently bumped into with update I hope it's the last one, if I bump into one more - I either give up or rewrite general logic of computing table aliases
1 parent a617cc5 commit 86c623b

File tree

4 files changed

+99
-2
lines changed

4 files changed

+99
-2
lines changed

docs/reference.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7061,6 +7061,41 @@ Select.insert.values(
70617061
70627062
70637063
7064+
## EscapedTableNameWithReturning
7065+
7066+
If your table name is a reserved sql world, e.g. `order`, you can specify this in your table definition with
7067+
`override def escape = true`
7068+
7069+
### EscapedTableNameWithReturning.insert with returning
7070+
7071+
7072+
7073+
```scala
7074+
Select.insert
7075+
.values(
7076+
Select[Sc](
7077+
id = 0,
7078+
name = "hello"
7079+
)
7080+
)
7081+
.returning(_.id)
7082+
```
7083+
7084+
7085+
*
7086+
```sql
7087+
INSERT INTO "select" (id, name) VALUES (?, ?) RETURNING "select".id AS res
7088+
```
7089+
7090+
7091+
7092+
*
7093+
```scala
7094+
Seq(0)
7095+
```
7096+
7097+
7098+
70647099
## SubQuery
70657100
Queries that explicitly use subqueries (e.g. for `JOIN`s) or require subqueries to preserve the Scala semantics of the various operators
70667101
### SubQuery.sortTakeJoin

scalasql/query/src/Returning.scala

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,16 @@ object Returning {
5454
override def queryIsSingleRow = false
5555

5656
private[scalasql] override def renderSql(ctx0: Context) = {
57-
implicit val implicitCtx = Context.compute(ctx0, Nil, Some(returnable.table))
57+
val contextStage1: Context = Context.compute(ctx0, Nil, Some(returnable.table))
58+
59+
implicit val implicitCtx: Context = if (returnable.table.value.escape) {
60+
contextStage1.withFromNaming(
61+
contextStage1.fromNaming
62+
.updated(returnable.table, Table.fullIdentifier(returnable.table.value)(contextStage1))
63+
)
64+
} else {
65+
contextStage1
66+
}
5867

5968
val prefix = Renderable.renderSql(returnable)
6069
val walked = qr.walkLabelsAndExprs(expr)

scalasql/test/src/ConcreteTestSuites.scala

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ import query.{
3030
GetGeneratedKeysTests,
3131
WithCteTests,
3232
SchemaTests,
33-
EscapedTableNameTests
33+
EscapedTableNameTests,
34+
EscapedTableNameWithReturningTests
3435
}
3536
import scalasql.dialects.{
3637
MySqlDialectTests,
@@ -63,6 +64,9 @@ package postgres {
6364
object GetGeneratedKeysTests extends GetGeneratedKeysTests with PostgresSuite
6465
object SchemaTests extends SchemaTests with PostgresSuite
6566
object EscapedTableNameTests extends EscapedTableNameTests with PostgresSuite
67+
object EscapedTableNameWithReturningTests
68+
extends EscapedTableNameWithReturningTests
69+
with PostgresSuite
6670

6771
object SubQueryTests extends SubQueryTests with PostgresSuite
6872
object WithCteTests extends WithCteTests with PostgresSuite
@@ -109,6 +113,9 @@ package hikari {
109113
object GetGeneratedKeysTests extends GetGeneratedKeysTests with HikariSuite
110114
object SchemaTests extends SchemaTests with HikariSuite
111115
object EscapedTableNameTests extends EscapedTableNameTests with HikariSuite
116+
object EscapedTableNameWithReturningTests
117+
extends EscapedTableNameWithReturningTests
118+
with HikariSuite
112119

113120
object SubQueryTests extends SubQueryTests with HikariSuite
114121
object WithCteTests extends WithCteTests with HikariSuite
@@ -220,6 +227,9 @@ package sqlite {
220227
// Sqlite doesn't support schemas
221228
// object SchemaTests extends SchemaTests with SqliteSuite
222229
object EscapedTableNameTests extends EscapedTableNameTests with SqliteSuite
230+
object EscapedTableNameWithReturningTests
231+
extends EscapedTableNameWithReturningTests
232+
with SqliteSuite
223233

224234
object DataTypesTests extends datatypes.DataTypesTests with SqliteSuite
225235
object OptionalTests extends datatypes.OptionalTests with SqliteSuite
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package scalasql.query
2+
3+
import scalasql._
4+
import scalasql.core.JoinNullable
5+
import sourcecode.Text
6+
import utest._
7+
import utils.ScalaSqlSuite
8+
9+
import java.time.LocalDate
10+
import scalasql.core.Config
11+
import scalasql.dialects.ReturningDialect
12+
13+
trait EscapedTableNameWithReturningTests extends ScalaSqlSuite {
14+
this: ReturningDialect =>
15+
16+
def description = """
17+
If your table name is a reserved sql world, e.g. `order`, you can specify this in your table definition with
18+
`override def escape = true`
19+
"""
20+
21+
def tests = Tests {
22+
val tableNameEscaped = dialectSelf.escape(Config.camelToSnake(Table.name(Select)))
23+
24+
test("insert with returning") {
25+
checker(
26+
query = Text {
27+
Select.insert
28+
.values(
29+
Select[Sc](
30+
id = 0,
31+
name = "hello"
32+
)
33+
)
34+
.returning(_.id)
35+
},
36+
sql =
37+
s"INSERT INTO $tableNameEscaped (id, name) VALUES (?, ?) RETURNING $tableNameEscaped.id AS res",
38+
value = Seq(0),
39+
docs = ""
40+
)
41+
}
42+
}
43+
}

0 commit comments

Comments
 (0)