We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Creating deep nested type gives error `could not serialize result in worker subprocess`
<!-- Please search existing issues to avoid creating duplicates. -->
- EdgeDB Version:
EdgeDB CLI 2.2.0+35980b5
EdgeDB Instance    "version": "2.6+db69671",
- OS Version:
MacOS 12.6 (21G115)

The schema has some types connected by links.
For each link to type `Target` the default is a freshly created as `(insert Target)`.
Most likely, the system can only cope with very short chains of such inserts or the total number of the inserts is too high.

Steps to Reproduce:

1. `edgedb migration create --non-interactive` (takes 2-3 minutes) 
2. `edgedb migrate` (takes a bit more than 2 minutes)
3. echo 'insert `varycon.Henkel.Adhesive Experience`::`ARMasterConfig` { id := <uuid>"dc29dd8b-6a44-47de-9048-a2d58629a193" };' | edgedb

Result:

edgedb error: InternalServerError: could not serialize result in worker subprocess
  Hint: This is most likely a bug in EdgeDB. Please consider opening an issue ticket at https://github.com/edgedb/edgedb/issues/new?template=bug_report.md
  Server traceback:
      Can't pickle local object 'process_insert_body.<locals>.dynamic_get_path':

      Traceback (most recent call last):
        File "/Users/doc/Library/Application Support/edgedb/portable/2.6/lib/python3.10/site-packages/edb/server/compiler_pool/worker_proc.py", line 64, in worker
          pickled = pickle.dumps(data, -1)
      AttributeError: Can't pickle local object 'process_insert_body.<locals>.dynamic_get_path'

<!-- If the issue is about a query error, please also provide your schema -->
Schema:

