def _to_ibis_table(self, query_info: QueryInfo): """ Returns the dataframe resulting from the SQL query :return: """ query_info.perform_transformation() relation = self._get_relation(query_info) self._set_casing_for_groupby_names(query_info) selected_group_columns = [] group_column_names = { group_column.group_by_name for group_column in query_info.group_columns } if query_info.group_columns and query_info.aggregates: selection_column_names = [ column.get_name() for column in query_info.columns ] remaining_columns = set( selection_column_names) - group_column_names if remaining_columns: raise InvalidQueryException( f"Must have grouping for columns in {remaining_columns}") selected_group_columns = [ column for column in query_info.columns if column.get_name() in set(group_column_names) ] query_info.columns = [ column for column in query_info.columns if column.get_name() in remaining_columns ] new_table = self.handle_filtering(relation, query_info.where_expr, query_info.internal_transformer) new_table = self.handle_selection(new_table, query_info.columns) new_table = self.handle_aggregation( query_info.aggregates, query_info.group_columns, new_table, query_info.having_expr, query_info.internal_transformer, selected_group_columns, ) if query_info.distinct: new_table = new_table.distinct() order_by = query_info.order_by if order_by: new_table = new_table.sort_by(order_by) if query_info.limit is not None: new_table = new_table.head(query_info.limit) return new_table
def query_expr(self, query_info: QueryInfo, *args): """ Handles the full query, including order and set operations such as union :param query_info: Map of all query information :param args: Additional arguments aside from query info :return: Query info """ for token in args: if isinstance(token, OrderByInfo): query_info.add_order_by_info(token) if isinstance(token, LimitExpression): query_info.limit = token.limit return query_info
def _reevaluate_transformation(query_info: QueryInfo, relations: List[TableExpr]): DerivedColumn.reset_expression_count() internal_transformer = InternalTransformerWithStarVal.from_internal_transformer( internal_transformer=query_info.internal_transformer, available_relations=relations, ) query_info = QueryInfo( internal_transformer, query_info.select_expressions_no_boolean_clauses, query_info.having_expr, query_info.where_expr, ) query_info.perform_transformation() return query_info
def _handle_join_subqueries(self, join: JoinBase) -> QueryInfo: info = QueryInfo( InternalTransformer( join.get_tables(), join.get_table_map(), self._column_name_map, self._column_to_table_name, self._table_name_map, self._alias_registry, ), ) info.add_table(join) info.add_column(Column(name="*")) return info
def select(self, *select_expressions: Tuple[Tree]) -> QueryInfo: """ Forms the final sequence of methods that will be executed :param select_expressions: :return: """ tables: List[Token] = [] having_expr = None where_expr = None for select_expression in select_expressions: if isinstance(select_expression, Tree): if select_expression.data == "from_expression": table_object = select_expression.children[0] if isinstance(table_object, JoinBase): tables += [ table_object.right_table, table_object.left_table, ] elif (isinstance(table_object, Tree) and table_object.data == "cross_join_expression"): cross_join: CrossJoin = table_object.children[0] tables += [ cross_join.right_table, cross_join.left_table, ] else: tables.append(table_object) elif select_expression.data == "having_expr": having_expr = select_expression elif select_expression.data == "where_expr": where_expr = select_expression internal_transformer = InternalTransformer( tables, # type: ignore self._table_map, self._column_name_map, self._column_to_table_name, self._table_name_map, self._alias_registry, ) select_expressions_no_boolean_clauses: List[Union[str, Tree]] = [] distinct = False for select_expression in select_expressions: if isinstance(select_expression, Tree) and select_expression.data not in ( "having_expr", "where_expr", ): select_expressions_no_boolean_clauses.append(select_expression) if (isinstance(select_expression, Token) and select_expression.value.lower() == "distinct"): distinct = True return QueryInfo( internal_transformer, select_expressions_no_boolean_clauses, having_expr=having_expr, where_expr=where_expr, distinct=distinct, )