def tuple_element_for_shape_el( shape_el: irast.Set, value: Optional[pgast.BaseExpr] = None, *, ctx: context.CompilerContextLevel) -> pgast.TupleElementBase: if shape_el.path_id.is_type_intersection_path(): assert shape_el.rptr is not None rptr = shape_el.rptr.source.rptr else: rptr = shape_el.rptr assert rptr is not None ptrref = rptr.ptrref ptrname = ptrref.shortname if value is not None: return pgast.TupleElement( path_id=shape_el.path_id, name=ptrname.name, val=value, ) else: return pgast.TupleElementBase( path_id=shape_el.path_id, name=ptrname.name, )
def _get_path_output(rel: pgast.BaseRelation, path_id: irast.PathId, *, aspect: str, allow_nullable: bool = True, ptr_info: typing.Optional[ pg_types.PointerStorageInfo] = None, env: context.Environment) -> pgast.OutputVar: result = rel.path_outputs.get((path_id, aspect)) if result is not None: return result ref: pgast.BaseExpr alias = None rptr = path_id.rptr() if rptr is not None and irtyputils.is_id_ptrref(rptr): # A value reference to Object.id is the same as a value # reference to the Object itself. src_path_id = path_id.src_path() id_output = rel.path_outputs.get((src_path_id, 'value')) if id_output is not None: _put_path_output_var(rel, path_id, aspect, id_output, env=env) return id_output if is_terminal_relation(rel): return _get_rel_path_output(rel, path_id, aspect=aspect, ptr_info=ptr_info, env=env) assert isinstance(rel, pgast.Query) if is_values_relation(rel): # The VALUES() construct seems to always expose its # value as "column1". alias = 'column1' ref = pgast.ColumnRef(name=[alias]) else: ref = get_path_var(rel, path_id, aspect=aspect, env=env) other_output = find_path_output(rel, path_id, ref, env=env) if other_output is not None: _put_path_output_var(rel, path_id, aspect, other_output, env=env) return other_output if isinstance(ref, pgast.TupleVarBase): elements = [] for el in ref.elements: el_path_id = reverse_map_path_id(el.path_id, rel.view_path_id_map) try: # Similarly to get_path_var(), check for outer path_id # first for tuple serialized var disambiguation. element = _get_path_output(rel, el_path_id, aspect=aspect, allow_nullable=False, env=env) except LookupError: element = get_path_output(rel, el_path_id, aspect=aspect, allow_nullable=False, env=env) elements.append( pgast.TupleElementBase(path_id=el_path_id, name=element)) result = pgast.TupleVarBase(elements=elements, named=ref.named) else: if astutils.is_set_op_query(rel): assert isinstance(ref, pgast.OutputVar) result = astutils.strip_output_var(ref) else: assert isinstance(rel, pgast.ReturningQuery), \ "expected ReturningQuery" if alias is None: alias = get_path_output_alias(path_id, aspect, env=env) restarget = pgast.ResTarget(name=alias, val=ref, ser_safe=getattr( ref, 'ser_safe', False)) rel.target_list.append(restarget) nullable = is_nullable(ref, env=env) optional = None if isinstance(ref, pgast.ColumnRef): optional = ref.optional if nullable and not allow_nullable: var = get_path_var(rel, path_id, aspect=aspect, env=env) rel.where_clause = astutils.extend_binop( rel.where_clause, pgast.NullTest(arg=var, negated=True)) nullable = False result = pgast.ColumnRef(name=[alias], nullable=nullable, optional=optional) _put_path_output_var(rel, path_id, aspect, result, env=env) if (path_id.is_objtype_path() and not isinstance(result, pgast.TupleVarBase)): equiv_aspect = None if aspect == 'identity': equiv_aspect = 'value' elif aspect == 'value': equiv_aspect = 'identity' if (equiv_aspect is not None and (path_id, equiv_aspect) not in rel.path_outputs): _put_path_output_var(rel, path_id, equiv_aspect, result, env=env) return result