def init_context( *, schema: s_schema.Schema, func_params: typing.Optional[s_func.FuncParameterList]=None, parent_object_type: typing.Optional[s_obj.ObjectMeta]=None, modaliases: typing.Optional[typing.Dict[str, str]]=None, anchors: typing.Optional[typing.Dict[str, s_obj.Object]]=None, singletons: typing.Optional[typing.Iterable[s_types.Type]]=None, security_context: typing.Optional[str]=None, derived_target_module: typing.Optional[str]=None, result_view_name: typing.Optional[str]=None, schema_view_mode: bool=False, disable_constant_folding: bool=False, allow_generic_type_output: bool=False, allow_abstract_operators: bool=False, implicit_id_in_shapes: bool=False, implicit_tid_in_shapes: bool=False, json_parameters: bool=False, session_mode: bool=False) -> \ context.ContextLevel: stack = context.CompilerContext() ctx = stack.current if not schema.get_global(s_mod.Module, '__derived__', None): schema, _ = s_mod.Module.create_in_schema(schema, name='__derived__') ctx.env = context.Environment( schema=schema, path_scope=irast.new_scope_tree(), constant_folding=not disable_constant_folding, func_params=func_params, parent_object_type=parent_object_type, schema_view_mode=schema_view_mode, json_parameters=json_parameters, session_mode=session_mode, allow_abstract_operators=allow_abstract_operators, allow_generic_type_output=allow_generic_type_output) if singletons: # The caller wants us to treat these type references # as singletons for the purposes of the overall expression # cardinality inference, so we set up the scope tree in # the necessary fashion. for singleton in singletons: path_id = pathctx.get_path_id(singleton, ctx=ctx) ctx.env.path_scope.attach_path(path_id) ctx.path_scope = ctx.env.path_scope.attach_fence() if modaliases: ctx.modaliases.update(modaliases) if anchors: with ctx.newscope(fenced=True) as subctx: populate_anchors(anchors, ctx=subctx) ctx.derived_target_module = derived_target_module ctx.toplevel_result_view_name = result_view_name ctx.implicit_id_in_shapes = implicit_id_in_shapes ctx.implicit_tid_in_shapes = implicit_tid_in_shapes return ctx
def init_stmt( irstmt: irast.Stmt, qlstmt: qlast.Statement, *, ctx: context.ContextLevel, parent_ctx: context.ContextLevel) -> None: ctx.stmt = irstmt if ctx.toplevel_stmt is None: parent_ctx.toplevel_stmt = ctx.toplevel_stmt = irstmt if parent_ctx.path_scope is None: parent_ctx.path_scope = ctx.path_scope = irast.new_scope_tree() else: ctx.path_scope = parent_ctx.path_scope.attach_fence() pending_own_ns = parent_ctx.pending_stmt_own_path_id_namespace if pending_own_ns: ctx.path_scope.add_namespaces(pending_own_ns) pending_full_ns = parent_ctx.pending_stmt_full_path_id_namespace if pending_full_ns: ctx.path_id_namespace |= pending_full_ns metadata = ctx.stmt_metadata.get(qlstmt) if metadata is not None and metadata.is_unnest_fence: ctx.path_scope.unnest_fence = True irstmt.parent_stmt = parent_ctx.stmt process_with_block(qlstmt, ctx=ctx, parent_ctx=parent_ctx)
def compile_ir_to_sql_tree( ir_expr: irast.Base, *, output_format: Optional[OutputFormat] = None, ignore_shapes: bool = False, explicit_top_cast: Optional[irast.TypeRef] = None, singleton_mode: bool = False, use_named_params: bool = False, expected_cardinality_one: bool = False, external_rvars: Optional[ Mapping[Tuple[irast.PathId, str], pgast.PathRangeVar] ] = None, ) -> pgast.Base: try: # Transform to sql tree query_params = [] type_rewrites = {} if isinstance(ir_expr, irast.Statement): scope_tree = ir_expr.scope_tree query_params = list(ir_expr.params) type_rewrites = ir_expr.type_rewrites ir_expr = ir_expr.expr elif isinstance(ir_expr, irast.ConfigCommand): scope_tree = ir_expr.scope_tree else: scope_tree = irast.new_scope_tree() env = context.Environment( output_format=output_format, expected_cardinality_one=expected_cardinality_one, use_named_params=use_named_params, query_params=query_params, type_rewrites=type_rewrites, ignore_object_shapes=ignore_shapes, explicit_top_cast=explicit_top_cast, singleton_mode=singleton_mode, external_rvars=external_rvars, ) ctx = context.CompilerContextLevel( None, context.ContextSwitchMode.TRANSPARENT, env=env, scope_tree=scope_tree, ) _ = context.CompilerContext(initial=ctx) ctx.singleton_mode = singleton_mode ctx.expr_exposed = True qtree = dispatch.compile(ir_expr, ctx=ctx) except Exception as e: # pragma: no cover try: args = [e.args[0]] except (AttributeError, IndexError): args = [] raise errors.InternalServerError(*args) from e return qtree
def init_context( *, schema: s_schema.Schema, options: coptions.CompilerOptions, ) -> context.ContextLevel: if not schema.get_global(s_mod.Module, '__derived__', None): schema, _ = s_mod.Module.create_in_schema(schema, name='__derived__') env = context.Environment( schema=schema, path_scope=irast.new_scope_tree(), options=options, ) ctx = context.ContextLevel(None, context.ContextSwitchMode.NEW, env=env) _ = context.CompilerContext(initial=ctx) if options.singletons: # The caller wants us to treat these type references # as singletons for the purposes of the overall expression # cardinality inference, so we set up the scope tree in # the necessary fashion. for singleton in options.singletons: path_id = pathctx.get_path_id(singleton, ctx=ctx) ctx.env.path_scope.attach_path(path_id, context=None) ctx.path_scope = ctx.env.path_scope.attach_fence() ctx.modaliases.update(options.modaliases) if options.anchors: with ctx.newscope(fenced=True) as subctx: populate_anchors(options.anchors, ctx=subctx) if options.path_prefix_anchor is not None: path_prefix = options.anchors[options.path_prefix_anchor] assert isinstance(path_prefix, s_types.Type) ctx.partial_path_prefix = setgen.class_set(path_prefix, ctx=ctx) ctx.partial_path_prefix.anchor = options.path_prefix_anchor ctx.partial_path_prefix.show_as_anchor = options.path_prefix_anchor ctx.derived_target_module = options.derived_target_module ctx.toplevel_result_view_name = options.result_view_name ctx.implicit_id_in_shapes = options.implicit_id_in_shapes ctx.implicit_tid_in_shapes = options.implicit_tid_in_shapes ctx.implicit_limit = options.implicit_limit return ctx
def fuse_scope_branch(ir_set: irast.Set, parent: irast.ScopeTreeNode, branch: irast.ScopeTreeNode, *, ctx: context.ContextLevel) -> None: if parent.path_id is None: parent.attach_subtree(branch) else: if branch.path_id is None and len(branch.children) == 1: target_branch = next(iter(branch.children)) else: target_branch = branch if parent.path_id == target_branch.path_id: new_root = irast.new_scope_tree() for child in tuple(target_branch.children): new_root.attach_child(child) parent.attach_subtree(new_root) else: parent.attach_subtree(branch)
def __init__( self, *, schema: s_schema.Schema, path_scope: Optional[irast.ScopeTreeNode] = None, alias_result_view_name: Optional[s_name.QualName] = None, options: Optional[GlobalCompilerOptions] = None, ) -> None: if options is None: options = GlobalCompilerOptions() if path_scope is None: path_scope = irast.new_scope_tree() self.options = options self.schema = schema self.orig_schema = schema self.path_scope = path_scope self.schema_view_cache = {} self.query_parameters = {} self.query_globals = {} self.set_types = {} self.type_origins = {} self.inferred_types = {} self.inferred_volatility = {} self.view_shapes = collections.defaultdict(list) self.view_shapes_metadata = collections.defaultdict( irast.ViewShapeMetadata) self.schema_refs = set() self.schema_ref_exprs = {} if options.track_schema_ref_exprs else None self.created_schema_objects = set() self.ptr_ref_cache = PointerRefCache() self.type_ref_cache = {} self.dml_exprs = [] self.dml_stmts = set() self.pointer_derivation_map = collections.defaultdict(list) self.pointer_specified_info = {} self.singletons = [] self.scope_tree_nodes = weakref.WeakValueDictionary() self.materialized_sets = {} self.compiled_stmts = {} self.alias_result_view_name = alias_result_view_name
def __init__( self, prevlevel: Optional[ContextLevel], mode: ContextSwitchMode, *, env: Optional[Environment] = None, ) -> None: self.mode = mode if prevlevel is None: assert env is not None self.env = env self.derived_target_module = None self.aliases = compiler.AliasGenerator() self.anchors = {} self.modaliases = {} self.stmt_metadata = {} self.completion_work = [] self.pending_cardinality = {} self.pointer_derivation_map = collections.defaultdict(list) self.source_map = {} self.view_nodes = {} self.view_sets = {} self.aliased_views = collections.ChainMap() self.must_use_views = {} self.expr_view_cache = {} self.shape_type_cache = {} self.class_view_overrides = {} self.toplevel_stmt = None self.stmt = None self.path_id_namespace = frozenset() self.pending_stmt_own_path_id_namespace = frozenset() self.pending_stmt_full_path_id_namespace = frozenset() self.banned_paths = set() self.view_map = collections.ChainMap() self.path_scope = irast.new_scope_tree() self.path_scope_map = {} self.iterator_ctx = None self.iterator_path_ids = frozenset() self.scope_id_ctr = compiler.SimpleCounter() self.view_scls = None self.expr_exposed = False self.partial_path_prefix = None self.view_rptr = None self.toplevel_result_view_name = None self.implicit_id_in_shapes = False self.implicit_tid_in_shapes = False self.implicit_limit = 0 self.inhibit_implicit_limit = False self.special_computables_in_mutation_shape = frozenset() self.empty_result_type_hint = None self.defining_view = None self.compiling_update_shape = False self.in_conditional = None self.in_temp_scope = False self.tentative_work = [] self.disable_shadowing = set() self.path_log = None else: self.env = prevlevel.env self.derived_target_module = prevlevel.derived_target_module self.aliases = prevlevel.aliases self.stmt_metadata = prevlevel.stmt_metadata self.completion_work = prevlevel.completion_work self.pending_cardinality = prevlevel.pending_cardinality self.pointer_derivation_map = prevlevel.pointer_derivation_map self.source_map = prevlevel.source_map self.view_nodes = prevlevel.view_nodes self.view_sets = prevlevel.view_sets self.must_use_views = prevlevel.must_use_views self.expr_view_cache = prevlevel.expr_view_cache self.shape_type_cache = prevlevel.shape_type_cache self.iterator_ctx = prevlevel.iterator_ctx self.iterator_path_ids = prevlevel.iterator_path_ids self.path_id_namespace = prevlevel.path_id_namespace self.pending_stmt_own_path_id_namespace = \ prevlevel.pending_stmt_own_path_id_namespace self.pending_stmt_full_path_id_namespace = \ prevlevel.pending_stmt_full_path_id_namespace self.banned_paths = prevlevel.banned_paths self.view_map = prevlevel.view_map if prevlevel.path_scope is None: prevlevel.path_scope = self.env.path_scope self.path_scope = prevlevel.path_scope self.path_scope_map = prevlevel.path_scope_map self.scope_id_ctr = prevlevel.scope_id_ctr self.view_scls = prevlevel.view_scls self.expr_exposed = prevlevel.expr_exposed self.partial_path_prefix = prevlevel.partial_path_prefix self.toplevel_stmt = prevlevel.toplevel_stmt self.implicit_id_in_shapes = prevlevel.implicit_id_in_shapes self.implicit_tid_in_shapes = prevlevel.implicit_tid_in_shapes self.implicit_limit = prevlevel.implicit_limit self.inhibit_implicit_limit = prevlevel.inhibit_implicit_limit self.special_computables_in_mutation_shape = \ prevlevel.special_computables_in_mutation_shape self.empty_result_type_hint = prevlevel.empty_result_type_hint self.defining_view = prevlevel.defining_view self.compiling_update_shape = prevlevel.compiling_update_shape self.in_conditional = prevlevel.in_conditional self.in_temp_scope = prevlevel.in_temp_scope self.tentative_work = prevlevel.tentative_work self.disable_shadowing = prevlevel.disable_shadowing self.path_log = prevlevel.path_log if mode == ContextSwitchMode.SUBQUERY: self.anchors = prevlevel.anchors.copy() self.modaliases = prevlevel.modaliases.copy() self.aliased_views = prevlevel.aliased_views.new_child() self.class_view_overrides = \ prevlevel.class_view_overrides.copy() self.pending_stmt_own_path_id_namespace = frozenset() self.pending_stmt_full_path_id_namespace = frozenset() self.banned_paths = prevlevel.banned_paths.copy() self.view_rptr = None self.view_scls = None self.stmt = None self.view_rptr = None self.toplevel_result_view_name = None elif mode == ContextSwitchMode.DETACHED: self.anchors = prevlevel.anchors.copy() self.modaliases = prevlevel.modaliases.copy() self.aliased_views = collections.ChainMap() self.class_view_overrides = {} self.expr_exposed = prevlevel.expr_exposed self.view_nodes = {} self.view_sets = {} self.path_id_namespace = frozenset({self.aliases.get('ns')}) self.pending_stmt_own_path_id_namespace = frozenset() self.pending_stmt_full_path_id_namespace = frozenset() self.banned_paths = set() self.iterator_ctx = None self.iterator_path_ids = frozenset() self.view_rptr = None self.view_scls = None self.stmt = prevlevel.stmt self.partial_path_prefix = None self.view_rptr = None self.toplevel_result_view_name = None self.disable_shadowing = prevlevel.disable_shadowing.copy() else: self.anchors = prevlevel.anchors self.modaliases = prevlevel.modaliases self.aliased_views = prevlevel.aliased_views self.class_view_overrides = prevlevel.class_view_overrides self.stmt = prevlevel.stmt self.view_rptr = prevlevel.view_rptr self.toplevel_result_view_name = \ prevlevel.toplevel_result_view_name if mode in {ContextSwitchMode.NEWFENCE_TEMP, ContextSwitchMode.NEWSCOPE_TEMP}: # Make a copy of the entire tree and set path_scope to # be the copy of the current node. Stash the root in # an attribute to keep it from being freed, since # scope tree parent pointers are weak pointers. self._stash, self.path_scope = self.path_scope.copy_all() self.in_temp_scope = True self.tentative_work = list(prevlevel.tentative_work) if mode in {ContextSwitchMode.NEWFENCE, ContextSwitchMode.NEWFENCE_TEMP}: self.path_scope = self.path_scope.attach_fence() if mode in {ContextSwitchMode.NEWSCOPE, ContextSwitchMode.NEWSCOPE_TEMP}: self.path_scope = self.path_scope.attach_branch()
def init_context( *, schema: s_schema.Schema, func_params: Optional[s_func.ParameterLikeList]=None, parent_object_type: Optional[s_obj.ObjectMeta]=None, modaliases: Optional[Mapping[Optional[str], str]]=None, anchors: Optional[ Mapping[ Union[str, qlast.SpecialAnchorT], Union[s_obj.Object, irast.Base], ], ]=None, singletons: Optional[Iterable[s_types.Type]]=None, security_context: Optional[str]=None, derived_target_module: Optional[str]=None, result_view_name: Optional[s_name.SchemaName]=None, schema_view_mode: bool=False, disable_constant_folding: bool=False, allow_generic_type_output: bool=False, implicit_limit: int=0, implicit_id_in_shapes: bool=False, implicit_tid_in_shapes: bool=False, json_parameters: bool=False, session_mode: bool=False) -> \ context.ContextLevel: if not schema.get_global(s_mod.Module, '__derived__', None): schema, _ = s_mod.Module.create_in_schema(schema, name='__derived__') env = context.Environment( schema=schema, path_scope=irast.new_scope_tree(), constant_folding=not disable_constant_folding, func_params=func_params, parent_object_type=parent_object_type, schema_view_mode=schema_view_mode, json_parameters=json_parameters, session_mode=session_mode, allow_generic_type_output=allow_generic_type_output) ctx = context.ContextLevel(None, context.ContextSwitchMode.NEW, env=env) _ = context.CompilerContext(initial=ctx) if singletons: # The caller wants us to treat these type references # as singletons for the purposes of the overall expression # cardinality inference, so we set up the scope tree in # the necessary fashion. for singleton in singletons: path_id = pathctx.get_path_id(singleton, ctx=ctx) ctx.env.path_scope.attach_path(path_id) ctx.path_scope = ctx.env.path_scope.attach_fence() if modaliases: ctx.modaliases.update(modaliases) if anchors: with ctx.newscope(fenced=True) as subctx: populate_anchors(anchors, ctx=subctx) ctx.derived_target_module = derived_target_module ctx.toplevel_result_view_name = result_view_name ctx.implicit_id_in_shapes = implicit_id_in_shapes ctx.implicit_tid_in_shapes = implicit_tid_in_shapes ctx.implicit_limit = implicit_limit return ctx
def compile_ir_to_sql_tree( ir_expr: irast.Base, *, output_format: Optional[OutputFormat] = None, ignore_shapes: bool = False, explicit_top_cast: Optional[irast.TypeRef] = None, singleton_mode: bool = False, use_named_params: bool = False, expected_cardinality_one: bool = False, external_rvars: Optional[Mapping[Tuple[irast.PathId, str], pgast.PathRangeVar]] = None, backend_runtime_params: Optional[pgparams.BackendRuntimeParams] = None, ) -> pgast.Base: try: # Transform to sql tree query_params = [] query_globals = [] type_rewrites = {} singletons = [] if isinstance(ir_expr, irast.Statement): scope_tree = ir_expr.scope_tree query_params = list(ir_expr.params) query_globals = list(ir_expr.globals) type_rewrites = ir_expr.type_rewrites singletons = ir_expr.singletons ir_expr = ir_expr.expr elif isinstance(ir_expr, irast.ConfigCommand): assert ir_expr.scope_tree scope_tree = ir_expr.scope_tree else: scope_tree = irast.new_scope_tree() scope_tree_nodes = { node.unique_id: node for node in scope_tree.descendants if node.unique_id is not None } if backend_runtime_params is None: backend_runtime_params = pgparams.get_default_runtime_params() env = context.Environment( output_format=output_format, expected_cardinality_one=expected_cardinality_one, use_named_params=use_named_params, query_params=list(tuple(query_params) + tuple(query_globals)), type_rewrites=type_rewrites, ignore_object_shapes=ignore_shapes, explicit_top_cast=explicit_top_cast, singleton_mode=singleton_mode, scope_tree_nodes=scope_tree_nodes, external_rvars=external_rvars, backend_runtime_params=backend_runtime_params, ) ctx = context.CompilerContextLevel( None, context.ContextSwitchMode.TRANSPARENT, env=env, scope_tree=scope_tree, ) ctx.rel = pgast.SelectStmt() _ = context.CompilerContext(initial=ctx) ctx.singleton_mode = singleton_mode ctx.expr_exposed = True for sing in singletons: ctx.path_scope[sing] = ctx.rel clauses.populate_argmap(query_params, query_globals, ctx=ctx) qtree = dispatch.compile(ir_expr, ctx=ctx) if isinstance(ir_expr, irast.Set) and not singleton_mode: assert isinstance(qtree, pgast.Query) clauses.fini_toplevel(qtree, ctx) except errors.EdgeDBError: # Don't wrap propertly typed EdgeDB errors into # InternalServerError; raise them as is. raise except Exception as e: # pragma: no cover try: args = [e.args[0]] except (AttributeError, IndexError): args = [] raise errors.InternalServerError(*args) from e return qtree