Skip to content

Commit

Permalink
Refactor schema.Expression.qlast to parse() (#7167)
Browse files Browse the repository at this point in the history
  • Loading branch information
aljazerzen authored Apr 17, 2024
1 parent 11376d4 commit 992ab82
Show file tree
Hide file tree
Showing 23 changed files with 84 additions and 80 deletions.
4 changes: 2 additions & 2 deletions edb/edgeql/compiler/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,8 +333,8 @@ def _enforce_pointer_constraints(
final_expr: Optional[s_expr.Expression] = (
constraint.get_finalexpr(ctx.env.schema)
)
assert final_expr is not None and final_expr.qlast is not None
ir = dispatch.compile(final_expr.qlast, ctx=sctx)
assert final_expr is not None and final_expr.parse() is not None
ir = dispatch.compile(final_expr.parse(), ctx=sctx)

result = ireval.evaluate(ir, schema=ctx.env.schema)
assert isinstance(result, irast.BooleanConstant)
Expand Down
30 changes: 17 additions & 13 deletions edb/edgeql/compiler/conflicts.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,20 +62,20 @@ def _get_needed_ptrs(
constr.get_subjectexpr(ctx.env.schema)
)
assert subjexpr
needed_ptrs |= qlutils.find_subject_ptrs(subjexpr.qlast)
needed_ptrs |= qlutils.find_subject_ptrs(subjexpr.parse())
if except_expr := constr.get_except_expr(ctx.env.schema):
assert isinstance(except_expr, s_expr.Expression)
needed_ptrs |= qlutils.find_subject_ptrs(except_expr.qlast)
needed_ptrs |= qlutils.find_subject_ptrs(except_expr.parse())

wl = list(needed_ptrs)
ptr_anchors = {}
while wl:
p = wl.pop()
ptr = subject_typ.getptr(ctx.env.schema, s_name.UnqualName(p))
if expr := ptr.get_expr(ctx.env.schema):
assert isinstance(expr.qlast, qlast.Expr)
ptr_anchors[p] = expr.qlast
for ref in qlutils.find_subject_ptrs(expr.qlast):
assert isinstance(expr.parse(), qlast.Expr)
ptr_anchors[p] = expr.parse()
for ref in qlutils.find_subject_ptrs(expr.parse()):
if ref not in needed_ptrs:
wl.append(ref)
needed_ptrs.add(ref)
Expand Down Expand Up @@ -213,9 +213,9 @@ def _compile_conflict_select_for_obj_type(
# for __subject__ in the subjectexpr and compare *that*
if (subjectexpr := cnstr.get_subjectexpr(ctx.env.schema)):
assert isinstance(subjectexpr, s_expr.Expression)
assert isinstance(subjectexpr.qlast, qlast.Expr)
lhs = qlutils.subject_substitute(subjectexpr.qlast, lhs)
rhs = qlutils.subject_substitute(subjectexpr.qlast, rhs)
assert isinstance(subjectexpr.parse(), qlast.Expr)
lhs = qlutils.subject_substitute(subjectexpr.parse(), lhs)
rhs = qlutils.subject_substitute(subjectexpr.parse(), rhs)

conds.append(qlast.BinOp(
op='=' if ptr_card.is_single() else 'IN',
Expand All @@ -241,19 +241,23 @@ def _compile_conflict_select_for_obj_type(
subject_expr: Optional[s_expr.Expression] = (
constr.get_subjectexpr(ctx.env.schema)
)
assert subject_expr and isinstance(subject_expr.qlast, qlast.Expr)
lhs = qlutils.subject_paths_substitute(subject_expr.qlast, ptr_anchors)
rhs = qlutils.subject_substitute(subject_expr.qlast, insert_subject)
assert subject_expr and isinstance(subject_expr.parse(), qlast.Expr)
lhs = qlutils.subject_paths_substitute(
subject_expr.parse(), ptr_anchors
)
rhs = qlutils.subject_substitute(
subject_expr.parse(), insert_subject
)
op = qlast.BinOp(op='=', left=lhs, right=rhs)

# If there is an except expr, we need to add in those checks also
if except_expr := constr.get_except_expr(ctx.env.schema):
assert isinstance(except_expr, s_expr.Expression)

e_lhs = qlutils.subject_paths_substitute(
except_expr.qlast, ptr_anchors)
except_expr.parse(), ptr_anchors)
e_rhs = qlutils.subject_substitute(
except_expr.qlast, insert_subject)
except_expr.parse(), insert_subject)

true_ast = qlast.Constant.boolean(True)
on = qlast.BinOp(
Expand Down
6 changes: 3 additions & 3 deletions edb/edgeql/compiler/expr.py
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,7 @@ def compile_GlobalExpr(
# treat it as being empty.
if ctx.env.options.make_globals_empty:
if default:
return dispatch.compile(default.qlast, ctx=ctx)
return dispatch.compile(default.parse(), ctx=ctx)
else:
return setgen.new_empty_set(
stype=glob.get_target(ctx.env.schema), ctx=ctx)
Expand Down Expand Up @@ -625,7 +625,7 @@ def compile_GlobalExpr(
main_param = subctx.maybe_create_anchor(param_set, 'glob')
param_set = func.compile_operator(
expr, op_name='std::??',
qlargs=[main_param, default.qlast], ctx=subctx)
qlargs=[main_param, default.parse()], ctx=subctx)
elif default and present_set:
# ... but if {} is a valid value for the global, we need to
# stick in an extra parameter to indicate whether to use
Expand All @@ -638,7 +638,7 @@ def compile_GlobalExpr(

param_set = func.compile_operator(
expr, op_name='std::IF',
qlargs=[main_param, present_param, default.qlast], ctx=subctx)
qlargs=[main_param, present_param, default.parse()], ctx=subctx)
elif not isinstance(param_set, irast.Set):
param_set = dispatch.compile(param_set, ctx=ctx)

Expand Down
4 changes: 2 additions & 2 deletions edb/edgeql/compiler/policies.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,13 @@ def compile_pol(

expr_field: Optional[s_expr.Expression] = pol.get_expr(schema)
if expr_field:
expr = expr_field.qlast
expr = expr_field.parse()
else:
expr = qlast.Constant.boolean(True)

if condition := pol.get_condition(schema):
assert isinstance(condition, s_expr.Expression)
expr = qlast.BinOp(op='AND', left=condition.qlast, right=expr)
expr = qlast.BinOp(op='AND', left=condition.parse(), right=expr)

# Find all descendants of the original subject of the rule
subject = pol.get_original_subject(schema)
Expand Down
2 changes: 1 addition & 1 deletion edb/edgeql/compiler/polyres.py
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ def _get_cast_distance(
)
assert param_default is not None
default = compile_arg(
param_default.qlast, param_typemod, ctx=ctx)
param_default.parse(), param_typemod, ctx=ctx)

empty_default = (
has_inlined_defaults or
Expand Down
2 changes: 1 addition & 1 deletion edb/edgeql/compiler/setgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -1600,7 +1600,7 @@ def computable_ptr_set(
raise errors.InternalServerError(
f'{ptrcls_sn!r} is not a computed pointer')

comp_qlexpr = comp_expr.qlast
comp_qlexpr = comp_expr.parse()
assert isinstance(comp_qlexpr, qlast.Expr), 'expected qlast.Expr'
schema_qlexpr = comp_qlexpr

Expand Down
2 changes: 1 addition & 1 deletion edb/edgeql/compiler/stmtctx.py
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,7 @@ def _declare_view_from_schema(
subctx.expr_exposed = context.Exposure.UNEXPOSED
view_expr: s_expr.Expression | None = viewcls.get_expr(ctx.env.schema)
assert view_expr is not None
view_ql = view_expr.qlast
view_ql = view_expr.parse()
viewcls_name = viewcls.get_name(ctx.env.schema)
assert isinstance(view_ql, qlast.Expr), 'expected qlast.Expr'
view_set = declare_view(view_ql, alias=viewcls_name,
Expand Down
4 changes: 2 additions & 2 deletions edb/edgeql/compiler/triggers.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def compile_trigger(

trigger_expr: Optional[s_expr.Expression] = trigger.get_expr(schema)
assert trigger_expr
trigger_ast = trigger_expr.qlast
trigger_ast = trigger_expr.parse()

# A conditional trigger desugars to a FOR query that puts the
# condition in the FILTER of a trivial SELECT.
Expand All @@ -112,7 +112,7 @@ def compile_trigger(
iterator_alias='__',
iterator=qlast.SelectQuery(
result=qlast.Tuple(elements=[]),
where=condition.qlast,
where=condition.parse(),
),
result=trigger_ast,
)
Expand Down
4 changes: 2 additions & 2 deletions edb/edgeql/compiler/viewgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,7 @@ def _gen_pointers_from_defaults(
steps=[qlast.Ptr(name=ptrcls_sn.name)],
),
compexpr=qlast.DetachedExpr(
expr=default_expr.qlast,
expr=default_expr.parse(),
preserve_path_prefix=True,
),
origin=qlast.ShapeOrigin.DEFAULT,
Expand Down Expand Up @@ -1147,7 +1147,7 @@ def _compile_rewrites_for_stype(
steps=[qlast.Ptr(name=ptrcls_sn.name)],
),
compexpr=qlast.DetachedExpr(
expr=rewrite_expr.qlast,
expr=rewrite_expr.parse(),
preserve_path_prefix=True,
),
)
Expand Down
4 changes: 2 additions & 2 deletions edb/pgsql/delta.py
Original file line number Diff line number Diff line change
Expand Up @@ -1230,7 +1230,7 @@ def fix_return_type(
qlexpr = qlcompiler.astutils.ensure_ql_query(
ql_ast.TypeCast(
type=s_utils.typeref_to_ast(schema, return_type),
expr=nativecode.qlast,
expr=nativecode.parse(),
)
)
nativecode = self._compile_edgeql_function(
Expand Down Expand Up @@ -4868,7 +4868,7 @@ def _compile_conversion_expr(
context,
s_expr.Expression.from_ast(
ql_ast.TypeCast(
expr=conv_expr.qlast,
expr=conv_expr.parse(),
type=s_utils.typeref_to_ast(schema, new_target),
),
schema=orig_schema,
Expand Down
12 changes: 6 additions & 6 deletions edb/pgsql/schemamech.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,9 +248,9 @@ def compile_constraint(
)

final_expr: Optional[s_expr.Expression] = constraint.get_finalexpr(schema)
assert final_expr is not None and final_expr.qlast is not None
assert final_expr is not None and final_expr.parse() is not None
ir = qlcompiler.compile_ast_to_ir(
final_expr.qlast,
final_expr.parse(),
schema,
options=options,
)
Expand All @@ -261,7 +261,7 @@ def compile_constraint(
if except_expr := constraint.get_except_expr(schema):
assert isinstance(except_expr, s_expr.Expression)
except_ir = qlcompiler.compile_ast_to_ir(
except_expr.qlast,
except_expr.parse(),
schema,
options=options,
)
Expand Down Expand Up @@ -329,9 +329,9 @@ def compile_constraint(
)

final_expr = constraint_origin.get_finalexpr(schema)
assert final_expr is not None and final_expr.qlast is not None
assert final_expr is not None and final_expr.parse() is not None
origin_ir = qlcompiler.compile_ast_to_ir(
final_expr.qlast,
final_expr.parse(),
schema,
options=origin_options,
)
Expand All @@ -357,7 +357,7 @@ def compile_constraint(
if except_expr := constraint_origin.get_except_expr(schema):
assert isinstance(except_expr, s_expr.Expression)
except_ir = qlcompiler.compile_ast_to_ir(
except_expr.qlast,
except_expr.parse(),
schema,
options=origin_options,
)
Expand Down
14 changes: 7 additions & 7 deletions edb/schema/constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ def format_error_text(
qlast.Path(steps=[qlast.ObjectRef(name=subject_name)]),
]

args_ql.extend(arg.qlast for arg in args)
args_ql.extend(arg.parse() for arg in args)

constr_base: Constraint = schema.get(
self.get_name(schema), type=type(self))
Expand Down Expand Up @@ -522,7 +522,7 @@ def as_inherited_ref_ast(

except_expr: s_expr.Expression | None = parent.get_except_expr(schema)
if except_expr:
except_expr_ql = except_expr.qlast
except_expr_ql = except_expr.parse()
else:
except_expr_ql = None

Expand Down Expand Up @@ -791,7 +791,7 @@ def _populate_concrete_constraint_attrs(
)

if subjectexpr is not None:
subject_ql = subjectexpr.qlast
subject_ql = subjectexpr.parse()
subject = subject_ql
else:
subject = subject_obj
Expand Down Expand Up @@ -830,7 +830,7 @@ def _populate_concrete_constraint_attrs(
args_ql: List[qlast.Base] = [
qlast.Path(steps=[qlast.SpecialAnchor(name='__subject__')]),
]
args_ql.extend(arg.qlast for arg in args)
args_ql.extend(arg.parse() for arg in args)
args_map = qlutils.index_parameters(
args_ql,
parameters=constr_base.get_params(schema),
Expand Down Expand Up @@ -1340,7 +1340,7 @@ def _apply_field_ast(
assert isinstance(op.new_value, s_expr.ExpressionList)
args = []
for arg in op.new_value:
exprast = arg.qlast
exprast = arg.parse()
assert isinstance(exprast, qlast.Expr), "expected qlast.Expr"
args.append(exprast)
node.args = args
Expand Down Expand Up @@ -1562,7 +1562,7 @@ def canonicalize_alter_from_external_ref(
assert isinstance(name, sn.QualName), "expected qualified name"
ast = qlast.CreateConcreteConstraint(
name=qlast.ObjectRef(name=name.name, module=name.module),
subjectexpr=subjectexpr.qlast,
subjectexpr=subjectexpr.parse(),
args=[],
)
quals = sn.quals_from_fullname(self.classname)
Expand Down Expand Up @@ -1603,7 +1603,7 @@ def _apply_field_ast(
if op.property == 'args':
assert isinstance(op.old_value, s_expr.ExpressionList)
assert isinstance(node, qlast.DropConcreteConstraint)
node.args = [arg.qlast for arg in op.old_value]
node.args = [arg.parse() for arg in op.old_value]
return

super()._apply_field_ast(schema, context, node, op)
Expand Down
8 changes: 4 additions & 4 deletions edb/schema/delta.py
Original file line number Diff line number Diff line change
Expand Up @@ -2079,7 +2079,7 @@ def _fix_referencing_expr_after_rename(

# say as_fragment=True as a hack to avoid renormalizing it
out = s_expr.Expression.from_ast(
compiled.qlast, schema, modaliases={}, as_fragment=True)
compiled.parse(), schema, modaliases={}, as_fragment=True)
return out

def _propagate_if_expr_refs(
Expand Down Expand Up @@ -2438,14 +2438,14 @@ def _apply_fields_ast(
attr_val: Any
if issubclass(field.type, s_expr.Expression):
assert isinstance(ddl_id, s_expr.Expression)
attr_val = ddl_id.qlast
attr_val = ddl_id.parse()
elif issubclass(field.type, s_expr.ExpressionList):
assert isinstance(ddl_id, s_expr.ExpressionList)
attr_val = [e.qlast for e in ddl_id]
attr_val = [e.parse() for e in ddl_id]
elif issubclass(field.type, s_expr.ExpressionDict):
assert isinstance(ddl_id, s_expr.ExpressionDict)
attr_val = {
name: e.qlast
name: e.parse()
for name, e in ddl_id.items()
}
else:
Expand Down
16 changes: 8 additions & 8 deletions edb/schema/expr.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,9 @@ def __eq__(self, rhs: object) -> bool:
and self.origin == rhs.origin
)

@property
def qlast(self) -> qlast_.Expr:
def parse(self) -> qlast_.Expr:
"""Parse the expression text into an AST. Cached."""

if self._qlast is None:
self._qlast = qlparser.parse_fragment(
self.text, filename=f'<{self.origin}>' if self.origin else "")
Expand Down Expand Up @@ -216,12 +217,12 @@ def compiled(

if as_fragment:
ir: irast_.Command = qlcompiler.compile_ast_fragment_to_ir(
self.qlast,
self.parse(),
schema=schema,
options=options,
)
else:
ql_expr = self.qlast
ql_expr = self.parse()
if detached:
ql_expr = qlast.DetachedExpr(
expr=ql_expr,
Expand All @@ -242,7 +243,7 @@ def compiled(
return CompiledExpression(
text=self.text,
refs=so.ObjectSet.create(schema, srefs),
_qlast=self.qlast,
_qlast=self.parse(),
_irast=ir,
origin=self.origin,
)
Expand Down Expand Up @@ -277,7 +278,7 @@ def from_ir(
return CompiledExpression(
text=expr.text,
refs=so.ObjectSet.create(schema, ir.schema_refs),
_qlast=expr.qlast,
_qlast=expr.parse(),
_irast=ir,
origin=expr.origin,
)
Expand Down Expand Up @@ -424,8 +425,7 @@ def resolve(self, schema: s_schema.Schema) -> Expression:
_irast=self._irast, # type: ignore[arg-type]
)

@property
def qlast(self) -> qlast_.Expr:
def parse(self) -> qlast_.Expr:
if self._qlast is None:
self._qlast = qlparser.parse_fragment(self.text)
return self._qlast
Expand Down
2 changes: 1 addition & 1 deletion edb/schema/expraliases.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ def _handle_alias_op(
pschema = drop_old_types_cmd.apply(pschema, context)

ir = compile_alias_expr(
expr.qlast,
expr.parse(),
classname,
pschema,
context,
Expand Down
Loading

0 comments on commit 992ab82

Please sign in to comment.