diff --git a/angel_orm/CHANGELOG.md b/angel_orm/CHANGELOG.md index cc359b6c..d92ba10f 100644 --- a/angel_orm/CHANGELOG.md +++ b/angel_orm/CHANGELOG.md @@ -1,3 +1,7 @@ +# 2.1.0-beta.1 +* Calls to `leftJoin`, etc. alias all fields in a child query, to prevent +`ambiguous column a0.id` errors. + # 2.1.0-beta * Split the formerly 600+ line `src/query.dart` up into separate files. diff --git a/angel_orm/lib/src/join_builder.dart b/angel_orm/lib/src/join_builder.dart index bf5836dd..8a6a3ef0 100644 --- a/angel_orm/lib/src/join_builder.dart +++ b/angel_orm/lib/src/join_builder.dart @@ -6,6 +6,7 @@ class JoinBuilder { final JoinType type; final Query from; final String key, value, op, alias; + final bool aliasAllFields; /// A callback to produces the expression to join against, i.e. /// a table name, or the result of compiling a query. @@ -13,34 +14,37 @@ class JoinBuilder { final List additionalFields; JoinBuilder(this.type, this.from, this.to, this.key, this.value, - {this.op = '=', this.alias, this.additionalFields = const []}) { + {this.op = '=', + this.alias, + this.additionalFields = const [], + this.aliasAllFields = false}) { assert(to != null, 'computation of this join threw an error, and returned null.'); } String get fieldName { - var right = '$to.$value'; - if (alias != null) right = '$alias.$value'; + var v = value; + if (aliasAllFields) { + v = '${alias}_$v'; + } + var right = '${from.tableName}.$v'; + if (alias != null) right = '$alias.$v'; return right; } String nameFor(String name) { - var right = '$to.$name'; + if (aliasAllFields) name = '${alias}_$name'; + var right = '${from.tableName}.$name'; if (alias != null) right = '$alias.$name'; return right; } String compile(Set trampoline) { var compiledTo = to(); - if (compiledTo == null) { - print( - 'NULLLLL $to; from $from; key: $key, value: $value, addl: $additionalFields'); - } if (compiledTo == null) return null; var b = StringBuffer(); var left = '${from.tableName}.$key'; var right = fieldName; - switch (type) { case JoinType.inner: b.write(' INNER JOIN'); diff --git a/angel_orm/lib/src/query.dart b/angel_orm/lib/src/query.dart index ce066897..d38ea343 100644 --- a/angel_orm/lib/src/query.dart +++ b/angel_orm/lib/src/query.dart @@ -151,10 +151,17 @@ abstract class Query extends QueryBase { var to = _compileJoin(tableName, trampoline); if (to != null) { + var alias = _joinAlias(trampoline); + if (tableName is Query) { + for (var field in tableName.fields) { + tableName.aliases[field] = '${alias}_$field'; + } + } _joins.add(JoinBuilder(type, this, to, localKey, foreignKey, op: op, - alias: _joinAlias(trampoline), - additionalFields: additionalFields)); + alias: alias, + additionalFields: additionalFields, + aliasAllFields: tableName is Query)); } } @@ -228,6 +235,13 @@ abstract class Query extends QueryBase { var ss = includeTableName ? '$tableName.$s' : s; var cast = casts[s]; if (cast != null) ss = 'CAST ($ss AS $cast)'; + if (aliases.containsKey(s)) { + if (cast != null) { + ss = '($ss) AS ${aliases[s]}'; + } else { + ss = '$ss AS ${aliases[s]}'; + } + } return ss; })); _joins.forEach((j) { diff --git a/angel_orm/lib/src/query_base.dart b/angel_orm/lib/src/query_base.dart index 8e378636..23ae1720 100644 --- a/angel_orm/lib/src/query_base.dart +++ b/angel_orm/lib/src/query_base.dart @@ -7,6 +7,9 @@ abstract class QueryBase { /// Casts to perform when querying the database. Map get casts => {}; + /// `AS` aliases to inject into the query, if any. + Map aliases = {}; + /// Values to insert into a prepared statement. final Map substitutionValues = {}; @@ -21,7 +24,12 @@ abstract class QueryBase { /// A String of all [fields], joined by a comma (`,`). String get fieldSet => fields.map((k) { var cast = casts[k]; - return cast == null ? k : 'CAST ($k AS $cast)'; + if (!aliases.containsKey(k)) { + return cast == null ? k : 'CAST ($k AS $cast)'; + } else { + var inner = cast == null ? k : '(CAST ($k AS $cast))'; + return '$inner AS ${aliases[k]}'; + } }).join(', '); String compile(Set trampoline, diff --git a/angel_orm/pubspec.yaml b/angel_orm/pubspec.yaml index dcd2ba3e..409ebfb1 100644 --- a/angel_orm/pubspec.yaml +++ b/angel_orm/pubspec.yaml @@ -1,5 +1,5 @@ name: angel_orm -version: 2.1.0-beta +version: 2.1.0-beta.1 description: Runtime support for Angel's ORM. Includes base classes for queries. author: Tobe O homepage: https://github.com/angel-dart/orm