# # The FOREACH relational operator # module Wukong module AndPig class PigVar # =========================================================================== # # FOREACH # def generate lval, *field_specs gen_clauses = field_specs.map{|field_spec| parse_gen_clause(field_spec)}.flatten l_klass = TypedStruct.new(* gen_clauses.map(&:name_type)) l_cmd = "FOREACH #{self.relation} GENERATE\n #{gen_clauses.join(",\n ")}" new_in_chain(lval, l_klass, l_cmd) end # # for a list of GENERATE args, we need # # * gen_clauses, the clause to stuff into the GENERATE line # gen_expr AS gen_field_name: gen_field_type # # * new_types, the resulting types for each # # gen_expr common cases include # # field # Rel::field # Rel.(field) # "ComplicatedExpression" # # # field_attrs # # def parse_gen_clause field_spec case field_spec when AS field_spec when Symbol AS[field_spec, field_spec, field_type(field_spec)]; when Array alias_in, field_in, name, type = field_spec name ||= field_in type = alias_in.field_type(field_in) AS[field_in, name, type, alias_in.relationize] when Hash field_spec.map do |field_in, field_out| AS[field_in, field_out, field_type(field_in)] end else raise "Don't know how to specify type for #{field_specs.inspect}" end end end end end # # when Array # # unless [2,3].include?(field_spec.length) then raise "Complex fields must be (field_spec, as_name) or (field_spec, as_name, as_type)" end # # field_expr, field_attr, field_type = field_spec # # field_as = field_attr.is_a?(Array) ? "(#{field_attr.join(", ")})" : field_attr # # gen_clauses << "#{field_expr} AS #{field_as}" # # field_attrs << [field_attr, field_type || klass.members_types[field_expr]] # def prelimify *field_specs # gen_clauses = [] # field_attrs = [] # field_specs.map do |field_spec| # unless field_spec.length == 2 then raise "Complex fields must be a pair (field_spec, as_name)" end # field_expr, field_attr = field_spec # gen_clauses << "#{field_expr}" # field_attrs += [field_attr].flatten # end # [ gen_clauses, field_attrs ] # end # # # def generate *args # # gen_clauses, field_attrs = self.class.fieldify *args # # l_klass = TypedStruct.new(*field_attrs) # # new_in_chain l_klass, "FOREACH #{relation} GENERATE\n #{gen_clauses.join(",\n ")}" # # end # # def foreach *args # generate_clause = args.pop # prelim_exprs, prelim_attrs = prelimify *args # prelims = prelim_exprs.zip(prelim_attrs).map{|e,a| "#{a} = #{e}" }.join(";\n ")+";" # gen_clauses, field_attrs = fieldify *generate_clause # l_klass = TypedStruct.new(*field_attrs) # new_in_chain l_klass, %Q{FOREACH #{relation} {\n #{prelims}\n GENERATE\n #{gen_clauses.join(",\n ")} ; } } # end