def test_simple_query_merge(): book_id = SQLQuery( ["users", "books"], "books.id", {"users.id": 1, "books.user_id": sql_query_dict.mysql_col("user.id")} ) combined = SQLQuery(["books"], "books.name", {"books.id": book_id}) combined.flatten() assert combined == SQLQuery( "users, books", "books.name", {"users.id": 1, "books.user_id": sql_query_dict.mysql_col("user.id")} )
def flatten(self): """ merge any SQLQuery objects on the rhs of a where clause into self. """ self._assert_flattenable() for k, v in self.where.copy().items(): if isinstance(v, SQLQuery): v._assert_flattenable() self.tables.update(v.tables) self._assert_no_overlapping_where(v.where) self.where.update(v.where) if len(v.selects) != 1: raise ValueError(( 'SQLQuery merging is only possible when ' 'the embedded query has one select. has: {}' ).format(', '.join(v.selects))) self.where[k] = sql_query_dict.mysql_col(v.selects[0]) # we just did a join, so definitely not just the first self.first = False self.cleanup()
def test_simple_query_merge(): book_id = SQLQuery(['users', 'books'], 'books.id', { 'users.id': 1, 'books.user_id': sql_query_dict.mysql_col('user.id'), }) combined = SQLQuery(['books'], 'books.name', { 'books.id': book_id }) combined.flatten() assert combined == SQLQuery( 'users, books', 'books.name', { 'users.id': 1, 'books.user_id': sql_query_dict.mysql_col('user.id'), })
def merge_parent_child(child, parent): """ NOTE: child and parent are switched here, it makes more sense """ parent.function._assert_flattenable() child.function._assert_flattenable() function = parent.function.copy() for k, v in function.input_mapping.items(): child_function = child.function.copy() # simply merge these parts of the SQLQuery function.tables.update(child_function.tables) function.where.update(child_function.where) function.selects.extend(child_function.selects) # join where clause and selects # the connecting path is the path which is set by the child and # read by the parent connecting_path = parent.input_path_by_property(k) # lookup the order that this path occurrs in the outputs so we can # match it up with the correct select i = child.outgoing_paths.index(connecting_path) # join in the where clause function.where[v] = sql_query_dict.mysql_col( child_function.selects[i] ) # remove unnecessary complexity function.cleanup() # TODO: assumes that all inputs were from SQLQuery objects function.input_mapping = child.function.input_mapping # even if there is just one column, this also works so long as # Cardinality.many function.one_column = False function.first = False inputs = child.incoming_paths outputs = parent.outgoing_paths + child.outgoing_paths relations = parent.relations + child.relations return Node( None, inputs, outputs, function, Cardinality.many, relations )