def reduce_For(self, *kids): r"%reduce FOR Identifier IN Set \ UNION OptionallyAliasedExpr \ OptFilterClause OptSortClause OptSelectLimit" offset, limit = kids[8].val if offset is not None or limit is not None: subj = qlast.ForQuery( iterator_alias=kids[1].val, iterator=kids[3].val, result=kids[5].val.expr, result_alias=kids[5].val.alias, where=kids[6].val, orderby=kids[7].val, implicit=True, ) self.val = qlast.SelectQuery( result=subj, offset=offset, limit=limit, ) else: self.val = qlast.ForQuery( iterator_alias=kids[1].val, iterator=kids[3].val, result=kids[5].val.expr, result_alias=kids[5].val.alias, where=kids[6].val, orderby=kids[7].val, )
def reduce_For(self, *kids): r"%reduce FOR Identifier IN Set \ UNION OptionallyAliasedExpr" self.val = qlast.ForQuery( iterator_alias=kids[1].val, iterator=kids[3].val, result=kids[5].val.expr, result_alias=kids[5].val.alias, )
def reduce_For(self, *kids): r"%reduce FOR Identifier IN Set \ UNION OptionallyAliasedExpr \ OptFilterClause OptSortClause OptSelectLimit" self.val = qlast.ForQuery( iterator_alias=kids[1].val, iterator=kids[3].val, result=kids[5].val.expr, result_alias=kids[5].val.alias, where=kids[6].val, orderby=kids[7].val, offset=kids[8].val[0], limit=kids[8].val[1], )
def try_group_rewrite( node: qlast.Query, aliases: AliasGenerator, ) -> Optional[qlast.Query]: """ Try to apply some syntactic rewrites of GROUP expressions so we can generate better code. The two key desugarings are: * Sink a shape into the internal group result SELECT (GROUP ...) <shape> [filter-clause] [order-clause] [other clauses] => SELECT ( FOR GROUP ... UNION <igroup-body> <shape> [filter-clause] [order-clause] ) [other clauses] * Convert a FOR over a group into just an internal group (and a trivial FOR) FOR g in (GROUP ...) UNION <body> => FOR GROUP ... UNION ( FOR g IN (<group-body>) UNION <body> ) """ # TODO: would Python's new pattern matching fit well here??? # Sink shapes into the GROUP if ( isinstance(node, qlast.SelectQuery) and isinstance(node.result, qlast.Shape) and isinstance(node.result.expr, qlast.GroupQuery) ): igroup = desugar_group(node.result.expr, aliases) igroup = igroup.replace(result=qlast.Shape( expr=igroup.result, elements=node.result.elements)) # FILTER gets sunk into the body of the FOR GROUP if node.where or node.orderby: igroup = igroup.replace( # We need to move the result_alias in case # the FILTER depends on it. result_alias=node.result_alias, where=node.where, orderby=node.orderby, ) return node.replace( result=igroup, result_alias=None, where=None, orderby=None) # Eliminate FORs over GROUPs if ( isinstance(node, qlast.ForQuery) and isinstance(node.iterator, qlast.GroupQuery) ): igroup = desugar_group(node.iterator, aliases) new_result = qlast.ForQuery( iterator_alias=node.iterator_alias, iterator=igroup.result, result=node.result, ) return igroup.replace(result=new_result, aliases=node.aliases) return None