Skip to content

Commit 79f3d71

Browse files
KangOlPirolsaj-fuentes
committed
[FIX] util.{remove_records,replace_record_references_batch}
Correctly handle changes in company dependent jsonb columns. Use the function `jsonb_object` instead of a casted string, so we don't get literal `{` and `}` into the query. Such characters needs to be escaped to allow the query to be exploded. Also use `cr.mogrify` instead of manual formatting of the jsonpath argument of the query. closes #141 Signed-off-by: Christophe Simonis (chs) <[email protected]> Co-authored-by: Edoardo Piroli <[email protected]> Co-authored-by: Alvaro Fuentes <[email protected]>
1 parent 5f199f2 commit 79f3d71

File tree

1 file changed

+28
-17
lines changed

1 file changed

+28
-17
lines changed

Diff for: src/util/records.py

+28-17
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from operator import itemgetter
1010

1111
import lxml
12+
from psycopg2 import sql
1213
from psycopg2.extras import Json, execute_values
1314

1415
try:
@@ -414,28 +415,33 @@ def remove_records(cr, model, ids):
414415
query = 'DELETE FROM "{}" WHERE {} AND "{}" IN %s'.format(ir.table, ir.model_filter(), ir.res_id)
415416
cr.execute(query, [model, ids])
416417
elif ir.company_dependent_comodel == model:
418+
json_path = cr.mogrify(
419+
"$.* ? ({})".format(" || ".join(["@ == %s"] * len(ids))),
420+
ids,
421+
).decode()
422+
417423
query = cr.mogrify(
418424
format_query(
419425
cr,
420426
"""
421427
UPDATE {table}
422-
SET {column} = (
423-
SELECT jsonb_object_agg(
424-
key,
425-
CASE
426-
WHEN value::int4 IN %s THEN NULL
427-
ELSE value::int4
428-
END)
429-
FROM jsonb_each_text({column})
430-
)
431-
WHERE {column} IS NOT NULL
432-
AND {column} @? %s
433-
AND {{parallel_filter}}
428+
SET {column} = (
429+
SELECT jsonb_object_agg(
430+
key,
431+
CASE
432+
WHEN value::int4 IN %s THEN NULL
433+
ELSE value::int4
434+
END)
435+
FROM jsonb_each_text({column})
436+
)
437+
WHERE {column} IS NOT NULL
438+
AND {column} @? {json_path}
434439
""",
435440
table=ir.table,
436441
column=ir.res_id,
442+
json_path=sql.Literal(json_path),
437443
),
438-
[ids, "$.* ? ({})".format(" || ".join(map("@ == {}".format, ids)))],
444+
[ids],
439445
).decode()
440446
explode_execute(cr, query, table=ir.table)
441447
_rm_refs(cr, model, ids)
@@ -1469,23 +1475,28 @@ def replace_record_references_batch(cr, id_mapping, model_src, model_dst=None, r
14691475
if ir.company_dependent_comodel:
14701476
if ir.company_dependent_comodel == model_src:
14711477
assert model_src == model_dst
1478+
json_path = cr.mogrify(
1479+
"$.* ? ({})".format(" || ".join(["@ == %s"] * len(id_mapping))),
1480+
list(id_mapping),
1481+
).decode()
1482+
14721483
query = cr.mogrify(
14731484
format_query(
14741485
cr,
14751486
"""
14761487
UPDATE {table}
14771488
SET {column} = (
1478-
SELECT jsonb_object_agg(key, COALESCE((%s::jsonb->>value)::int, value::int))
1489+
SELECT jsonb_object_agg(key, COALESCE(((jsonb_object(%s::text[]))->>value)::int, value::int))
14791490
FROM jsonb_each_text({column})
14801491
)
14811492
WHERE {column} IS NOT NULL
1482-
AND {column} @? %s
1483-
AND {{parallel_filter}}
1493+
AND {column} @? {json_path}
14841494
""",
14851495
table=ir.table,
14861496
column=ir.res_id,
1497+
json_path=sql.Literal(json_path),
14871498
),
1488-
[Json(id_mapping), "$.* ? ({})".format(" || ".join(map("@ == {}".format, id_mapping)))],
1499+
[list(map(list, id_mapping.items()))],
14891500
).decode()
14901501
explode_execute(cr, query, table=ir.table)
14911502
continue

0 commit comments

Comments
 (0)