Skip to content

Commit

Permalink
Add aliases to nested subselects
Browse files Browse the repository at this point in the history
  • Loading branch information
deusaquilus committed Dec 6, 2021
1 parent 87665a2 commit 287ba2b
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,13 @@ trait SqlIdiom extends Idiom {

def astTokenizer(implicit astTokenizer: Tokenizer[Ast], strategy: NamingStrategy): Tokenizer[Ast] =
Tokenizer[Ast] {
case a: Query => SqlQuery(a).token
case a: Query =>
// This case almost exclusively happens when you have a select inside of an insert.
// have a look at the SqlDslSpec `forUpdate` and `insert with subselects` tests
// for more details.
// Right now we are not removing extra select clauses here (via RemoveUnusedSelects) since I am not sure what
// kind of impact that could have on selects. Can try to do that in the future.
RemoveExtraAlias(strategy)(ExpandNestedQueries(SqlQuery(a))).token
case a: Operation => a.token
case a: Infix => a.token
case a: Action => a.token
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package io.getquill.context.sql

import io.getquill.{ Insert, Spec }
import io.getquill.context.sql.testContext._

class InsertSubquerySpec extends Spec {

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.getquill.context.sql.dsl

import io.getquill.Spec
import io.getquill.{ Insert, Query, Quoted, Spec }
import io.getquill.context.sql.testContext
import io.getquill.context.sql.testContext._

Expand All @@ -22,9 +22,29 @@ class SqlDslSpec extends Spec {
}

"forUpdate" in {
val q = quote {
val q: Quoted[Query[TestEntity]] = quote {
query[TestEntity].filter(t => t.s == "a").forUpdate
}
testContext.run(q).string mustEqual "SELECT t.s, t.i, t.l, t.o, t.b FROM TestEntity t WHERE t.s = 'a' FOR UPDATE"
}

case class Person(name: String, age: Int)

"insert with subselects" - {
// In this case we are not renaming the ages into the table, just the names so technically
// we can exclude the age columns. I am not sure if that has some other potential issues
// for inserts so for now I am just doing ExpandNestedSelects and RemoveUnusedAliases.
// have a look at `astTokenizer` in `SqlIdiom` for details.
val q1 = quote {
(query[Person].map(p => Person("x", p.age)) union query[Person]).map(_.name)
}

val q2 = quote {
infix"INSERT into names $q1".as[Insert[Person]]
}

"should show all field aliases" in {
testContext.run(q2).string mustEqual "INSERT into names SELECT x1.name FROM ((SELECT 'x' AS name, p.age FROM Person p) UNION (SELECT x.name, x.age FROM Person x)) AS x1"
}
}
}

0 comments on commit 287ba2b

Please sign in to comment.