Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
source=source_expr,
ptrcls=ptrcls,
direction=ptr_direction
)
shape_expr_ctx.stmt_path_scope = collections.defaultdict(int)
compexpr = self.visit(shape_el.compexpr)
target_class = irutils.infer_type(compexpr, schema)
if target_class is None:
msg = 'cannot determine expression result type'
raise errors.EdgeQLError(msg, context=source_ctx)
if ptrcls is None:
if (isinstance(ctx.stmt, irast.MutatingStmt) and
ctx.clause != 'result'):
raise errors.EdgeQLError(
'reference to unknown pointer',
context=source_ctx)
ptrcls = ptr_metacls(
name=sn.SchemaName(
module=ptrname[0] or ptrsource.name.module,
name=ptrname[1]),
).derive(schema, ptrsource, target_class)
if isinstance(shape_el.compexpr, qlast.Statement):
if shape_el.compexpr.single:
ptrcls.mapping = s_links.LinkMapping.ManyToOne
else:
ptrcls.mapping = s_links.LinkMapping.ManyToMany
compexpr = self._ensure_stmt(compexpr, shape_expr_ctx)
# that references to link properties in sub-SELECT
# can be resolved. This is necessary for proper
# evaluation of link properties on computable links,
# most importantly, in INSERT/UPDATE context.
shape_expr_ctx.toplevel_shape_rptr = irast.Pointer(
source=source_expr,
ptrcls=ptrcls,
direction=ptr_direction
)
shape_expr_ctx.stmt_path_scope = collections.defaultdict(int)
compexpr = self.visit(shape_el.compexpr)
target_class = irutils.infer_type(compexpr, schema)
if target_class is None:
msg = 'cannot determine expression result type'
raise errors.EdgeQLError(msg, context=source_ctx)
if ptrcls is None:
if (isinstance(ctx.stmt, irast.MutatingStmt) and
ctx.clause != 'result'):
raise errors.EdgeQLError(
'reference to unknown pointer',
context=source_ctx)
ptrcls = ptr_metacls(
name=sn.SchemaName(
module=ptrname[0] or ptrsource.name.module,
name=ptrname[1]),
).derive(schema, ptrsource, target_class)
if isinstance(shape_el.compexpr, qlast.Statement):
if shape_el.compexpr.single:
node = self.process_binop(left, right, expr.op)
elif isinstance(expr, qlast.PathNode):
node = self._process_path(context, expr)
if (context.current.groupprefixes
and context.current.location in ('sorter', 'selector')\
and not context.current.in_aggregate):
for p in node.paths:
if isinstance(p, irast.MetaRef):
p = p.ref
if p.id not in context.current.groupprefixes:
err = ('node reference "%s" must appear in the GROUP BY expression or '
'used in an aggregate function ') % p.id
raise errors.EdgeQLError(err)
if (context.current.location not in {'generator', 'selector', 'opvalues'} \
and not context.current.in_func_call) or context.current.in_aggregate:
if isinstance(node, irast.EntitySet):
node = self.entityref_to_record(node, self.proto_schema)
elif isinstance(expr, qlast.ConstantNode):
node = self._process_constant(context, expr)
elif isinstance(expr, qlast.SequenceNode):
elements=[self._process_expr(context, e) for e in expr.elements]
node = irast.Sequence(elements=elements)
# Squash the sequence if it comes from IS (type,...), since we unconditionally
# transform PrototypeRefNodes into list-type constants below.
#
squash_homogeneous = expr.elements and isinstance(expr.elements[0],
def _process_update_nested_shape(self, targetstep, elements):
ctx = self.context.current
for subel in elements or []:
is_prop = (
isinstance(subel.expr.steps[0], qlast.Ptr) and
subel.expr.steps[0].type == 'property'
)
if not is_prop:
raise errors.EdgeQLError(
'only references to link properties are allowed '
'in nested UPDATE shapes', context=subel.context)
ptr_node = targetstep.rptr
el = self._process_shape(
targetstep,
elements,
rptr=ptr_node,
_recurse=True,
require_expressions=True,
include_implicit=False)
substmt = irast.SelectStmt(
result=el,
path_scope=ctx.path_scope,
def _process_expr(self, context, expr):
node = None
if isinstance(expr, qlast.SubqueryNode):
node = self._process_expr(context, expr.expr)
elif isinstance(expr, qlast.SelectQueryNode):
node = context.current.subgraphs_map.get(expr)
if node is None:
with self.context(ParseContext.SUBQUERY):
node = self._transform_select(context, expr, self.arg_types)
if len(node.selector) > 1:
err = ('subquery must return only one column')
raise errors.EdgeQLError(err)
node.referrers.append(context.current.location)
context.current.graph.subgraphs.add(node)
context.current.subgraphs_map[expr] = node
refname = node.selector[0].name or node.selector[0].autoname
node.attrrefs.add(refname)
node = irast.SubgraphRef(ref=node, name=refname)
elif isinstance(expr, qlast.BinOpNode):
left = self._process_expr(context, expr.left)
right = self._process_expr(context, expr.right)
# The entityref_to_record transform must be reverted for typecheck ops
if isinstance(expr.op, ast.ops.EquivalenceOperator) \
and isinstance(left, irast.Record) \
scls=target_class,
expr=compexpr
)
ctx.singletons.add(targetstep)
targetstep.rptr = irast.Pointer(
source=source_expr,
target=targetstep,
ptrcls=ptrcls,
direction=ptr_direction
)
if ptrcls.shortname == 'std::__class__':
msg = 'cannot assign to __class__'
raise errors.EdgeQLError(msg, context=source_ctx)
if (isinstance(ctx.stmt, irast.MutatingStmt) and
ctx.clause != 'result'):
if (isinstance(ptrcls.target, s_concepts.Concept) and
not target_class.issubclass(ptrcls.target) and
target_class.name != 'std::Object'):
# Validate that the insert/update expression is
# of the correct class. Make an exception for
# expressions returning std::Object, as the
# GraphQL translator relies on that to support
# insert-by-object-id. XXX: remove this
# exemption once support for class casts is added
# to DML.
lname = f'{ptrsource.name}.{ptrcls.shortname.name}'
expected = [repr(str(ptrcls.target.name))]
raise edgedb_error.InvalidPointerTargetError(
# that references to link properties in sub-SELECT
# can be resolved. This is necessary for proper
# evaluation of link properties on computable links,
# most importantly, in INSERT/UPDATE context.
shape_expr_ctx.toplevel_shape_rptr = irast.Pointer(
source=source_expr,
ptrcls=ptrcls,
direction=ptr_direction
)
qlexpr = astutils.ensure_qlstmt(shape_el.compexpr)
compexpr = dispatch.compile(qlexpr, ctx=shape_expr_ctx)
target_class = irutils.infer_type(compexpr, schema)
if target_class is None:
msg = 'cannot determine expression result type'
raise errors.EdgeQLError(msg, context=source_ctx)
if ptrcls is None:
if (isinstance(ctx.stmt, irast.MutatingStmt) and
ctx.clause != 'result'):
raise errors.EdgeQLError(
'reference to unknown pointer',
context=source_ctx)
ptr_module = (
ptrname[0] or
ctx.derived_target_module or
ptrsource.name.module
)
ptrcls = ptr_metacls(
name=sn.SchemaName(
def _check_update_expr(self, source, target, expr):
# Check that all refs in expr point to source and are atomic,
# or, if not, are in the form ptr := ptr {+|-} set
#
schema_scope = self.get_query_schema_scope(expr)
ok = (len(schema_scope) == 0 or
(len(schema_scope) == 1
and (schema_scope[0].id == source.id
or schema_scope[0].id == target.id)))
if not ok:
msg = "update expression can only reference local atoms"
raise errors.EdgeQLError(msg)
##
# Copyright (c) 2008-2010 MagicStack Inc.
# All rights reserved.
#
# See LICENSE for details.
##
from edgedb.lang.edgeql.errors import EdgeQLError
class EdgeQLSyntaxError(EdgeQLError):
def __init__(self, token, lineno, expr=None):
self.token = token
self.expr = expr
self.lineno = lineno
def __str__(self):
return "unexpected `%s' (%s) on line %d" % (self.token, self.expr, self.lineno)