| 154 | |
| 155 | |
| 156 | def query(self): |
| 157 | def render_col(c): |
| 158 | return '%s.%s' % (c[0].name, c[2]) if c[0] else c[2] |
| 159 | |
| 160 | # build join conditions |
| 161 | first_source_name = list(self.sources.keys())[0].name |
| 162 | join_where = flatten([['%s.%s = %s.%s' % (s.name, c, first_source_name, c) for c in ['pid', 'task', 'event_time']] for s in list(self.sources.keys())[1:]]) |
| 163 | |
| 164 | attr = { |
| 165 | 'projection': '\t' + ',\n\t'.join([render_col(c) for c in self.full_projection()]), |
| 166 | 'tables': '\t' + ',\n\t'.join([s.name for s in self.sources]), |
| 167 | 'where': '\t' + ' AND\n\t'.join([c[2] for c in self.where] + join_where), |
| 168 | 'dimensions': '\t' + ',\n\t'.join([render_col(c) for c in self.dimensions]), |
| 169 | 'order': '\t' + ',\n\t'.join([render_col(c) + ' DESC' for c in self.order]), |
| 170 | 'num_sample_events': '(SELECT COUNT(DISTINCT(event_time)) FROM %s)' % first_source_name |
| 171 | } |
| 172 | |
| 173 | logging.debug('attr where=%s#end' % attr['where']) |
| 174 | |
| 175 | sql = 'SELECT\n%(projection)s\nFROM\n%(tables)s' % attr |
| 176 | # tanel changed from self.where to attr['where'] |
| 177 | # TODO think through the logic of using self.where vs attr.where (in the context of allowing pid/tid to be not part of group by) |
| 178 | if attr['where'].strip(): |
| 179 | sql += '\nWHERE\n%(where)s' % attr |
| 180 | if attr['dimensions']: |
| 181 | sql += '\nGROUP BY\n%(dimensions)s' % attr |
| 182 | if attr['order']: |
| 183 | sql += '\nORDER BY\n%(order)s' % attr |
| 184 | |
| 185 | # final substitution allows things like avg_threads to work |
| 186 | return sql % attr |
| 187 | |
| 188 | |
| 189 | def dataset(self, conn): |