From bafd35be640c3f4ff5ebada335c3ee54d226aadf Mon Sep 17 00:00:00 2001 From: dnwpark Date: Thu, 11 Jul 2024 15:29:45 -0400 Subject: [PATCH] Remove cfg view children from non-cfg view typerefs. --- edb/ir/ast.py | 2 ++ edb/ir/typeutils.py | 31 +++++++++++++++++++++++++++++++ edb/pgsql/compiler/relctx.py | 18 +++++++++++++++++- edb/pgsql/delta.py | 35 +++++++++++++++++++---------------- edb/pgsql/inheritance.py | 8 +++++--- edb/pgsql/types.py | 30 ------------------------------ edb/server/bootstrap.py | 4 ++-- 7 files changed, 76 insertions(+), 52 deletions(-) diff --git a/edb/ir/ast.py b/edb/ir/ast.py index bbaff11ac20..9559f05a022 100644 --- a/edb/ir/ast.py +++ b/edb/ir/ast.py @@ -173,6 +173,8 @@ class TypeRef(ImmutableBase): is_scalar: bool = False # True, if this describes a view is_view: bool = False + # True, if this describes a cfg view + is_cfg_view: bool = False # True, if this describes an abstract type is_abstract: bool = False # True, if the collection type is persisted in the schema diff --git a/edb/ir/typeutils.py b/edb/ir/typeutils.py index 6a5ae22bbd2..934a5be0201 100644 --- a/edb/ir/typeutils.py +++ b/edb/ir/typeutils.py @@ -61,6 +61,36 @@ TypeRefCache = dict[TypeRefCacheKey, 'irast.TypeRef'] +# Modules where all the "types" in them are really just custom views +# provided by metaschema. +VIEW_MODULES = ('sys', 'cfg') + + +def is_cfg_view( + obj: s_obj.Object, + schema: s_schema.Schema, +) -> bool: + return ( + isinstance(obj, (s_objtypes.ObjectType, s_pointers.Pointer)) + and ( + obj.get_name(schema).module in VIEW_MODULES + or bool( + (cfg_object := schema.get( + 'cfg::ConfigObject', + type=s_objtypes.ObjectType, default=None + )) + and ( + nobj := ( + obj if isinstance(obj, s_objtypes.ObjectType) + else obj.get_source(schema) + ) + ) + and nobj.issubclass(schema, cfg_object) + ) + ) + ) + + def is_scalar(typeref: irast.TypeRef) -> bool: """Return True if *typeref* describes a scalar type.""" return typeref.is_scalar @@ -400,6 +430,7 @@ def _typeref( is_scalar=t.is_scalar(), is_abstract=t.get_abstract(schema), is_view=t.is_view(schema), + is_cfg_view=is_cfg_view(t, schema), is_opaque_union=t.get_is_opaque_union(schema), needs_custom_json_cast=needs_custom_json_cast, sql_type=sql_type, diff --git a/edb/pgsql/compiler/relctx.py b/edb/pgsql/compiler/relctx.py index 29316b87f02..e3471dcd535 100644 --- a/edb/pgsql/compiler/relctx.py +++ b/edb/pgsql/compiler/relctx.py @@ -1804,7 +1804,23 @@ def _get_typeref_descendants( include_descendants and not for_mutation ): - descendants = [typeref, *irtyputils.get_typeref_descendants(typeref)] + descendants = [ + typeref, + *( + descendant + for descendant in irtyputils.get_typeref_descendants(typeref) + + # XXX: Exclude sys/cfg tables from non sys/cfg inheritance CTEs. + # This probably isn't *really* what we want to do, but until we + # figure that out, do *something* so that DDL isn't + # excruciatingly slow because of the cost of explicit id + # checks. See #5168. + if ( + not descendant.is_cfg_view + or typeref.is_cfg_view + ) + ) + ] # Try to only select from actual concrete types. concrete_descendants = [ diff --git a/edb/pgsql/delta.py b/edb/pgsql/delta.py index 551648153a1..86d1c466d92 100644 --- a/edb/pgsql/delta.py +++ b/edb/pgsql/delta.py @@ -241,7 +241,7 @@ def schedule_inhview_source_update( assert isinstance(ctx.op, CompositeMetaCommand) src = ptr.get_source(schema) - if src and types.is_cfg_view(src, schema): + if src and irtyputils.is_cfg_view(src, schema): assert isinstance(src, s_sources.Source) self.pgops.add( CompositeMetaCommand._refresh_fake_cfg_view_cmd( @@ -2000,7 +2000,7 @@ def constraint_is_effective( ): return False - if types.is_cfg_view(subject, schema): + if irtyputils.is_cfg_view(subject, schema): return False match subject: @@ -3089,7 +3089,7 @@ def attach_alter_table(self, context): @staticmethod def _get_table_name(obj, schema) -> tuple[str, str]: - is_internal_view = types.is_cfg_view(obj, schema) + is_internal_view = irtyputils.is_cfg_view(obj, schema) aspect = 'dummy' if is_internal_view else None return common.get_backend_name( schema, obj, catenate=False, aspect=aspect) @@ -3214,7 +3214,7 @@ def _get_select_from( cols = [] special_cols = ['tableoid', 'xmin', 'cmin', 'xmax', 'cmax', 'ctid'] - if not types.is_cfg_view(obj, schema): + if not irtyputils.is_cfg_view(obj, schema): cols.extend([(col, col, True) for col in special_cols]) else: cols.extend([('NULL', col, False) for col in special_cols]) @@ -3342,8 +3342,8 @@ def get_inhview( # excruciatingly slow because of the cost of explicit id # checks. See #5168. and ( - not types.is_cfg_view(child, schema) - or types.is_cfg_view(obj, schema) + not irtyputils.is_cfg_view(child, schema) + or irtyputils.is_cfg_view(obj, schema) ) ] @@ -3381,7 +3381,7 @@ def update_base_inhviews_on_rebase( context: sd.CommandContext, obj: CompositeObject, ) -> None: - if types.is_cfg_view(obj, schema): + if irtyputils.is_cfg_view(obj, schema): self._refresh_fake_cfg_view(obj, schema, context) bases = set(obj.get_bases(schema).objects(schema)) @@ -3460,7 +3460,7 @@ def create_inhview( ) -> None: assert types.has_table(obj, schema) - if types.is_cfg_view(obj, schema): + if irtyputils.is_cfg_view(obj, schema): self._refresh_fake_cfg_view(obj, schema, context) inhview = self.get_inhview(schema, obj, exclude_ptrs=exclude_ptrs) @@ -3490,7 +3490,7 @@ def alter_inhview( ) -> None: assert types.has_table(obj, schema) - if types.is_cfg_view(obj, schema): + if irtyputils.is_cfg_view(obj, schema): self._refresh_fake_cfg_view(obj, schema, context) inhview = self.get_inhview( @@ -3944,8 +3944,8 @@ def _fixup_configs( # configs, since those need to be created after the standard # schema is in place. if not ( - types.is_cfg_view(scls, eff_schema) - and scls.get_name(eff_schema).module not in types.VIEW_MODULES + irtyputils.is_cfg_view(scls, eff_schema) + and scls.get_name(eff_schema).module not in irtyputils.VIEW_MODULES ): return @@ -5837,7 +5837,7 @@ def _create_property( (default := prop.get_default(schema)) and not prop.is_pure_computable(schema) and not fills_required - and not types.is_cfg_view(src.scls, schema) # sigh + and not irtyputils.is_cfg_view(src.scls, schema) # sigh # link properties use SQL defaults and shouldn't need # us to do it explicitly (which is good, since # _alter_pointer_optionality doesn't currently work on @@ -6241,7 +6241,10 @@ def get_target_objs(self, link, schema): x for obj in objs for x in obj.descendants(schema)} return { obj for obj in objs - if not obj.is_view(schema) and not types.is_cfg_view(obj, schema) + if ( + not obj.is_view(schema) + and not irtyputils.is_cfg_view(obj, schema) + ) } def get_orphan_link_ancestors(self, link, schema): @@ -6798,7 +6801,7 @@ def apply( if ( not isinstance(source, s_objtypes.ObjectType) - or types.is_cfg_view(source, eff_schema) + or irtyputils.is_cfg_view(source, eff_schema) ): continue @@ -6847,7 +6850,7 @@ def apply( delete_target_targets = set() for target in all_affected_targets: - if types.is_cfg_view(target, schema): + if irtyputils.is_cfg_view(target, schema): continue deferred_links = [] @@ -6876,7 +6879,7 @@ def apply( source = link.get_source(schema) if ( not source.is_material_object_type(schema) - or types.is_cfg_view(source, schema) + or irtyputils.is_cfg_view(source, schema) ): continue diff --git a/edb/pgsql/inheritance.py b/edb/pgsql/inheritance.py index e1a1694d26e..c4b88682ca0 100644 --- a/edb/pgsql/inheritance.py +++ b/edb/pgsql/inheritance.py @@ -7,6 +7,8 @@ from edb.schema import sources as s_sources from edb.schema import schema as s_schema +from edb.ir import typeutils as irtyputils + from . import ast as pgast from . import types from . import common @@ -69,8 +71,8 @@ def get_inheritance_view( # excruciatingly slow because of the cost of explicit id # checks. See #5168. and ( - not types.is_cfg_view(child, schema) - or types.is_cfg_view(obj, schema) + not irtyputils.is_cfg_view(child, schema) + or irtyputils.is_cfg_view(obj, schema) ) ] @@ -125,7 +127,7 @@ def _get_select_from( system_cols = ['tableoid', 'xmin', 'cmin', 'xmax', 'cmax', 'ctid'] for sys_col_name in system_cols: val: pgast.BaseExpr - if not types.is_cfg_view(obj, schema): + if not irtyputils.is_cfg_view(obj, schema): val = pgast.ColumnRef(name=(table_rvar_name, sys_col_name)) else: val = pgast.NullConstant() diff --git a/edb/pgsql/types.py b/edb/pgsql/types.py index 7120689adc2..0bc7c9d00f4 100644 --- a/edb/pgsql/types.py +++ b/edb/pgsql/types.py @@ -768,36 +768,6 @@ def _ptrref_storable_in_pointer(ptrref: irast.BasePointerRef) -> bool: ) -# Modules where all the "types" in them are really just custom views -# provided by metaschema. -VIEW_MODULES = ('sys', 'cfg') - - -def is_cfg_view( - obj: s_obj.Object, - schema: s_schema.Schema, -) -> bool: - return ( - isinstance(obj, (s_objtypes.ObjectType, s_pointers.Pointer)) - and ( - obj.get_name(schema).module in VIEW_MODULES - or bool( - (cfg_object := schema.get( - 'cfg::ConfigObject', - type=s_objtypes.ObjectType, default=None - )) - and ( - nobj := ( - obj if isinstance(obj, s_objtypes.ObjectType) - else obj.get_source(schema) - ) - ) - and nobj.issubclass(schema, cfg_object) - ) - ) - ) - - def has_table( obj: Optional[s_obj.InheritingObject], schema: s_schema.Schema ) -> bool: diff --git a/edb/server/bootstrap.py b/edb/server/bootstrap.py index c57fbc01ba6..53059f5fac4 100644 --- a/edb/server/bootstrap.py +++ b/edb/server/bootstrap.py @@ -51,6 +51,7 @@ from edb import edgeql from edb.ir import statypes +from edb.ir import typeutils as irtyputils from edb.edgeql import ast as qlast from edb.common import debug @@ -79,7 +80,6 @@ from edb.server import pgcon from edb.pgsql import common as pg_common -from edb.pgsql import types as pg_types from edb.pgsql import dbops from edb.pgsql import delta as delta_cmds from edb.pgsql import metaschema @@ -1135,7 +1135,7 @@ async def create_branch( multi_properties = { prop for prop in schema.get_objects(type=s_props.Property) if prop.get_cardinality(schema).is_multi() - and prop.get_name(schema).module not in pg_types.VIEW_MODULES + and prop.get_name(schema).module not in irtyputils.VIEW_MODULES } for mprop in multi_properties: