Skip to content

Instantly share code, notes, and snippets.

@icot
Created April 7, 2016 16:20
Show Gist options
  • Save icot/f058c7b9144f8d530397ada875f804e8 to your computer and use it in GitHub Desktop.
Save icot/f058c7b9144f8d530397ada875f804e8 to your computer and use it in GitHub Desktop.
Stored procedure for updating a JSON object in PG
-- https://stackoverflow.com/questions/18209625/how-do-i-modify-fields-inside-the-new-postgresql-json-datatype
-- Works as upsert (creates the key if it doesn't exist)
CREATE OR REPLACE FUNCTION "json_object_set_keys"(
"json" json,
"keys_to_set" TEXT[],
"values_to_set" anyarray
)
RETURNS json
LANGUAGE sql
IMMUTABLE
STRICT
AS $function$
SELECT concat('{', string_agg(to_json("key") || ':' || "value", ','), '}')::json
FROM (SELECT *
FROM json_each("json")
WHERE "key" <> ALL ("keys_to_set")
UNION ALL
SELECT DISTINCT ON ("keys_to_set"["index"])
"keys_to_set"["index"],
CASE
WHEN "values_to_set"["index"] IS NULL THEN 'null'::json
ELSE to_json("values_to_set"["index"])
END
FROM generate_subscripts("keys_to_set", 1) AS "keys"("index")
JOIN generate_subscripts("values_to_set", 1) AS "values"("index")
USING ("index")) AS "fields"
$function$;
dbod> update metadata
set data =
(select json_object_set_key(data, 'subcategory', 'MySQL'::text)
from metadata where db_name = 'funmysql')
where db_name = 'funmysql';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment