Skip to content

Commit 902b24d

Browse files
authored
Merge pull request #37 from hasura/rel-ordering-fix
added joins, selects and order bys for ordering by a related table
2 parents ab66004 + 75cc0ea commit 902b24d

File tree

1 file changed

+33
-14
lines changed

1 file changed

+33
-14
lines changed

ndc-connector-mysql/src/main/kotlin/io/hasura/mysql/JSONGenerator.kt

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,12 @@ package io.hasura.mysql
22

33
import io.hasura.ndc.common.ConnectorConfiguration
44
import io.hasura.ndc.common.NDCScalar
5-
import io.hasura.ndc.common.NativeQueryInfo
6-
import io.hasura.ndc.common.NativeQueryPart
75
import io.hasura.ndc.ir.*
86
import io.hasura.ndc.ir.Field.ColumnField
97
import io.hasura.ndc.ir.Field as IRField
108
import io.hasura.ndc.sqlgen.BaseQueryGenerator
119
import org.jooq.*
1210
import org.jooq.Field
13-
import org.jooq.impl.CustomField
1411
import org.jooq.impl.DSL
1512
import org.jooq.impl.SQLDataType
1613

@@ -21,7 +18,7 @@ object JsonQueryGenerator : BaseQueryGenerator() {
2118
return DSL
2219
.with(buildVarsCTE(request))
2320
.select(
24-
jsonArrayAgg(
21+
DSL.jsonArrayAgg(
2522
buildJSONSelectionForQueryRequest(request)
2623
)
2724
)
@@ -34,12 +31,12 @@ object JsonQueryGenerator : BaseQueryGenerator() {
3431
return queryRequestToSQLInternal(request)
3532
}
3633

37-
fun queryRequestToSQLInternal(
34+
private fun queryRequestToSQLInternal(
3835
request: QueryRequest,
3936
): SelectSelectStep<*> {
4037
// JOOQ is smart enough to not generate CTEs if there are no native queries
4138
return mkNativeQueryCTEs(request).select(
42-
jsonArrayAgg(
39+
DSL.jsonArrayAgg(
4340
buildJSONSelectionForQueryRequest(request)
4441
)
4542
)
@@ -53,7 +50,8 @@ object JsonQueryGenerator : BaseQueryGenerator() {
5350

5451
val baseSelection = DSL.select(
5552
DSL.table(DSL.name(request.collection)).asterisk()
56-
).from(
53+
).select(getSelectOrderFields(request))
54+
.from(
5755
if (request.query.predicate == null) {
5856
DSL.table(DSL.name(request.collection))
5957
} else {
@@ -77,8 +75,12 @@ object JsonQueryGenerator : BaseQueryGenerator() {
7775
)
7876
)
7977
}
78+
8079
}
8180
).apply {
81+
addJoinsRequiredForOrderByFields(this, request)
82+
}
83+
.apply {
8284
if (request.query.predicate != null) {
8385
where(getWhereConditions(request))
8486
}
@@ -116,7 +118,7 @@ object JsonQueryGenerator : BaseQueryGenerator() {
116118
DSL.jsonEntry(
117119
"rows",
118120
DSL.select(
119-
jsonArrayAgg(
121+
DSL.jsonArrayAgg(
120122
DSL.jsonObject(
121123
(request.query.fields ?: emptyMap()).map { (alias, field) ->
122124
when (field) {
@@ -163,6 +165,8 @@ object JsonQueryGenerator : BaseQueryGenerator() {
163165
}
164166
}
165167
)
168+
).orderBy(
169+
getConcatOrderFields(request)
166170
)
167171
).from(
168172
baseSelection
@@ -193,11 +197,7 @@ object JsonQueryGenerator : BaseQueryGenerator() {
193197
)
194198
}
195199

196-
fun jsonArrayAgg(field: JSONObjectNullStep<*>) = CustomField.of("mysql_json_arrayagg", SQLDataType.JSON) {
197-
it.visit(DSL.field("json_arrayagg({0})", field))
198-
}
199-
200-
fun collectRequiredJoinTablesForWhereClause(
200+
private fun collectRequiredJoinTablesForWhereClause(
201201
where: Expression,
202202
collectionRelationships: Map<String, Relationship>,
203203
previousTableName: String? = null
@@ -230,7 +230,7 @@ object JsonQueryGenerator : BaseQueryGenerator() {
230230
}
231231
}
232232

233-
fun ndcScalarTypeToSQLDataType(scalarType: NDCScalar): DataType<out Any> = when (scalarType) {
233+
private fun ndcScalarTypeToSQLDataType(scalarType: NDCScalar): DataType<out Any> = when (scalarType) {
234234
NDCScalar.BOOLEAN -> SQLDataType.BOOLEAN
235235
NDCScalar.INT -> SQLDataType.INTEGER
236236
NDCScalar.FLOAT -> SQLDataType.FLOAT
@@ -292,4 +292,23 @@ object JsonQueryGenerator : BaseQueryGenerator() {
292292
return collection.split('.').last()
293293
}
294294

295+
private const val ORDER_FIELD_SUFFIX = "_order_field"
296+
297+
private fun getSelectOrderFields(request: QueryRequest) : List<Field<*>>{
298+
val sortFields = translateIROrderByField(request, request.collection)
299+
return sortFields.map { it.`$field`().`as`(it.name + ORDER_FIELD_SUFFIX) }
300+
}
301+
302+
private fun getConcatOrderFields(request: QueryRequest) : List<SortField<*>>{
303+
val sortFields = translateIROrderByField(request, request.collection)
304+
return sortFields.map {
305+
val field = DSL.field(DSL.name(it.name + ORDER_FIELD_SUFFIX))
306+
when(it.order) {
307+
SortOrder.ASC -> field.asc().nullsLast()
308+
SortOrder.DESC -> field.desc().nullsFirst()
309+
else -> field.asc().nullsLast()
310+
}
311+
}
312+
}
313+
295314
}

0 commit comments

Comments
 (0)