engine: remove use of cross join (#38691)
It prevented reporting of NULL values.
This commit is contained in:
parent
8f204362a4
commit
16b60621d4
|
@ -371,7 +371,6 @@ class EngineCube(object):
|
|||
where = []
|
||||
group_by = []
|
||||
order_by = []
|
||||
join_conditions = []
|
||||
|
||||
for dimension_name, values in filters:
|
||||
dimension = self.dimensions[dimension_name]
|
||||
|
@ -381,7 +380,7 @@ class EngineCube(object):
|
|||
if dimension.filter_needs_join and dimension.join:
|
||||
joins.update(dimension.join)
|
||||
if dimension.filter_in_join:
|
||||
join_conditions.append(condition)
|
||||
assert False, 'filter in join is not supported anymore'
|
||||
else:
|
||||
where.append(condition)
|
||||
|
||||
|
@ -403,8 +402,7 @@ class EngineCube(object):
|
|||
sql = 'SELECT ' + ', '.join(projections)
|
||||
table_expression = ' %s' % self.cube.fact_table
|
||||
if joins:
|
||||
table_expression = self.build_table_expression(
|
||||
joins, self.fact_table, other_conditions=join_conditions)
|
||||
table_expression = self.build_table_expression(joins, self.fact_table)
|
||||
sql += ' FROM %s' % table_expression
|
||||
where_conditions = 'true'
|
||||
if where:
|
||||
|
@ -450,7 +448,14 @@ class EngineCube(object):
|
|||
))
|
||||
yield cells
|
||||
|
||||
def build_table_expression(self, joins, table_name, other_conditions=None):
|
||||
JOIN_KINDS = {
|
||||
'inner': 'INNER JOIN',
|
||||
'left': 'LEFT OUTER JOIN',
|
||||
'right': 'RIGHT OUTER JOIN',
|
||||
'full': 'FULL OUTER JOIN',
|
||||
}
|
||||
|
||||
def build_table_expression(self, joins, table_name):
|
||||
'''Recursively build the table expression from the join tree,
|
||||
starting from the fact table'''
|
||||
|
||||
|
@ -461,45 +466,37 @@ class EngineCube(object):
|
|||
master_table = join.master_table or self.fact_table
|
||||
join_tree.setdefault(master_table, {}).setdefault(join.kind, {})[join.name] = join
|
||||
|
||||
def build_table_expression_helper(join_tree, table_name, alias=None, top=True, other_conditions=None):
|
||||
def build_table_expression_helper(join_tree, table_name, alias=None, top=True):
|
||||
contain_joins = False
|
||||
|
||||
sql = table_name
|
||||
if alias:
|
||||
sql += ' AS %s' % quote(alias)
|
||||
add_paren = False
|
||||
|
||||
for kind in ['left', 'inner', 'right', 'full']:
|
||||
joins = join_tree.get(alias or table_name, {}).get(kind)
|
||||
if not joins:
|
||||
continue
|
||||
add_paren = True
|
||||
join_kinds = {
|
||||
'inner': 'INNER JOIN',
|
||||
'left': 'LEFT OUTER JOIN',
|
||||
'right': 'RIGHT OUTER JOIN',
|
||||
'full': 'FULL OUTER JOIN',
|
||||
}
|
||||
sql += ' %s ' % join_kinds[kind]
|
||||
sub_joins = []
|
||||
conditions = []
|
||||
if other_conditions:
|
||||
conditions = other_conditions
|
||||
other_conditions = None
|
||||
for join_name, join in joins.iteritems():
|
||||
sub_joins.append(
|
||||
build_table_expression_helper(join_tree, join.table, alias=join.name, top=False))
|
||||
conditions.append('%s.%s = %s.%s' % (
|
||||
contain_joins = True
|
||||
sql += ' %s ' % self.JOIN_KINDS[kind]
|
||||
sql += ' ' + build_table_expression_helper(join_tree, join.table, alias=join.name, top=False)
|
||||
condition = '%s.%s = %s.%s' % (
|
||||
alias or table_name,
|
||||
join.master.split('.')[-1],
|
||||
quote(join.name), join.detail))
|
||||
sub_join = ' CROSS JOIN '.join(sub_joins)
|
||||
if len(sub_joins) > 1:
|
||||
sub_join = '(%s)' % sub_join
|
||||
sql += sub_join
|
||||
sql += ' ON %s' % ' AND '.join(conditions)
|
||||
if not top and add_paren:
|
||||
quote(join.name),
|
||||
join.detail)
|
||||
sql += ' ON ' + condition
|
||||
|
||||
# if the table expression contains joins and is not the full table
|
||||
# expression but used in another join, it must be quoted with
|
||||
# parenthesis
|
||||
if not top and contain_joins:
|
||||
sql = '(%s)' % sql
|
||||
|
||||
return sql
|
||||
return build_table_expression_helper(
|
||||
join_tree, table_name, other_conditions=other_conditions)
|
||||
|
||||
return build_table_expression_helper(join_tree, table_name)
|
||||
|
||||
|
||||
class Engine(object):
|
||||
|
|
|
@ -328,7 +328,7 @@ class Join(Base):
|
|||
'kind': join_kind,
|
||||
}
|
||||
|
||||
kind = 'right'
|
||||
kind = 'full'
|
||||
|
||||
@property
|
||||
def master_table(self):
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue