def get_longest_paths(ir: irast.Base) -> Set[irast.Set]: """Return a distinct set of longest paths found in an expression. For example in SELECT (A.B.C, D.E.F, A.B, D.E) the result would be {A.B.C, D.E.F}. """ result = set() parents = set() flt = lambda n: isinstance(n, irast.Set) and n.expr is None ir_sets = ast.find_children(ir, flt) for ir_set in ir_sets: result.add(ir_set) if ir_set.rptr: parents.add(ir_set.rptr.source) return result - parents
def _classname_quals_from_ast( cls, schema: s_schema.Schema, astnode: qlast.NamedDDL, base_name: str, referrer_name: str, context: sd.CommandContext, ) -> Tuple[str, ...]: assert isinstance(astnode, qlast.IndexOp) # use the normalized text directly from the expression expr = s_expr.Expression.from_ast(astnode.expr, schema, context.modaliases) expr_text = expr.text assert expr_text is not None expr_qual = cls._name_qual_from_exprs(schema, (expr_text, )) ptrs = ast.find_children(astnode, lambda n: isinstance(n, qlast.Ptr)) ptr_name_qual = '_'.join(ptr.ptr.name for ptr in ptrs) if not ptr_name_qual: ptr_name_qual = 'idx' return (expr_qual, ptr_name_qual)
def _edgeql_ref_to_pg_constr(cls, subject, tree, schema, link_bias): sql_tree = compiler.compile_ir_to_sql_tree( tree, singleton_mode=True) if isinstance(sql_tree, pg_ast.SelectStmt): # XXX: use ast pattern matcher for this sql_expr = sql_tree.from_clause[0].relation\ .query.target_list[0].val else: sql_expr = sql_tree if isinstance(tree, irast.Statement): tree = tree.expr if isinstance(tree.expr, irast.SelectStmt): tree = tree.expr.result is_multicol = irtyputils.is_tuple(tree.typeref) # Determine if the sequence of references are all simple refs, not # expressions. This influences the type of Postgres constraint used. # is_trivial = ( isinstance(sql_expr, pg_ast.ColumnRef) or ( isinstance(sql_expr, pg_ast.ImplicitRowExpr) and all( isinstance(el, pg_ast.ColumnRef) for el in sql_expr.args))) # Find all field references # flt = lambda n: isinstance(n, pg_ast.ColumnRef) and len(n.name) == 1 refs = set(ast.find_children(sql_expr, flt)) if isinstance(subject, s_scalars.ScalarType): # Domain constraint, replace <scalar_name> with VALUE subject_pg_name = common.edgedb_name_to_pg_name(str(subject.id)) for ref in refs: if ref.name != [subject_pg_name]: raise ValueError( f'unexpected node reference in ' f'ScalarType constraint: {".".join(ref.name)}' ) # work around the immutability check object.__setattr__(ref, 'name', ['VALUE']) plain_expr = codegen.SQLSourceGenerator.to_source(sql_expr) if is_multicol: chunks = [] for elem in sql_expr.args: chunks.append(codegen.SQLSourceGenerator.to_source(elem)) else: chunks = [plain_expr] if isinstance(sql_expr, pg_ast.ColumnRef): refs.add(sql_expr) for ref in refs: ref.name.insert(0, 'NEW') new_expr = codegen.SQLSourceGenerator.to_source(sql_expr) for ref in refs: ref.name[0] = 'OLD' old_expr = codegen.SQLSourceGenerator.to_source(sql_expr) exprdata = dict( plain=plain_expr, plain_chunks=chunks, new=new_expr, old=old_expr) return dict( exprdata=exprdata, is_multicol=is_multicol, is_trivial=is_trivial)
def find_paths(ql: qlast.Base) -> List[qlast.Path]: paths: List[qlast.Path] = ast.find_children( ql, lambda x: isinstance(x, qlast.Path), ) return paths
def is_const(ir: irast.Base) -> bool: """Return True if the given *ir* expression is constant.""" flt = lambda n: isinstance(n, irast.Set) and n.expr is None and n is not ir ir_sets = ast.find_children(ir, flt) variables = get_parameters(ir) return not ir_sets and not variables
def get_parameters(ir: irast.Base) -> Set[irast.Parameter]: """Return all parameters found in *ir*.""" result: Set[irast.Parameter] = set() flt = lambda n: isinstance(n, irast.Parameter) result.update(ast.find_children(ir, flt)) return result
def contains_set_of_op(ir: irast.Base) -> bool: flt = (lambda n: isinstance(n, irast.Call) and any( x == ft.TypeModifier.SetOfType for x in n.params_typemods)) return bool(ast.find_children(ir, flt, terminate_early=True))
def is_const(ir): flt = lambda n: isinstance(n, irast.Set) and n.expr is None ir_sets = ast.find_children(ir, flt) variables = get_variables(ir) return not ir_sets and not variables
def get_variables(ir): result = set() flt = lambda n: isinstance(n, irast.Parameter) result.update(ast.find_children(ir, flt)) return result