Skip to content

Commit 96f0bbe

Browse files
author
Nam Nd
committed
update feature having clause, support full cut type
1 parent b5e984c commit 96f0bbe

File tree

3 files changed

+40
-60
lines changed

3 files changed

+40
-60
lines changed

cubes/cells.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@
3636

3737
class Cell(object):
3838
"""Part of a cube determined by slicing dimensions. Immutable object."""
39-
def __init__(self, cube=None, cuts=None, having_clauses=None):
39+
def __init__(self, cube=None, cuts=None, having_cuts=None):
4040
if not isinstance(cube, Cube):
4141
raise ArgumentError("Cell cube should be sublcass of Cube, "
4242
"provided: %s" % type(cube).__name__)
4343
self.cube = cube
4444
self.cuts = cuts if cuts is not None else []
45-
self.having_clauses = having_clauses if having_clauses is not None else []
45+
self.having_cuts = having_cuts if having_cuts is not None else []
4646

4747
def __and__(self, other):
4848
"""Returns a new cell that is a conjunction of the two provided
@@ -52,15 +52,15 @@ def __and__(self, other):
5252
"cubes '%s' and '%s'."
5353
% (self.name, other.name))
5454
cuts = self.cuts + other.cuts
55-
having_clauses = self.having_clauses + other.having_clauses
56-
return Cell(self.cube, cuts=cuts, having_clause=having_clauses)
55+
having_cuts = self.having_cuts + other.having_cuts
56+
return Cell(self.cube, cuts=cuts, having_cuts=having_cuts)
5757

5858
def to_dict(self):
5959
"""Returns a dictionary representation of the cell"""
6060
result = {
6161
"cube": str(self.cube.name),
6262
"cuts": [cut.to_dict() for cut in self.cuts],
63-
"having_clauses": [clause.to_dict() for clause in self.having_clauses]
63+
"having_cuts": [clause.to_dict() for clause in self.having_cuts]
6464
}
6565

6666
return result

cubes/sql/browser.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -579,25 +579,26 @@ def aggregation_statement(self, cell, aggregates, drilldown=None,
579579
else:
580580
selection += aggregate_cols
581581

582-
# namnd added:
583-
# HAVING
582+
# madman: HAVING
584583
# ------
585-
having_clauses = context.clause_for_having(cell)
586-
havings = having_clauses["condition"]
587-
group_clauses = having_clauses["groups"]
588-
if group_by is None:
589-
group_by = []
590-
for group in group_clauses:
591-
if group not in group_by:
592-
group_by.append(group)
584+
having_clauses = None
585+
colums_and_havings = context.colums_and_having_cut_for_cell(cell)
586+
if colums_and_havings is not None:
587+
having_clauses = colums_and_havings[1]
588+
group_clauses = colums_and_havings[0]
589+
if group_by is None:
590+
group_by = []
591+
for group in group_clauses:
592+
if group not in group_by:
593+
group_by.append(group)
593594

594595
statement = sql.expression.select(selection,
595596
from_obj=context.star,
596597
use_labels=True,
597598
whereclause=condition,
598599
group_by=group_by,
599-
having=havings)
600-
# print("statement: {}".format(statement))
600+
having=having_clauses)
601+
601602
return (statement, context.get_labels(statement.columns))
602603

603604
def _log_statement(self, statement, label=None):

cubes/sql/query.py

Lines changed: 22 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,55 +1111,34 @@ def column_for_split(self, split_cell, label=None):
11111111

11121112
return split_column.label(label)
11131113

1114-
# namnd added
1115-
def clause_for_having(self, cell):
1116-
"""Returns a clause for having clause and attr for group. If cell is empty, not contain having or cell is
1114+
# madman: get having clause and attributes
1115+
def colums_and_having_cut_for_cell(self, cell):
1116+
"""Returns attributes and having clause. If cell is empty, not contain having or cell is
11171117
`None` then returns `None`."""
11181118

11191119
if not cell:
11201120
return None
11211121

1122-
clauses = self.clauses_for_having(cell.having_clauses)
1123-
condition = and_(*clauses["condition"])
1124-
clauses["condition"] = condition
1125-
return clauses
1122+
having_cuts = cell.having_cuts
1123+
hav_condition = and_(*self.conditions_for_cuts(having_cuts))
11261124

1127-
# namnd added
1128-
def clauses_for_having(self, having_clauses):
1129-
clauses = []
1130-
groups = []
1131-
for cut in having_clauses:
1132-
hierarchy = str(cut.hierarchy) if cut.hierarchy else None
1133-
if isinstance(cut, PointCut):
1134-
path = cut.path
1135-
hav_conds = self.having_condition(str(cut.dimension),
1136-
path,
1137-
hierarchy, cut.invert)
1138-
clauses.append(hav_conds["condition"])
1139-
groups += hav_conds["group"]
1140-
# return one dict
1141-
dict_clause = {"groups": groups, "condition": clauses}
1142-
return dict_clause
1143-
1144-
# namnd added
1145-
def having_condition(self, dim, path, hierarchy=None, invert=False):
1146-
"""Returns a dict of `Condition` tuple (`attributes`, `conditions`,
1147-
`group_by`) dimension `dim` point at `path` and list group attrs use having. It is a compound
1148-
condition - one equality condition for each path element in form:
1149-
``level[i].key = path[i]``"""
1150-
conditions = []
1151-
groups = []
1152-
levels = self.level_keys(dim, hierarchy, path)
1153-
for level_key, value in zip(levels, path):
1154-
# Prepare condition: dimension.level_key = path_value
1155-
column = self.column(level_key)
1156-
conditions.append(column == value)
1157-
groups.append(column)
1125+
if hav_condition is None:
1126+
return None
11581127

1159-
condition = sql.expression.and_(*conditions)
1128+
colums = self.colums_in_having_cuts(having_cuts)
11601129

1161-
if invert:
1162-
condition = sql.expression.not_(condition)
1130+
return (colums, hav_condition)
1131+
1132+
# madman: get attributes in having cuts
1133+
def colums_in_having_cuts(self, having_cus):
1134+
1135+
columns = []
1136+
1137+
for cut in having_cus:
1138+
hierarchy = str(cut.hierarchy) if cut.hierarchy else None
1139+
levels = self.hierarchies[(str(cut.dimension), hierarchy)]
1140+
for level_key in levels:
1141+
column = self.column(level_key)
1142+
columns.append(column)
11631143

1164-
dict_condition = {"group": groups, "condition": condition}
1165-
return dict_condition
1144+
return columns

0 commit comments

Comments
 (0)