Skip to content

Commit

Permalink
support for full outer join - initial implementation #24
Browse files Browse the repository at this point in the history
  • Loading branch information
isuru89 committed May 31, 2017
1 parent 91dd837 commit c5db939
Show file tree
Hide file tree
Showing 12 changed files with 242 additions and 33 deletions.
3 changes: 2 additions & 1 deletion core/src/main/groovy/com/virtusa/gto/nyql/Join.groovy
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.virtusa.gto.nyql

import com.virtusa.gto.nyql.model.JoinType
import com.virtusa.gto.nyql.utils.QOperator
import groovy.transform.CompileStatic

Expand All @@ -9,7 +10,7 @@ import groovy.transform.CompileStatic
@CompileStatic
class Join extends Table {

String type = 'JOIN'
JoinType type = JoinType.CROSS_JOIN

Table table1
Table table2
Expand Down
17 changes: 11 additions & 6 deletions core/src/main/groovy/com/virtusa/gto/nyql/JoinClosure.groovy
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.virtusa.gto.nyql

import com.virtusa.gto.nyql.exceptions.NySyntaxException
import com.virtusa.gto.nyql.model.JoinType
import com.virtusa.gto.nyql.model.QScript
import com.virtusa.gto.nyql.utils.QUtils
import com.virtusa.gto.nyql.utils.QueryType
Expand All @@ -12,7 +13,7 @@ import groovy.transform.CompileStatic
@CompileStatic
class JoinClosure extends AbstractClause {

private static final String DEF_JOIN = 'INNER_JOIN'
private static final JoinType DEF_JOIN = JoinType.INNER_JOIN

final Table startingTable

Expand Down Expand Up @@ -42,7 +43,7 @@ class JoinClosure extends AbstractClause {
}

Table CROSS_JOIN(Table t) {
activeTable = QUtils.mergeJoinClauses(_ctx, activeTable, t, 'JOIN')
activeTable = QUtils.mergeJoinClauses(_ctx, activeTable, t, JoinType.CROSS_JOIN)
activeTable
}

Expand All @@ -52,23 +53,27 @@ class JoinClosure extends AbstractClause {
}

Table LEFT_OUTER_JOIN(Table t) {
activeTable = QUtils.mergeJoinClauses(_ctx, activeTable, t, 'LEFT_OUTER_JOIN')
activeTable = QUtils.mergeJoinClauses(_ctx, activeTable, t, JoinType.LEFT_JOIN)
activeTable
}

Table RIGHT_OUTER_JOIN(Table t) {
activeTable = QUtils.mergeJoinClauses(_ctx, activeTable, t, 'RIGHT_OUTER_JOIN')
activeTable = QUtils.mergeJoinClauses(_ctx, activeTable, t, JoinType.RIGHT_JOIN)
activeTable
}

Table RIGHT_JOIN(Table t) {
activeTable = QUtils.mergeJoinClauses(_ctx, activeTable, t, 'RIGHT_JOIN')
activeTable = QUtils.mergeJoinClauses(_ctx, activeTable, t, JoinType.RIGHT_JOIN)
activeTable
}

Table LEFT_JOIN(Table t) {
activeTable = QUtils.mergeJoinClauses(_ctx, activeTable, t, 'LEFT_JOIN')
activeTable = QUtils.mergeJoinClauses(_ctx, activeTable, t, JoinType.LEFT_JOIN)
activeTable
}

Table FULL_JOIN(Table t) {
activeTable = QUtils.mergeJoinClauses(_ctx, activeTable, t, JoinType.FULL_JOIN)
activeTable
}
}
19 changes: 0 additions & 19 deletions core/src/main/groovy/com/virtusa/gto/nyql/db/QJoins.groovy

This file was deleted.

13 changes: 12 additions & 1 deletion core/src/main/groovy/com/virtusa/gto/nyql/db/QTranslator.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.virtusa.gto.nyql.db

import com.virtusa.gto.nyql.*
import com.virtusa.gto.nyql.exceptions.NyException
import com.virtusa.gto.nyql.model.JoinType
import com.virtusa.gto.nyql.model.units.*
import com.virtusa.gto.nyql.utils.QOperator
import com.virtusa.gto.nyql.utils.QUtils
Expand All @@ -10,7 +11,7 @@ import groovy.transform.CompileStatic
/**
* @author Isuru Weerarathna
*/
trait QTranslator extends QJoins {
trait QTranslator {

String NULL() { 'NULL' }

Expand Down Expand Up @@ -167,6 +168,16 @@ trait QTranslator extends QJoins {
*/
abstract QResultProxy ___updateQuery(QueryUpdate q)

/**
* Return resolved name for the given join type.
*
* @param joinType join type.
* @return resolved name for join.
*/
String ___resolveJoinType(JoinType joinType) {
return joinType.getJoinName()
}

/**
* Converts a given operator to appropriate db specific string.
*
Expand Down
26 changes: 26 additions & 0 deletions core/src/main/groovy/com/virtusa/gto/nyql/model/JoinType.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.virtusa.gto.nyql.model

import groovy.transform.CompileStatic

/**
* @author iweerarathna
*/
@CompileStatic
enum JoinType {

CROSS_JOIN('CROSS JOIN'),
LEFT_JOIN('LEFT JOIN'),
RIGHT_JOIN('RIGHT JOIN'),
FULL_JOIN('FULL JOIN'),
INNER_JOIN('INNER JOIN')

private final String joinName

JoinType(String joinName) {
this.joinName = joinName
}

String getJoinName() {
return joinName
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.virtusa.gto.nyql.Table
import com.virtusa.gto.nyql.TableProxy
import com.virtusa.gto.nyql.Where
import com.virtusa.gto.nyql.exceptions.NySyntaxException
import com.virtusa.gto.nyql.model.JoinType
import com.virtusa.gto.nyql.model.units.AParam
import com.virtusa.gto.nyql.model.units.NamedParam
import groovy.transform.CompileStatic
Expand Down Expand Up @@ -157,7 +158,7 @@ final class QUtils {
* @param type type of the join if it needed to be merged.
* @return merged table reference.
*/
static Table mergeJoinClauses(QContext ctx, Table tableLeft, Table tableRight, String type) {
static Table mergeJoinClauses(QContext ctx, Table tableLeft, Table tableRight, JoinType type) {
Table table1 = tableLeft
Table table2 = tableRight
Table rmost = findRightMostTable(table1)
Expand Down
30 changes: 28 additions & 2 deletions tests/scripts/joins/simple.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,32 @@
mysql: "SELECT * FROM `Film` f CROSS JOIN `Film_Actor` fa"
],

$DSL.select {
TARGET (Film.alias("f"))
JOIN (TARGET()) {
FULL_JOIN (Film_Actor.alias("fa"))
}
FETCH ()
},
[
mysql: "SELECT * FROM `Film` f LEFT JOIN `Film_Actor` fa UNION ALL " +
"SELECT * FROM `Film` f RIGHT JOIN `Film_Actor` fa"
],

$DSL.select {
TARGET (Film.alias("f"))
JOIN (TARGET()) {
FULL_JOIN (Film_Actor.alias("fa"))
FULL_JOIN (Film_Character.alias("fc"))
}
FETCH ()
},
[
mysql: "SELECT * FROM `Film` f LEFT JOIN `Film_Actor` fa LEFT JOIN `Film_Character` fc UNION ALL " +
"SELECT * FROM `Film` f RIGHT JOIN `Film_Actor` fa LEFT JOIN `Film_Character` fc UNION ALL " +
"SELECT * FROM `Film` f RIGHT JOIN `Film_Actor` fa RIGHT JOIN `Film_Character` fc"
],

$DSL.select {
TARGET (Film.alias("f"))
JOIN {
Expand All @@ -62,7 +88,7 @@
},
[
mysql: "SELECT * FROM `Film` f " +
"LEFT OUTER JOIN `Film_Actor` fa ON f.film_id = fa.film_id " +
"LEFT JOIN `Film_Actor` fa ON f.film_id = fa.film_id " +
"RIGHT JOIN `Actor` a ON fa.actor_id = a.actor_id"
],

Expand All @@ -80,7 +106,7 @@
},
[
mysql: "SELECT * FROM `Film` f " +
"RIGHT OUTER JOIN `Film_Actor` fa ON f.film_id = fa.film_id AND f.film_id = fa.second_film_id " +
"RIGHT JOIN `Film_Actor` fa ON f.film_id = fa.film_id AND f.film_id = fa.second_film_id " +
"CROSS JOIN `Actor` a ON fa.actor_id = a.actor_id"
],

Expand Down
2 changes: 1 addition & 1 deletion tests/src/test/java/nyql/parsing/AbstractTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ private void compare(QResultProxy proxy, final Object queryComp) {
}
System.out.println("Generated Query:");
System.out.println(q1);
Assert.assertEquals(q2, q1);
Assert.assertEquals(q1, q2);

List<AParam> paramList = proxy.getOrderedParameters();
assertLists(paramList, pList);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class MSSql extends MSSqlFunctions implements QTranslator {
@CompileStatic
@Override
String ___tableJoinName(final Join join, final QContextType contextType, List<AParam> paramOrder) {
String jtype = invokeMethod(join.type, null)
String jtype = ___resolveJoinType(join.type)
generateTableJoinName(join, jtype, contextType, paramOrder)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.virtusa.gto.nyql.*
import com.virtusa.gto.nyql.db.QDdl
import com.virtusa.gto.nyql.db.QTranslator
import com.virtusa.gto.nyql.db.TranslatorOptions
import com.virtusa.gto.nyql.exceptions.NyException
import com.virtusa.gto.nyql.model.units.AParam
import com.virtusa.gto.nyql.utils.QUtils
import com.virtusa.gto.nyql.utils.QueryCombineType
Expand Down Expand Up @@ -108,7 +109,7 @@ class MySql extends MySqlFunctions implements QTranslator {
@CompileStatic
@Override
String ___tableJoinName(final Join join, final QContextType contextType, List<AParam> paramOrder) {
String jtype = invokeMethod(join.type, null)
String jtype = ___resolveJoinType(join.type)
generateTableJoinName(join, jtype, contextType, paramOrder)
}

Expand Down Expand Up @@ -154,6 +155,44 @@ class MySql extends MySqlFunctions implements QTranslator {
}
}

@Override
QResultProxy ___selectQuery(QuerySelect q) throws NyException {
int count
if ((count = MySqlUtils.countFullJoin(q._joiningTable)) > 0) {
List<QResultProxy> qParts = new LinkedList<>()
List<String> qs = new LinkedList<>()
QResultProxy resultProxy = new QResultProxy()
resultProxy.orderedParameters = new LinkedList<>()

for (int i = count; i >= 0; i--) {
QuerySelect qt = MySqlUtils.cloneQuery(q)
MySqlUtils.flipNthFullJoin(qt._joiningTable, i, 0)

QResultProxy qr = super.___selectQuery(qt)
qs.add(qr.query)
qParts.add(qr)

if (qr.orderedParameters != null) {
resultProxy.orderedParameters.addAll(qr.orderedParameters)
}
resultProxy.returnType = qr.returnType
resultProxy.qObject = qr.qObject
resultProxy.queryType = qr.queryType
resultProxy.rawObject = qr.rawObject
}

resultProxy.query = String.join(' UNION ALL ', qs)
return resultProxy

} else {
return super.___selectQuery(q)
}
}

private static QResultProxy mergeResults(List<QResultProxy> resultProxies) {

}

@CompileStatic
@Override
QResultProxy ___updateQuery(QueryUpdate q) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.virtusa.gto.nyql.db.mysql

import com.virtusa.gto.nyql.Join
import groovy.transform.CompileStatic
import groovy.transform.PackageScope

/**
* @author iweerarathna
*/
@CompileStatic
@PackageScope
class MySqlFullJoin extends Join {
}
Loading

0 comments on commit c5db939

Please sign in to comment.