def compile_to_ir(expr, schema, *, anchors=None, path_prefix_anchor=None, security_context=None, modaliases=None, implicit_id_in_shapes=False, implicit_tid_in_shapes=False): """Compile given EdgeQL statement into EdgeDB IR.""" if debug.flags.edgeql_compile: debug.header('EdgeQL TEXT') debug.print(expr) tree = ql_parser.parse(expr, modaliases) return compile_ast_to_ir(tree, schema, anchors=anchors, path_prefix_anchor=path_prefix_anchor, security_context=security_context, modaliases=modaliases, implicit_id_in_shapes=implicit_id_in_shapes, implicit_tid_in_shapes=implicit_tid_in_shapes)
def compile_func_to_ir(func, schema, *, anchors=None, security_context=None, modaliases=None, implicit_id_in_shapes=False, implicit_tid_in_shapes=False): """Compile an EdgeQL function into EdgeDB IR.""" if debug.flags.edgeql_compile: debug.header('EdgeQL Function') debug.print(func.get_code(schema)) trees = ql_parser.parse_block(func.get_code(schema) + ';') if len(trees) != 1: raise errors.InvalidFunctionDefinitionError( 'functions can only contain one statement') tree = trees[0] if modaliases: ql_parser.append_module_aliases(tree, modaliases) param_anchors, param_aliases = get_param_anchors_for_callable( func.get_params(schema), schema) if anchors is None: anchors = {} anchors.update(param_anchors) tree.aliases.extend(param_aliases) ir = compile_ast_to_ir( tree, schema, anchors=anchors, func_params=func.get_params(schema), security_context=security_context, modaliases=modaliases, implicit_id_in_shapes=implicit_id_in_shapes, implicit_tid_in_shapes=implicit_tid_in_shapes, # the body of a session_only function can contain calls to # other session_only functions session_mode=func.get_session_only(schema)) return ir
def compile_func_to_ir(func, schema, *, anchors=None, security_context=None, modaliases=None, implicit_id_in_shapes=False, implicit_tid_in_shapes=False): """Compile an EdgeQL function into EdgeDB IR.""" if debug.flags.edgeql_compile: debug.header('EdgeQL Function') debug.print(func.get_code(schema)) trees = ql_parser.parse_block(func.get_code(schema) + ';') if len(trees) != 1: raise errors.InvalidFunctionDefinitionError( 'functions can only contain one statement') tree = trees[0] if modaliases: ql_parser.append_module_aliases(tree, modaliases) param_anchors, param_aliases = get_param_anchors_for_callable( func.get_params(schema), schema, inlined_defaults=func.has_inlined_defaults(schema)) if anchors is None: anchors = {} anchors.update(param_anchors) tree.aliases.extend(param_aliases) ir = compile_ast_to_ir( tree, schema, anchors=anchors, func_params=func.get_params(schema), security_context=security_context, modaliases=modaliases, implicit_id_in_shapes=implicit_id_in_shapes, implicit_tid_in_shapes=implicit_tid_in_shapes, # the body of a session_only function can contain calls to # other session_only functions session_mode=func.get_session_only(schema)) return_type = func.get_return_type(schema) if (not ir.stype.issubclass(schema, return_type) and not ir.stype.implicitly_castable_to(return_type, schema)): raise errors.InvalidFunctionDefinitionError( f'return type mismatch in function declared to return ' f'{return_type.get_verbosename(schema)}', details=f'Actual return type is ' f'{ir.stype.get_verbosename(schema)}', context=tree.context, ) return_typemod = func.get_return_typemod(schema) if (return_typemod is not qltypes.TypeModifier.SET_OF and ir.cardinality is qltypes.Cardinality.MANY): raise errors.InvalidFunctionDefinitionError( f'return cardinality mismatch in function declared to return ' f'a singleton', details=f'Function may return a set with more than one element.', context=tree.context, ) return ir
def compile_func_to_ir(func, schema, *, anchors=None, security_context=None, modaliases=None, implicit_id_in_shapes=False, implicit_tid_in_shapes=False): """Compile an EdgeQL function into EdgeDB IR.""" if debug.flags.edgeql_compile: debug.header('EdgeQL Function') debug.print(func.get_code(schema)) trees = ql_parser.parse_block(func.get_code(schema) + ';') if len(trees) != 1: raise errors.InvalidFunctionDefinitionError( 'functions can only contain one statement') tree = trees[0] if modaliases: ql_parser.append_module_aliases(tree, modaliases) if anchors is None: anchors = {} anchors['__defaults_mask__'] = irast.Parameter( name='__defaults_mask__', typeref=irtyputils.type_to_typeref(schema, schema.get('std::bytes'))) func_params = func.get_params(schema) pg_params = s_func.PgParams.from_params(schema, func_params) for pi, p in enumerate(pg_params.params): p_shortname = p.get_shortname(schema) anchors[p_shortname] = irast.Parameter( name=p_shortname, typeref=irtyputils.type_to_typeref(schema, p.get_type(schema))) if p.get_default(schema) is None: continue tree.aliases.append( qlast.AliasedExpr( alias=p_shortname, expr=qlast.IfElse( condition=qlast.BinOp( left=qlast.FunctionCall( func=('std', 'bytes_get_bit'), args=[ qlast.FuncArg( arg=qlast.Path(steps=[ qlast.ObjectRef( name='__defaults_mask__') ])), qlast.FuncArg( arg=qlast.IntegerConstant(value=str(pi))) ]), right=qlast.IntegerConstant(value='0'), op='='), if_expr=qlast.Path( steps=[qlast.ObjectRef(name=p_shortname)]), else_expr=qlast._Optional(expr=p.get_ql_default(schema))))) ir = compile_ast_to_ir( tree, schema, anchors=anchors, func=func, security_context=security_context, modaliases=modaliases, implicit_id_in_shapes=implicit_id_in_shapes, implicit_tid_in_shapes=implicit_tid_in_shapes) return ir
def compile_func_to_ir( func: s_func.Function, schema: s_schema.Schema, ) -> irast.Statement: """Compile an EdgeQL function into EdgeDB IR. Args: func: A function object. schema: A schema instance where the function is defined. Returns: An instance of :class:`ir.ast.Statement` representing the function body. """ if debug.flags.edgeql_compile: debug.header('EdgeQL Function') debug.print(func.get_code(schema)) code = func.get_code(schema) assert code is not None trees = ql_parser.parse_block(code + ';') if len(trees) != 1: raise errors.InvalidFunctionDefinitionError( 'functions can only contain one statement') tree = trees[0] param_anchors, param_aliases = get_param_anchors_for_callable( func.get_params(schema), schema, inlined_defaults=func.has_inlined_defaults(schema)) tree.aliases.extend(param_aliases) ir = compile_ast_to_ir( tree, schema, anchors=param_anchors, # type: ignore # (typing#273) func_params=func.get_params(schema), # the body of a session_only function can contain calls to # other session_only functions session_mode=func.get_session_only(schema), ) assert isinstance(ir, irast.Statement) return_type = func.get_return_type(schema) if (not ir.stype.issubclass(schema, return_type) and not ir.stype.implicitly_castable_to(return_type, schema)): raise errors.InvalidFunctionDefinitionError( f'return type mismatch in function declared to return ' f'{return_type.get_verbosename(schema)}', details=f'Actual return type is ' f'{ir.stype.get_verbosename(schema)}', context=tree.context, ) return_typemod = func.get_return_typemod(schema) if (return_typemod is not qltypes.TypeModifier.SET_OF and ir.cardinality is qltypes.Cardinality.MANY): raise errors.InvalidFunctionDefinitionError( f'return cardinality mismatch in function declared to return ' f'a singleton', details=f'Function may return a set with more than one element.', context=tree.context, ) return ir