[default.esdl.zip](https://github.com/edgedb/edgedb/files/10021869/default.esdl.zip)


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `edb/pgsql/compiler/__init__.py`
Content:
```
1 #
2 # This source file is part of the EdgeDB open source project.
3 #
4 # Copyright 2008-present MagicStack Inc. and the EdgeDB authors.
5 #
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
9 #
10 #     http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
17 #
18 
19 
20 from __future__ import annotations
21 
22 from typing import *
23 
24 from edb import errors
25 
26 from edb.common import debug
27 from edb.common import exceptions as edgedb_error
28 
29 from edb.ir import ast as irast
30 
31 from edb.pgsql import ast as pgast
32 from edb.pgsql import codegen as pgcodegen
33 from edb.pgsql import debug as pgdebug
34 from edb.pgsql import params as pgparams
35 
36 from . import config as _config_compiler  # NOQA
37 from . import expr as _expr_compiler  # NOQA
38 from . import stmt as _stmt_compiler  # NOQA
39 
40 from . import clauses
41 from . import context
42 from . import dispatch
43 from . import dml
44 
45 from .context import OutputFormat as OutputFormat # NOQA
46 
47 
48 def compile_ir_to_sql_tree(
49     ir_expr: irast.Base,
50     *,
51     output_format: Optional[OutputFormat] = None,
52     ignore_shapes: bool = False,
53     explicit_top_cast: Optional[irast.TypeRef] = None,
54     singleton_mode: bool = False,
55     use_named_params: bool = False,
56     expected_cardinality_one: bool = False,
57     expand_inhviews: bool = False,
58     external_rvars: Optional[
59         Mapping[Tuple[irast.PathId, str], pgast.PathRangeVar]
60     ] = None,
61     external_rels: Optional[
62         Mapping[
63             irast.PathId,
64             Tuple[pgast.BaseRelation | pgast.CommonTableExpr, Tuple[str, ...]],
65         ]
66     ] = None,
67     backend_runtime_params: Optional[pgparams.BackendRuntimeParams]=None,
68 ) -> Tuple[pgast.Base, context.Environment]:
69     try:
70         # Transform to sql tree
71         query_params = []
72         query_globals = []
73         type_rewrites = {}
74         triggers: tuple[tuple[irast.Trigger, ...], ...] = ()
75 
76         singletons = []
77         if isinstance(ir_expr, irast.Statement):
78             scope_tree = ir_expr.scope_tree
79             query_params = list(ir_expr.params)
80             query_globals = list(ir_expr.globals)
81             type_rewrites = ir_expr.type_rewrites
82             singletons = ir_expr.singletons
83             triggers = ir_expr.triggers
84             ir_expr = ir_expr.expr
85         elif isinstance(ir_expr, irast.ConfigCommand):
86             assert ir_expr.scope_tree
87             scope_tree = ir_expr.scope_tree
88             if ir_expr.globals:
89                 query_globals = list(ir_expr.globals)
90         else:
91             scope_tree = irast.new_scope_tree()
92 
93         scope_tree_nodes = {
94             node.unique_id: node for node in scope_tree.descendants
95             if node.unique_id is not None
96         }
97 
98         if backend_runtime_params is None:
99             backend_runtime_params = pgparams.get_default_runtime_params()
100 
101         env = context.Environment(
102             output_format=output_format,
103             expected_cardinality_one=expected_cardinality_one,
104             use_named_params=use_named_params,
105             query_params=list(tuple(query_params) + tuple(query_globals)),
106             type_rewrites=type_rewrites,
107             ignore_object_shapes=ignore_shapes,
108             explicit_top_cast=explicit_top_cast,
109             expand_inhviews=expand_inhviews,
110             singleton_mode=singleton_mode,
111             scope_tree_nodes=scope_tree_nodes,
112             external_rvars=external_rvars,
113             backend_runtime_params=backend_runtime_params,
114         )
115 
116         ctx = context.CompilerContextLevel(
117             None,
118             context.ContextSwitchMode.TRANSPARENT,
119             env=env,
120             scope_tree=scope_tree,
121         )
122         ctx.rel = pgast.SelectStmt()
123 
124         _ = context.CompilerContext(initial=ctx)
125 
126         ctx.singleton_mode = singleton_mode
127         ctx.expr_exposed = True
128         for sing in singletons:
129             ctx.path_scope[sing] = ctx.rel
130         if external_rels:
131             ctx.external_rels = external_rels
132         clauses.populate_argmap(query_params, query_globals, ctx=ctx)
133 
134         qtree = dispatch.compile(ir_expr, ctx=ctx)
135         dml.compile_triggers(triggers, qtree, ctx=ctx)
136 
137         if isinstance(ir_expr, irast.Set) and not singleton_mode:
138             assert isinstance(qtree, pgast.Query)
139             clauses.fini_toplevel(qtree, ctx)
140 
141     except errors.EdgeDBError:
142         # Don't wrap propertly typed EdgeDB errors into
143         # InternalServerError; raise them as is.
144         raise
145 
146     except Exception as e:  # pragma: no cover
147         try:
148             args = [e.args[0]]
149         except (AttributeError, IndexError):
150             args = []
151         raise errors.InternalServerError(*args) from e
152 
153     return (qtree, env)
154 
155 
156 def compile_ir_to_tree_and_sql(
157     ir_expr: irast.Base, *,
158     output_format: Optional[OutputFormat]=None,
159     ignore_shapes: bool=False,
160     explicit_top_cast: Optional[irast.TypeRef]=None,
161     singleton_mode: bool=False,
162     use_named_params: bool=False,
163     expected_cardinality_one: bool=False,
164     expand_inhviews: bool = False,
165     pretty: bool=True,
166     backend_runtime_params: Optional[pgparams.BackendRuntimeParams]=None,
167 ) -> Tuple[pgast.Base, str, Dict[str, pgast.Param]]:
168 
169     qtree, _ = compile_ir_to_sql_tree(
170         ir_expr,
171         output_format=output_format,
172         ignore_shapes=ignore_shapes,
173         explicit_top_cast=explicit_top_cast,
174         singleton_mode=singleton_mode,
175         use_named_params=use_named_params,
176         expected_cardinality_one=expected_cardinality_one,
177         backend_runtime_params=backend_runtime_params,
178         expand_inhviews=expand_inhviews,
179     )
180 
181     if (  # pragma: no cover
182         debug.flags.edgeql_compile or debug.flags.edgeql_compile_sql_ast
183     ):
184         debug.header('SQL Tree')
185         debug.dump(
186             qtree, _ast_include_meta=debug.flags.edgeql_compile_sql_ast_meta)
187 
188     if isinstance(qtree, pgast.Query) and qtree.argnames:
189         argmap = qtree.argnames
190     else:
191         argmap = {}
192 
193     # Generate query text
194     sql_text = run_codegen(qtree, pretty=pretty)
195 
196     if (  # pragma: no cover
197         debug.flags.edgeql_compile or debug.flags.edgeql_compile_sql_text
198     ):
199         debug.header('SQL')
200         debug.dump_code(sql_text, lexer='sql')
201     if (  # pragma: no cover
202         debug.flags.edgeql_compile_sql_reordered_text
203     ):
204         debug.header('Reordered SQL')
205         debug_sql_text = run_codegen(qtree, pretty=True, reordered=True)
206         if isinstance(ir_expr, irast.Statement):
207             # Rewrite uuids back into something approximating
208             # readable object names.
209             debug_sql_text = pgdebug.rewrite_names_in_sql(
210                 debug_sql_text, ir_expr.schema)
211         debug.dump_code(debug_sql_text, lexer='sql')
212 
213     return qtree, sql_text, argmap
214 
215 
216 def compile_ir_to_sql(
217     ir_expr: irast.Base, *,
218     output_format: Optional[OutputFormat]=None,
219     ignore_shapes: bool=False,
220     explicit_top_cast: Optional[irast.TypeRef]=None,
221     singleton_mode: bool=False,
222     use_named_params: bool=False,
223     expected_cardinality_one: bool=False,
224     pretty: bool=True,
225     backend_runtime_params: Optional[pgparams.BackendRuntimeParams]=None,
226 ) -> Tuple[str, Dict[str, pgast.Param]]:
227     _, sql_text, argmap = compile_ir_to_tree_and_sql(
228         ir_expr,
229         output_format=output_format,
230         ignore_shapes=ignore_shapes,
231         explicit_top_cast=explicit_top_cast,
232         singleton_mode=singleton_mode,
233         use_named_params=use_named_params,
234         expected_cardinality_one=expected_cardinality_one,
235         backend_runtime_params=backend_runtime_params,
236         pretty=pretty,
237     )
238     return sql_text, argmap
239 
240 
241 def run_codegen(
242     qtree: pgast.Base,
243     *,
244     pretty: bool=True,
245     reordered: bool=False,
246 ) -> str:
247     codegen = pgcodegen.SQLSourceGenerator(pretty=pretty, reordered=reordered)
248     try:
249         codegen.visit(qtree)
250     except pgcodegen.SQLSourceGeneratorError as e:  # pragma: no cover
251         ctx = pgcodegen.SQLSourceGeneratorContext(
252             qtree, codegen.result)
253         edgedb_error.add_context(e, ctx)
254         raise
255     except Exception as e:  # pragma: no cover
256         ctx = pgcodegen.SQLSourceGeneratorContext(
257             qtree, codegen.result)
258         err = pgcodegen.SQLSourceGeneratorError(
259             'error while generating SQL source')
260         edgedb_error.add_context(err, ctx)
261         raise err from e
262 
263     return ''.join(codegen.result)
264 
265 
266 def new_external_rvar(
267     *,
268     rel_name: Tuple[str, ...],
269     path_id: irast.PathId,
270     outputs: Mapping[Tuple[irast.PathId, Tuple[str, ...]], str],
271 ) -> pgast.RelRangeVar:
272     """Construct a ``RangeVar`` instance given a relation name and a path id.
273 
274     Given an optionally-qualified relation name *rel_name* and a *path_id*,
275     return a ``RangeVar`` instance over the specified relation that is
276     then assumed to represent the *path_id* binding.
277 
278     This is useful in situations where it is necessary to "prime" the compiler
279     with a list of external relations that exist in a larger SQL expression
280     that _this_ expression is being embedded into.
281 
282     The *outputs* mapping optionally specifies a set of outputs in the
283     resulting range var as a ``(path_id, tuple-of-aspects): attribute name``
284     mapping.
285     """
286     rel = new_external_rel(rel_name=rel_name, path_id=path_id)
287     assert rel.name
288 
289     alias = pgast.Alias(aliasname=rel.name)
290 
291     if not path_id.is_ptr_path():
292         rvar = pgast.RelRangeVar(
293             relation=rel, typeref=path_id.target, alias=alias)
294     else:
295         rvar = pgast.RelRangeVar(
296             relation=rel, alias=alias)
297 
298     for (output_pid, output_aspects), colname in outputs.items():
299         var = pgast.ColumnRef(name=[colname])
300         for aspect in output_aspects:
301             rel.path_outputs[output_pid, aspect] = var
302 
303     return rvar
304 
305 
306 def new_external_rel(
307     *,
308     rel_name: Tuple[str, ...],
309     path_id: irast.PathId,
310 ) -> pgast.Relation:
311     if len(rel_name) == 1:
312         table_name = rel_name[0]
313         schema_name = None
314     elif len(rel_name) == 2:
315         schema_name, table_name = rel_name
316     else:
317         raise AssertionError(f'unexpected rvar name: {rel_name}')
318 
319     return pgast.Relation(
320         name=table_name,
321         schemaname=schema_name,
322         path_id=path_id,
323     )
324
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/edb/pgsql/compiler/__init__.py b/edb/pgsql/compiler/__init__.py
--- a/edb/pgsql/compiler/__init__.py
+++ b/edb/pgsql/compiler/__init__.py
@@ -247,6 +247,11 @@
     codegen = pgcodegen.SQLSourceGenerator(pretty=pretty, reordered=reordered)
     try:
         codegen.visit(qtree)
+    except RecursionError:
+        # Don't try to wrap and add context to a recursion error,
+        # since the context might easily be too deeply recursive to
+        # process further down the pipe.
+        raise
     except pgcodegen.SQLSourceGeneratorError as e:  # pragma: no cover
         ctx = pgcodegen.SQLSourceGeneratorContext(
             qtree, codegen.result)

{"golden_diff": "diff --git a/edb/pgsql/compiler/__init__.py b/edb/pgsql/compiler/__init__.py\n--- a/edb/pgsql/compiler/__init__.py\n+++ b/edb/pgsql/compiler/__init__.py\n@@ -247,6 +247,11 @@\n     codegen = pgcodegen.SQLSourceGenerator(pretty=pretty, reordered=reordered)\n     try:\n         codegen.visit(qtree)\n+    except RecursionError:\n+        # Don't try to wrap and add context to a recursion error,\n+        # since the context might easily be too deeply recursive to\n+        # process further down the pipe.\n+        raise\n     except pgcodegen.SQLSourceGeneratorError as e:  # pragma: no cover\n         ctx = pgcodegen.SQLSourceGeneratorContext(\n             qtree, codegen.result)\n", "issue": "Creating deep nested type gives error `could not serialize result in worker subprocess`\n<!-- Please search existing issues to avoid creating duplicates. -->\r\n- EdgeDB Version:\r\nEdgeDB CLI 2.2.0+35980b5\r\nEdgeDB Instance    \"version\": \"2.6+db69671\",\r\n- OS Version:\r\nMacOS 12.6 (21G115)\r\n\r\nThe schema has some types connected by links.\r\nFor each link to type `Target` the default is a freshly created as `(insert Target)`.\r\nMost likely, the system can only cope with very short chains of such inserts or the total number of the inserts is too high.\r\n\r\nSteps to Reproduce:\r\n\r\n1. `edgedb migration create --non-interactive` (takes 2-3 minutes) \r\n2. `edgedb migrate` (takes a bit more than 2 minutes)\r\n3. echo 'insert `varycon.Henkel.Adhesive Experience`::`ARMasterConfig` { id := <uuid>\"dc29dd8b-6a44-47de-9048-a2d58629a193\" };' | edgedb\r\n\r\nResult:\r\n\r\nedgedb error: InternalServerError: could not serialize result in worker subprocess\r\n  Hint: This is most likely a bug in EdgeDB. Please consider opening an issue ticket at https://github.com/edgedb/edgedb/issues/new?template=bug_report.md\r\n  Server traceback:\r\n      Can't pickle local object 'process_insert_body.<locals>.dynamic_get_path':\r\n\r\n      Traceback (most recent call last):\r\n        File \"/Users/doc/Library/Application Support/edgedb/portable/2.6/lib/python3.10/site-packages/edb/server/compiler_pool/worker_proc.py\", line 64, in worker\r\n          pickled = pickle.dumps(data, -1)\r\n      AttributeError: Can't pickle local object 'process_insert_body.<locals>.dynamic_get_path'\r\n\r\n<!-- If the issue is about a query error, please also provide your schema -->\r\nSchema:\r\n\r\n[default.esdl.zip](https://github.com/edgedb/edgedb/files/10021869/default.esdl.zip)\r\n\n", "before_files": [{"content": "#\n# This source file is part of the EdgeDB open source project.\n#\n# Copyright 2008-present MagicStack Inc. and the EdgeDB authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n\nfrom __future__ import annotations\n\nfrom typing import *\n\nfrom edb import errors\n\nfrom edb.common import debug\nfrom edb.common import exceptions as edgedb_error\n\nfrom edb.ir import ast as irast\n\nfrom edb.pgsql import ast as pgast\nfrom edb.pgsql import codegen as pgcodegen\nfrom edb.pgsql import debug as pgdebug\nfrom edb.pgsql import params as pgparams\n\nfrom . import config as _config_compiler  # NOQA\nfrom . import expr as _expr_compiler  # NOQA\nfrom . import stmt as _stmt_compiler  # NOQA\n\nfrom . import clauses\nfrom . import context\nfrom . import dispatch\nfrom . import dml\n\nfrom .context import OutputFormat as OutputFormat # NOQA\n\n\ndef compile_ir_to_sql_tree(\n    ir_expr: irast.Base,\n    *,\n    output_format: Optional[OutputFormat] = None,\n    ignore_shapes: bool = False,\n    explicit_top_cast: Optional[irast.TypeRef] = None,\n    singleton_mode: bool = False,\n    use_named_params: bool = False,\n    expected_cardinality_one: bool = False,\n    expand_inhviews: bool = False,\n    external_rvars: Optional[\n        Mapping[Tuple[irast.PathId, str], pgast.PathRangeVar]\n    ] = None,\n    external_rels: Optional[\n        Mapping[\n            irast.PathId,\n            Tuple[pgast.BaseRelation | pgast.CommonTableExpr, Tuple[str, ...]],\n        ]\n    ] = None,\n    backend_runtime_params: Optional[pgparams.BackendRuntimeParams]=None,\n) -> Tuple[pgast.Base, context.Environment]:\n    try:\n        # Transform to sql tree\n        query_params = []\n        query_globals = []\n        type_rewrites = {}\n        triggers: tuple[tuple[irast.Trigger, ...], ...] = ()\n\n        singletons = []\n        if isinstance(ir_expr, irast.Statement):\n            scope_tree = ir_expr.scope_tree\n            query_params = list(ir_expr.params)\n            query_globals = list(ir_expr.globals)\n            type_rewrites = ir_expr.type_rewrites\n            singletons = ir_expr.singletons\n            triggers = ir_expr.triggers\n            ir_expr = ir_expr.expr\n        elif isinstance(ir_expr, irast.ConfigCommand):\n            assert ir_expr.scope_tree\n            scope_tree = ir_expr.scope_tree\n            if ir_expr.globals:\n                query_globals = list(ir_expr.globals)\n        else:\n            scope_tree = irast.new_scope_tree()\n\n        scope_tree_nodes = {\n            node.unique_id: node for node in scope_tree.descendants\n            if node.unique_id is not None\n        }\n\n        if backend_runtime_params is None:\n            backend_runtime_params = pgparams.get_default_runtime_params()\n\n        env = context.Environment(\n            output_format=output_format,\n            expected_cardinality_one=expected_cardinality_one,\n            use_named_params=use_named_params,\n            query_params=list(tuple(query_params) + tuple(query_globals)),\n            type_rewrites=type_rewrites,\n            ignore_object_shapes=ignore_shapes,\n            explicit_top_cast=explicit_top_cast,\n            expand_inhviews=expand_inhviews,\n            singleton_mode=singleton_mode,\n            scope_tree_nodes=scope_tree_nodes,\n            external_rvars=external_rvars,\n            backend_runtime_params=backend_runtime_params,\n        )\n\n        ctx = context.CompilerContextLevel(\n            None,\n            context.ContextSwitchMode.TRANSPARENT,\n            env=env,\n            scope_tree=scope_tree,\n        )\n        ctx.rel = pgast.SelectStmt()\n\n        _ = context.CompilerContext(initial=ctx)\n\n        ctx.singleton_mode = singleton_mode\n        ctx.expr_exposed = True\n        for sing in singletons:\n            ctx.path_scope[sing] = ctx.rel\n        if external_rels:\n            ctx.external_rels = external_rels\n        clauses.populate_argmap(query_params, query_globals, ctx=ctx)\n\n        qtree = dispatch.compile(ir_expr, ctx=ctx)\n        dml.compile_triggers(triggers, qtree, ctx=ctx)\n\n        if isinstance(ir_expr, irast.Set) and not singleton_mode:\n            assert isinstance(qtree, pgast.Query)\n            clauses.fini_toplevel(qtree, ctx)\n\n    except errors.EdgeDBError:\n        # Don't wrap propertly typed EdgeDB errors into\n        # InternalServerError; raise them as is.\n        raise\n\n    except Exception as e:  # pragma: no cover\n        try:\n            args = [e.args[0]]\n        except (AttributeError, IndexError):\n            args = []\n        raise errors.InternalServerError(*args) from e\n\n    return (qtree, env)\n\n\ndef compile_ir_to_tree_and_sql(\n    ir_expr: irast.Base, *,\n    output_format: Optional[OutputFormat]=None,\n    ignore_shapes: bool=False,\n    explicit_top_cast: Optional[irast.TypeRef]=None,\n    singleton_mode: bool=False,\n    use_named_params: bool=False,\n    expected_cardinality_one: bool=False,\n    expand_inhviews: bool = False,\n    pretty: bool=True,\n    backend_runtime_params: Optional[pgparams.BackendRuntimeParams]=None,\n) -> Tuple[pgast.Base, str, Dict[str, pgast.Param]]:\n\n    qtree, _ = compile_ir_to_sql_tree(\n        ir_expr,\n        output_format=output_format,\n        ignore_shapes=ignore_shapes,\n        explicit_top_cast=explicit_top_cast,\n        singleton_mode=singleton_mode,\n        use_named_params=use_named_params,\n        expected_cardinality_one=expected_cardinality_one,\n        backend_runtime_params=backend_runtime_params,\n        expand_inhviews=expand_inhviews,\n    )\n\n    if (  # pragma: no cover\n        debug.flags.edgeql_compile or debug.flags.edgeql_compile_sql_ast\n    ):\n        debug.header('SQL Tree')\n        debug.dump(\n            qtree, _ast_include_meta=debug.flags.edgeql_compile_sql_ast_meta)\n\n    if isinstance(qtree, pgast.Query) and qtree.argnames:\n        argmap = qtree.argnames\n    else:\n        argmap = {}\n\n    # Generate query text\n    sql_text = run_codegen(qtree, pretty=pretty)\n\n    if (  # pragma: no cover\n        debug.flags.edgeql_compile or debug.flags.edgeql_compile_sql_text\n    ):\n        debug.header('SQL')\n        debug.dump_code(sql_text, lexer='sql')\n    if (  # pragma: no cover\n        debug.flags.edgeql_compile_sql_reordered_text\n    ):\n        debug.header('Reordered SQL')\n        debug_sql_text = run_codegen(qtree, pretty=True, reordered=True)\n        if isinstance(ir_expr, irast.Statement):\n            # Rewrite uuids back into something approximating\n            # readable object names.\n            debug_sql_text = pgdebug.rewrite_names_in_sql(\n                debug_sql_text, ir_expr.schema)\n        debug.dump_code(debug_sql_text, lexer='sql')\n\n    return qtree, sql_text, argmap\n\n\ndef compile_ir_to_sql(\n    ir_expr: irast.Base, *,\n    output_format: Optional[OutputFormat]=None,\n    ignore_shapes: bool=False,\n    explicit_top_cast: Optional[irast.TypeRef]=None,\n    singleton_mode: bool=False,\n    use_named_params: bool=False,\n    expected_cardinality_one: bool=False,\n    pretty: bool=True,\n    backend_runtime_params: Optional[pgparams.BackendRuntimeParams]=None,\n) -> Tuple[str, Dict[str, pgast.Param]]:\n    _, sql_text, argmap = compile_ir_to_tree_and_sql(\n        ir_expr,\n        output_format=output_format,\n        ignore_shapes=ignore_shapes,\n        explicit_top_cast=explicit_top_cast,\n        singleton_mode=singleton_mode,\n        use_named_params=use_named_params,\n        expected_cardinality_one=expected_cardinality_one,\n        backend_runtime_params=backend_runtime_params,\n        pretty=pretty,\n    )\n    return sql_text, argmap\n\n\ndef run_codegen(\n    qtree: pgast.Base,\n    *,\n    pretty: bool=True,\n    reordered: bool=False,\n) -> str:\n    codegen = pgcodegen.SQLSourceGenerator(pretty=pretty, reordered=reordered)\n    try:\n        codegen.visit(qtree)\n    except pgcodegen.SQLSourceGeneratorError as e:  # pragma: no cover\n        ctx = pgcodegen.SQLSourceGeneratorContext(\n            qtree, codegen.result)\n        edgedb_error.add_context(e, ctx)\n        raise\n    except Exception as e:  # pragma: no cover\n        ctx = pgcodegen.SQLSourceGeneratorContext(\n            qtree, codegen.result)\n        err = pgcodegen.SQLSourceGeneratorError(\n            'error while generating SQL source')\n        edgedb_error.add_context(err, ctx)\n        raise err from e\n\n    return ''.join(codegen.result)\n\n\ndef new_external_rvar(\n    *,\n    rel_name: Tuple[str, ...],\n    path_id: irast.PathId,\n    outputs: Mapping[Tuple[irast.PathId, Tuple[str, ...]], str],\n) -> pgast.RelRangeVar:\n    \"\"\"Construct a ``RangeVar`` instance given a relation name and a path id.\n\n    Given an optionally-qualified relation name *rel_name* and a *path_id*,\n    return a ``RangeVar`` instance over the specified relation that is\n    then assumed to represent the *path_id* binding.\n\n    This is useful in situations where it is necessary to \"prime\" the compiler\n    with a list of external relations that exist in a larger SQL expression\n    that _this_ expression is being embedded into.\n\n    The *outputs* mapping optionally specifies a set of outputs in the\n    resulting range var as a ``(path_id, tuple-of-aspects): attribute name``\n    mapping.\n    \"\"\"\n    rel = new_external_rel(rel_name=rel_name, path_id=path_id)\n    assert rel.name\n\n    alias = pgast.Alias(aliasname=rel.name)\n\n    if not path_id.is_ptr_path():\n        rvar = pgast.RelRangeVar(\n            relation=rel, typeref=path_id.target, alias=alias)\n    else:\n        rvar = pgast.RelRangeVar(\n            relation=rel, alias=alias)\n\n    for (output_pid, output_aspects), colname in outputs.items():\n        var = pgast.ColumnRef(name=[colname])\n        for aspect in output_aspects:\n            rel.path_outputs[output_pid, aspect] = var\n\n    return rvar\n\n\ndef new_external_rel(\n    *,\n    rel_name: Tuple[str, ...],\n    path_id: irast.PathId,\n) -> pgast.Relation:\n    if len(rel_name) == 1:\n        table_name = rel_name[0]\n        schema_name = None\n    elif len(rel_name) == 2:\n        schema_name, table_name = rel_name\n    else:\n        raise AssertionError(f'unexpected rvar name: {rel_name}')\n\n    return pgast.Relation(\n        name=table_name,\n        schemaname=schema_name,\n        path_id=path_id,\n    )\n", "path": "edb/pgsql/compiler/__init__.py"}], "after_files": [{"content": "#\n# This source file is part of the EdgeDB open source project.\n#\n# Copyright 2008-present MagicStack Inc. and the EdgeDB authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n\nfrom __future__ import annotations\n\nfrom typing import *\n\nfrom edb import errors\n\nfrom edb.common import debug\nfrom edb.common import exceptions as edgedb_error\n\nfrom edb.ir import ast as irast\n\nfrom edb.pgsql import ast as pgast\nfrom edb.pgsql import codegen as pgcodegen\nfrom edb.pgsql import debug as pgdebug\nfrom edb.pgsql import params as pgparams\n\nfrom . import config as _config_compiler  # NOQA\nfrom . import expr as _expr_compiler  # NOQA\nfrom . import stmt as _stmt_compiler  # NOQA\n\nfrom . import clauses\nfrom . import context\nfrom . import dispatch\nfrom . import dml\n\nfrom .context import OutputFormat as OutputFormat # NOQA\n\n\ndef compile_ir_to_sql_tree(\n    ir_expr: irast.Base,\n    *,\n    output_format: Optional[OutputFormat] = None,\n    ignore_shapes: bool = False,\n    explicit_top_cast: Optional[irast.TypeRef] = None,\n    singleton_mode: bool = False,\n    use_named_params: bool = False,\n    expected_cardinality_one: bool = False,\n    expand_inhviews: bool = False,\n    external_rvars: Optional[\n        Mapping[Tuple[irast.PathId, str], pgast.PathRangeVar]\n    ] = None,\n    external_rels: Optional[\n        Mapping[\n            irast.PathId,\n            Tuple[pgast.BaseRelation | pgast.CommonTableExpr, Tuple[str, ...]],\n        ]\n    ] = None,\n    backend_runtime_params: Optional[pgparams.BackendRuntimeParams]=None,\n) -> Tuple[pgast.Base, context.Environment]:\n    try:\n        # Transform to sql tree\n        query_params = []\n        query_globals = []\n        type_rewrites = {}\n        triggers: tuple[tuple[irast.Trigger, ...], ...] = ()\n\n        singletons = []\n        if isinstance(ir_expr, irast.Statement):\n            scope_tree = ir_expr.scope_tree\n            query_params = list(ir_expr.params)\n            query_globals = list(ir_expr.globals)\n            type_rewrites = ir_expr.type_rewrites\n            singletons = ir_expr.singletons\n            triggers = ir_expr.triggers\n            ir_expr = ir_expr.expr\n        elif isinstance(ir_expr, irast.ConfigCommand):\n            assert ir_expr.scope_tree\n            scope_tree = ir_expr.scope_tree\n            if ir_expr.globals:\n                query_globals = list(ir_expr.globals)\n        else:\n            scope_tree = irast.new_scope_tree()\n\n        scope_tree_nodes = {\n            node.unique_id: node for node in scope_tree.descendants\n            if node.unique_id is not None\n        }\n\n        if backend_runtime_params is None:\n            backend_runtime_params = pgparams.get_default_runtime_params()\n\n        env = context.Environment(\n            output_format=output_format,\n            expected_cardinality_one=expected_cardinality_one,\n            use_named_params=use_named_params,\n            query_params=list(tuple(query_params) + tuple(query_globals)),\n            type_rewrites=type_rewrites,\n            ignore_object_shapes=ignore_shapes,\n            explicit_top_cast=explicit_top_cast,\n            expand_inhviews=expand_inhviews,\n            singleton_mode=singleton_mode,\n            scope_tree_nodes=scope_tree_nodes,\n            external_rvars=external_rvars,\n            backend_runtime_params=backend_runtime_params,\n        )\n\n        ctx = context.CompilerContextLevel(\n            None,\n            context.ContextSwitchMode.TRANSPARENT,\n            env=env,\n            scope_tree=scope_tree,\n        )\n        ctx.rel = pgast.SelectStmt()\n\n        _ = context.CompilerContext(initial=ctx)\n\n        ctx.singleton_mode = singleton_mode\n        ctx.expr_exposed = True\n        for sing in singletons:\n            ctx.path_scope[sing] = ctx.rel\n        if external_rels:\n            ctx.external_rels = external_rels\n        clauses.populate_argmap(query_params, query_globals, ctx=ctx)\n\n        qtree = dispatch.compile(ir_expr, ctx=ctx)\n        dml.compile_triggers(triggers, qtree, ctx=ctx)\n\n        if isinstance(ir_expr, irast.Set) and not singleton_mode:\n            assert isinstance(qtree, pgast.Query)\n            clauses.fini_toplevel(qtree, ctx)\n\n    except errors.EdgeDBError:\n        # Don't wrap propertly typed EdgeDB errors into\n        # InternalServerError; raise them as is.\n        raise\n\n    except Exception as e:  # pragma: no cover\n        try:\n            args = [e.args[0]]\n        except (AttributeError, IndexError):\n            args = []\n        raise errors.InternalServerError(*args) from e\n\n    return (qtree, env)\n\n\ndef compile_ir_to_tree_and_sql(\n    ir_expr: irast.Base, *,\n    output_format: Optional[OutputFormat]=None,\n    ignore_shapes: bool=False,\n    explicit_top_cast: Optional[irast.TypeRef]=None,\n    singleton_mode: bool=False,\n    use_named_params: bool=False,\n    expected_cardinality_one: bool=False,\n    expand_inhviews: bool = False,\n    pretty: bool=True,\n    backend_runtime_params: Optional[pgparams.BackendRuntimeParams]=None,\n) -> Tuple[pgast.Base, str, Dict[str, pgast.Param]]:\n\n    qtree, _ = compile_ir_to_sql_tree(\n        ir_expr,\n        output_format=output_format,\n        ignore_shapes=ignore_shapes,\n        explicit_top_cast=explicit_top_cast,\n        singleton_mode=singleton_mode,\n        use_named_params=use_named_params,\n        expected_cardinality_one=expected_cardinality_one,\n        backend_runtime_params=backend_runtime_params,\n        expand_inhviews=expand_inhviews,\n    )\n\n    if (  # pragma: no cover\n        debug.flags.edgeql_compile or debug.flags.edgeql_compile_sql_ast\n    ):\n        debug.header('SQL Tree')\n        debug.dump(\n            qtree, _ast_include_meta=debug.flags.edgeql_compile_sql_ast_meta)\n\n    if isinstance(qtree, pgast.Query) and qtree.argnames:\n        argmap = qtree.argnames\n    else:\n        argmap = {}\n\n    # Generate query text\n    sql_text = run_codegen(qtree, pretty=pretty)\n\n    if (  # pragma: no cover\n        debug.flags.edgeql_compile or debug.flags.edgeql_compile_sql_text\n    ):\n        debug.header('SQL')\n        debug.dump_code(sql_text, lexer='sql')\n    if (  # pragma: no cover\n        debug.flags.edgeql_compile_sql_reordered_text\n    ):\n        debug.header('Reordered SQL')\n        debug_sql_text = run_codegen(qtree, pretty=True, reordered=True)\n        if isinstance(ir_expr, irast.Statement):\n            # Rewrite uuids back into something approximating\n            # readable object names.\n            debug_sql_text = pgdebug.rewrite_names_in_sql(\n                debug_sql_text, ir_expr.schema)\n        debug.dump_code(debug_sql_text, lexer='sql')\n\n    return qtree, sql_text, argmap\n\n\ndef compile_ir_to_sql(\n    ir_expr: irast.Base, *,\n    output_format: Optional[OutputFormat]=None,\n    ignore_shapes: bool=False,\n    explicit_top_cast: Optional[irast.TypeRef]=None,\n    singleton_mode: bool=False,\n    use_named_params: bool=False,\n    expected_cardinality_one: bool=False,\n    pretty: bool=True,\n    backend_runtime_params: Optional[pgparams.BackendRuntimeParams]=None,\n) -> Tuple[str, Dict[str, pgast.Param]]:\n    _, sql_text, argmap = compile_ir_to_tree_and_sql(\n        ir_expr,\n        output_format=output_format,\n        ignore_shapes=ignore_shapes,\n        explicit_top_cast=explicit_top_cast,\n        singleton_mode=singleton_mode,\n        use_named_params=use_named_params,\n        expected_cardinality_one=expected_cardinality_one,\n        backend_runtime_params=backend_runtime_params,\n        pretty=pretty,\n    )\n    return sql_text, argmap\n\n\ndef run_codegen(\n    qtree: pgast.Base,\n    *,\n    pretty: bool=True,\n    reordered: bool=False,\n) -> str:\n    codegen = pgcodegen.SQLSourceGenerator(pretty=pretty, reordered=reordered)\n    try:\n        codegen.visit(qtree)\n    except RecursionError:\n        # Don't try to wrap and add context to a recursion error,\n        # since the context might easily be too deeply recursive to\n        # process further down the pipe.\n        raise\n    except pgcodegen.SQLSourceGeneratorError as e:  # pragma: no cover\n        ctx = pgcodegen.SQLSourceGeneratorContext(\n            qtree, codegen.result)\n        edgedb_error.add_context(e, ctx)\n        raise\n    except Exception as e:  # pragma: no cover\n        ctx = pgcodegen.SQLSourceGeneratorContext(\n            qtree, codegen.result)\n        err = pgcodegen.SQLSourceGeneratorError(\n            'error while generating SQL source')\n        edgedb_error.add_context(err, ctx)\n        raise err from e\n\n    return ''.join(codegen.result)\n\n\ndef new_external_rvar(\n    *,\n    rel_name: Tuple[str, ...],\n    path_id: irast.PathId,\n    outputs: Mapping[Tuple[irast.PathId, Tuple[str, ...]], str],\n) -> pgast.RelRangeVar:\n    \"\"\"Construct a ``RangeVar`` instance given a relation name and a path id.\n\n    Given an optionally-qualified relation name *rel_name* and a *path_id*,\n    return a ``RangeVar`` instance over the specified relation that is\n    then assumed to represent the *path_id* binding.\n\n    This is useful in situations where it is necessary to \"prime\" the compiler\n    with a list of external relations that exist in a larger SQL expression\n    that _this_ expression is being embedded into.\n\n    The *outputs* mapping optionally specifies a set of outputs in the\n    resulting range var as a ``(path_id, tuple-of-aspects): attribute name``\n    mapping.\n    \"\"\"\n    rel = new_external_rel(rel_name=rel_name, path_id=path_id)\n    assert rel.name\n\n    alias = pgast.Alias(aliasname=rel.name)\n\n    if not path_id.is_ptr_path():\n        rvar = pgast.RelRangeVar(\n            relation=rel, typeref=path_id.target, alias=alias)\n    else:\n        rvar = pgast.RelRangeVar(\n            relation=rel, alias=alias)\n\n    for (output_pid, output_aspects), colname in outputs.items():\n        var = pgast.ColumnRef(name=[colname])\n        for aspect in output_aspects:\n            rel.path_outputs[output_pid, aspect] = var\n\n    return rvar\n\n\ndef new_external_rel(\n    *,\n    rel_name: Tuple[str, ...],\n    path_id: irast.PathId,\n) -> pgast.Relation:\n    if len(rel_name) == 1:\n        table_name = rel_name[0]\n        schema_name = None\n    elif len(rel_name) == 2:\n        schema_name, table_name = rel_name\n    else:\n        raise AssertionError(f'unexpected rvar name: {rel_name}')\n\n    return pgast.Relation(\n        name=table_name,\n        schemaname=schema_name,\n        path_id=path_id,\n    )\n", "path": "edb/pgsql/compiler/__init__.py"}]}