I have loop for each element_id
and nested loop for jsonb in array, and when I want to get value from jsonb by key I get null:
create procedure elements_to_entries_add(IN entry_ids uuid[], IN element_ids uuid[], IN element_values jsonb[])
language plpgsql
as
$$
<<main_label>>
DECLARE
singe_jsonb_with_values JSONB := '[]';
BEGIN
<<elements_n_values_relationship_create>>
BEGIN
<<elements_n_values_add_elements_without_values>>
DECLARE
element_id UUID;
element_n_value_relationship JSONB;
flag BOOLEAN := false;
BEGIN
FOREACH element_id IN ARRAY element_ids
LOOP
FOREACH element_n_value_relationship IN ARRAY element_values
LOOP
RAISE LOG 'INSIDE NESTED LOOP obj % , element_id %', element_n_value_relationship, element_n_value_relationship ->> 'element_id';
IF element_id::UUID = (element_n_value_relationship ->> 'element_id')::UUID THEN
flag := true;
EXIT;
END IF ;
END LOOP;
IF NOT flag THEN
singe_jsonb_with_values := singe_jsonb_with_values || jsonb_build_array(jsonb_build_object('element_id', element_id, 'value', NULL));
ELSE
singe_jsonb_with_values := singe_jsonb_with_values || jsonb_build_array(element_n_value_relationship);
END IF;
flag := false;
END LOOP;
END;
END;
INSERT INTO m2m_entries_n_elements(entry_id, element_id, value)
SELECT entry_id, element_id, value
FROM (
UNNEST(entry_ids) as entry_id
CROSS JOIN (
SELECT
element_id,
CASE
WHEN value IS NULL THEN
CASE
WHEN element_type = 1 THEN
(attributes -> 'default_value')::JSONB
WHEN element_type = 7 THEN
(attributes -> 'default_location')::JSONB
WHEN element_type = 3 THEN
(attributes -> 'default_divider')::JSONB
END
ELSE value
END
FROM (
jsonb_to_recordset(singe_jsonb_with_values::JSONB) as x(element_id UUID, value JSONB)
INNER JOIN elements ON x.element_id = elements.id
) AS element_rows_part
) as t(element_id, value)
) AS new_rows(entry_id, element_id, value)
WHERE NOT EXISTS(
SELECT 1
FROM m2m_entries_n_elements
WHERE m2m_entries_n_elements.entry_id = new_rows.entry_id::UUID
AND m2m_entries_n_elements.element_id = new_rows.element_id::UUID
);
end;
$$;
Some raise logs
:
INSIDE NESTED LOOP obj "{\"element_id\":\"ceeb364e-bb88-4f41-9c56-9e5f4d0bc1fb\",\"value\":null}" , element_id <NULL> INSIDE NESTED LOOP obj "{\"element_id\":\"e9a9ce50-a324-4529-87ef-8fdc35a3ce48\",\"value\":\"abc\"}" , element_id <NULL> INSIDE NESTED LOOP obj "{\"element_id\":\"a7993f3d-9256-4354-a147-5b9d18d7812b\",\"value\":true}" , element_id <NULL>
So when I try to compare element_id
from an external loop with element_id
from jsonb, I will always try to compare <uuid> == <null>
and never execute flag:=true
.
Why does element_n_value_relationship, element_n_value_relationship ->> 'element_id'
always return null
?
Postgres version: 14
Okay, I fixed it. This is going to seem really stupid, but maybe someone else will fall for it. The pl/pgsql
procedure had nothing to do with it, it turned out that I didn't have a jsonb
object itself coming in, but a jsonb
that contained a single element - a string that contained the object itself.
Excepted jsonb
:
{"element_id": <uuid>, "value": "some value"}
Actual coming jsonb
inside procedure:
'{"element_id": <uuid>, "value": "some value"}'