Skip to content

Commit

Permalink
Merge pull request #964 from jverswijver/union_bug
Browse files Browse the repository at this point in the history
Fix bug with unions.
  • Loading branch information
guzman-raphael authored Feb 9, 2022
2 parents 3bdfcf3 + 7f4ea4b commit 8115393
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 6 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Release notes

### 0.13.3 -- TBD
### 0.13.3 -- Feb 9, 2022
* Bugfix - Fix error in listing ancestors, descendants with part tables.
* Bugfix - Fix Python 3.10 compatibility (#983) PR #972
* Bugfix - Allow renaming non-conforming attributes in proj (#982) PR #972
Expand All @@ -16,6 +16,7 @@
* Bugfix - Fix count for left-joined `QueryExpressions` (#951) PR #966
* Bugfix - Fix assertion error when performing a union into a join (#930) PR #967
* Update `~jobs.error_stack` from blob to mediumblob to allow error stacks >64kB in jobs (#984) PR #986
* Bugfix - Fix error when performing a union on multiple tables (#926) PR #964
* Add - Allow optional keyword arguments for `make()` in `populate()` PR #971

### 0.13.2 -- May 7, 2021
Expand Down
12 changes: 8 additions & 4 deletions datajoint/expression.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def from_clause(self):
return clause

def where_clause(self):
return '' if not self.restriction else ' WHERE(%s)' % ')AND('.join(
return '' if not self.restriction else ' WHERE (%s)' % ')AND('.join(
str(s) for s in self.restriction)

def make_sql(self, fields=None):
Expand Down Expand Up @@ -606,6 +606,8 @@ class Union(QueryExpression):
"""
Union is the private DataJoint class that implements the union operator.
"""
__count = count()

@classmethod
def create(cls, arg1, arg2):
if inspect.isclass(arg2) and issubclass(arg2, QueryExpression):
Expand All @@ -632,9 +634,11 @@ def make_sql(self):
if not arg1.heading.secondary_attributes and not arg2.heading.secondary_attributes:
# no secondary attributes: use UNION DISTINCT
fields = arg1.primary_key
return "({sql1}) UNION ({sql2})".format(
sql1=arg1.make_sql(fields),
sql2=arg2.make_sql(fields))
return ("SELECT * FROM (({sql1}) UNION ({sql2})) as `_u{alias}`".format(
sql1=arg1.make_sql() if isinstance(arg1, Union) else arg1.make_sql(fields),
sql2=arg2.make_sql() if isinstance(arg2, Union) else arg2.make_sql(fields),
alias=next(self.__count)
))
# with secondary attributes, use union of left join with antijoin
fields = self.heading.names
sql1 = arg1.join(arg2, left=True).make_sql(fields)
Expand Down
3 changes: 2 additions & 1 deletion docs-parts/intro/Releases_lang1.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
0.13.3 -- TBD
0.13.3 -- Feb 9, 2022
----------------------
* Bugfix - Fix error in listing ancestors, descendants with part tables.
* Bugfix - Fix Python 3.10 compatibility (#983) PR #972
Expand All @@ -15,6 +15,7 @@
* Bugfix - Fix assertion error when performing a union into a join (#930) PR #967
* Bugfix - Fix regression issue with `DISTINCT` clause and `GROUP_BY` (#914) PR #963
* Update `~jobs.error_stack` from blob to mediumblob to allow error stacks >64kB in jobs (#984) PR #986
* Bugfix - Fix error when performing a union on multiple tables (#926) PR #964
* Add - Allow optional keyword arguments for `make()` in `populate()` PR #971

0.13.2 -- May 7, 2021
Expand Down
10 changes: 10 additions & 0 deletions tests/test_relational_operand.py
Original file line number Diff line number Diff line change
Expand Up @@ -516,3 +516,13 @@ def test_joins_with_aggregation():
session_dates = ((SessionDateA * (subj_query & 'date_trained<"2020-12-21"')) &
'session_date<date_trained')
assert len(session_dates) == 1

@staticmethod
def test_union_multiple():
# https://github.com/datajoint/datajoint-python/issues/926
q1 = IJ & dict(j=2)
q2 = (IJ & dict(j=2, i=0)) + (IJ & dict(j=2, i=1)) + (IJ & dict(j=2, i=2))
x = set(zip(*q1.fetch('i', 'j')))
y = set(zip(*q2.fetch('i', 'j')))
assert x == y
assert q1.fetch(as_dict=True) == q2.fetch(as_dict=True)

0 comments on commit 8115393

Please sign in to comment.