Skip to content

Commit fcda1e9

Browse files
committed
Fix regression with UPDATEs on a complex path with rewrite
This was introduced as a regression in 6.x by #7265, which eliminated the use of a separate standalone subject_path_id to represent the object being updated in a rewrite. The method used for picking the the subject_path_id used when compiling the rewrites was unsound, though, and only worked in the simple case. Fix this by passing in the path_id of the update expression, so that it always matches. (If this doesn't make sense to people, we could revert #7265 instead.) Fixes #8444
1 parent 13ce875 commit fcda1e9

File tree

2 files changed

+53
-6
lines changed

2 files changed

+53
-6
lines changed

edb/edgeql/compiler/viewgen.py

+3-5
Original file line numberDiff line numberDiff line change
@@ -1018,7 +1018,8 @@ def _compile_rewrites(
10181018

10191019
def get_anchors(stype: s_objtypes.ObjectType) -> RewriteAnchors:
10201020
if stype not in anchors:
1021-
anchors[stype] = prepare_rewrite_anchors(stype, r_ctx, s_ctx, ctx)
1021+
anchors[stype] = prepare_rewrite_anchors(
1022+
stype, ir_set.path_id, r_ctx, s_ctx, ctx)
10221023
return anchors[stype]
10231024

10241025
rewrites = _compile_rewrites_for_stype(
@@ -1270,17 +1271,14 @@ class RewriteAnchors:
12701271

12711272
def prepare_rewrite_anchors(
12721273
stype: s_objtypes.ObjectType,
1274+
subject_path_id: irast.PathId,
12731275
r_ctx: RewriteContext,
12741276
s_ctx: ShapeContext,
12751277
ctx: context.ContextLevel,
12761278
) -> RewriteAnchors:
12771279
schema = ctx.env.schema
12781280

12791281
# init set for __subject__
1280-
subject_path_id = irast.PathId.from_type(
1281-
schema, stype,
1282-
namespace=ctx.path_id_namespace, env=ctx.env,
1283-
)
12841282
subject_set = setgen.class_set(
12851283
stype, path_id=subject_path_id, ctx=ctx
12861284
)

tests/test_edgeql_rewrites.py

+50-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
from edb.testbase import server as tb
2525

2626

27-
class TestRewrites(tb.QueryTestCase):
27+
class TestRewrites(tb.DDLTestCase):
2828

2929
SCHEMA = os.path.join(os.path.dirname(__file__), 'schemas', 'movies.esdl')
3030
# Setting up some rewrites makes the tests run a bit faster
@@ -1108,3 +1108,52 @@ async def test_edgeql_rewrites_29(self):
11081108
update Project set { name := '## redacted ##' }
11091109
'''
11101110
)
1111+
1112+
async def test_edgeql_rewrites_30(self):
1113+
await self.con.execute('''
1114+
insert Document { name := '1' };
1115+
insert Document { name := '2' };
1116+
insert Document { name := '3' };
1117+
''')
1118+
1119+
await self.con.execute('''
1120+
with H := ( x := (select Document filter .name = '1') )
1121+
update H.x set { text := 'full' };
1122+
''')
1123+
await self.con.execute('''
1124+
with H := { x := (select Document filter .name = '1') }
1125+
update H.x set { text := 'full' };
1126+
''')
1127+
await self.con.execute('''
1128+
with H := { x := (select Document filter .name = '1' limit 1) }
1129+
update H.x set { text := 'full' };
1130+
''')
1131+
1132+
async def test_edgeql_rewrites_triggers_01(self):
1133+
await self.con.execute('''
1134+
create type Pidgeon {
1135+
create required link hole: Document;
1136+
create trigger set_hole_full
1137+
after insert
1138+
for each do (update
1139+
__new__.hole
1140+
set {
1141+
text := 'full'
1142+
});
1143+
};
1144+
''')
1145+
1146+
await self.con.execute('''
1147+
insert Document { name := '1' };
1148+
insert Document { name := '2' };
1149+
insert Document { name := '3' };
1150+
''')
1151+
1152+
# A 6.0 regression (#8444)
1153+
await self.con.execute('''
1154+
insert Pidgeon {
1155+
hole := (
1156+
(select Document filter .name = '1' limit 1)
1157+
),
1158+
};
1159+
''')

0 commit comments

Comments
 (0)