Skip to content

Commit ceaef97

Browse files
Fix multiple relationships pointing to the same collection (#88)
* Fix multiple relationships pointing to the same collection * Update test expectation * Oops wrong test * Format * Update expected.json --------- Co-authored-by: Gavin Ray <ray.gavin97@gmail.com>
1 parent 39d04f2 commit ceaef97

3 files changed

Lines changed: 133 additions & 120 deletions

File tree

ndc-connector-snowflake/src/main/kotlin/io/hasura/snowflake/CTEQueryGenerator.kt

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,8 @@ object CTEQueryGenerator : BaseQueryGenerator() {
352352
DSL.name(
353353
createAlias(
354354
relation.target_collection,
355-
isAggOnlyRelationField(field)
355+
isAggOnlyRelationField(field),
356+
alias
356357
),
357358
ROWS_AND_AGGREGATES
358359
)
@@ -429,12 +430,12 @@ object CTEQueryGenerator : BaseQueryGenerator() {
429430
val args = if (baseRel.arguments.isEmpty() && baseRel.column_mapping.isEmpty() && field.arguments.isNotEmpty()) {
430431
field.arguments
431432
} else baseRel.arguments
432-
Pair(field, baseRel.copy(arguments = args))
433+
Triple(alias, field, baseRel.copy(arguments = args))
433434
}
434435

435436
val joinedAliases = mutableSetOf<String>()
436437

437-
relationFields.forEach { (field, relationship) ->
438+
relationFields.forEach { (fieldAlias, field, relationship) ->
438439
val desiredAggOnly = isAggOnlyRelationField(field)
439440

440441
var chosenTriple: Triple<QueryRequest, String?, SelectJoinStep<*>>? = null
@@ -456,7 +457,8 @@ object CTEQueryGenerator : BaseQueryGenerator() {
456457
val (innerRequest, _, innerSelect) = chosenTriple!!
457458
val innerAlias = createAlias(
458459
innerRequest.collection,
459-
isAggregateOnlyRequest(innerRequest)
460+
isAggregateOnlyRequest(innerRequest),
461+
fieldAlias
460462
)
461463

462464
if (!joinedAliases.contains(innerAlias)) {
@@ -537,9 +539,14 @@ object CTEQueryGenerator : BaseQueryGenerator() {
537539
}
538540

539541
/**
540-
* Helper to alias inner SELECTs based on collection and whether they are aggregate-only.
542+
* Helper to alias inner SELECTs based on collection, field alias, and whether they are aggregate-only.
541543
*/
542-
private fun createAlias(collection: String, isAggregateOnly: Boolean): String {
543-
return "$collection${if (isAggregateOnly) "_AGG" else ""}".replace(".", "_")
544+
private fun createAlias(collection: String, isAggregateOnly: Boolean, fieldAlias: String? = null): String {
545+
val baseAlias = if (fieldAlias != null) {
546+
"${fieldAlias}_${collection}"
547+
} else {
548+
collection
549+
}
550+
return "$baseAlias${if (isAggregateOnly) "_AGG" else ""}".replace(".", "_")
544551
}
545552
}

ndc-connector-trino/src/main/kotlin/io/hasura/trino/CTEQueryGenerator.kt

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,8 @@ object CTEQueryGenerator : BaseQueryGenerator() {
198198
DSL.name(
199199
createAlias(
200200
relation.target_collection,
201-
isAggOnlyRelationField(field)
201+
isAggOnlyRelationField(field),
202+
alias
202203
),
203204
ROWS_AND_AGGREGATES
204205
)
@@ -251,22 +252,22 @@ object CTEQueryGenerator : BaseQueryGenerator() {
251252

252253

253254
selects.forEachIndexed() { idx, (request, select) ->
254-
val relationships = getQueryRelationFields(request.query.fields).values.map {
255-
val rel = request.collection_relationships[it.relationship]!!
256-
val args = if (rel.arguments.isEmpty() && rel.column_mapping.isEmpty() && it.arguments.isNotEmpty()) {
257-
it.arguments
255+
val relationships = getQueryRelationFields(request.query.fields).map { (alias, field) ->
256+
val rel = request.collection_relationships[field.relationship]!!
257+
val args = if (rel.arguments.isEmpty() && rel.column_mapping.isEmpty() && field.arguments.isNotEmpty()) {
258+
field.arguments
258259
} else rel.arguments
259-
rel.copy(arguments = args)
260+
Pair(alias, rel.copy(arguments = args))
260261
}
261262

262-
relationships.forEach { relationship ->
263+
relationships.forEach { (fieldAlias, relationship) ->
263264

264265
val innerSelects =
265266
selects.minus(selects[idx]).filter { it.first.collection == relationship.target_collection }
266267

267268
innerSelects.forEach { (innerRequest, innerSelect) ->
268269
val innerAlias = createAlias(
269-
innerRequest.collection, isAggregateOnlyRequest(innerRequest)
270+
innerRequest.collection, isAggregateOnlyRequest(innerRequest), fieldAlias
270271
)
271272

272273
run {
@@ -338,8 +339,13 @@ object CTEQueryGenerator : BaseQueryGenerator() {
338339
)
339340
}
340341

341-
private fun createAlias(collection: String, isAggregateOnly: Boolean): String {
342-
return "$collection${if (isAggregateOnly) "_AGG" else ""}".replace(".", "_")
342+
private fun createAlias(collection: String, isAggregateOnly: Boolean, fieldAlias: String? = null): String {
343+
val baseAlias = if (fieldAlias != null) {
344+
"${fieldAlias}_${collection}"
345+
} else {
346+
collection
347+
}
348+
return "$baseAlias${if (isAggregateOnly) "_AGG" else ""}".replace(".", "_")
343349
}
344350

345351
}

0 commit comments

Comments
 (0)