Append a value to json array - sql

I have a postgresql table profile with columns (username, friends). username is a string and friends is a json type and has the current values ["Mary", "Bob]. I want to append an item at the end of the array so it is ["Mary", "Bob", "Alice"]
I am currently have tried:
UPDATE profile SET friends = friends || '["Alice"]'::jsonb WHERE username = 'David';
This yields the error:
[ERROR] 23:56:23 error: operator does not exist: json || jsonb
I tried changing the first expression to include json instead of jsonb but I then got the error:
[ERROR] 00:06:25 error: operator does not exist: json || json
Other answers seem to suggesst the || operator is indeed a thing, e.g.:
Appending (pushing) and removing from a JSON array in PostgreSQL 9.5+
How do I append an item to the end of a json array?

The data type json is much more limited than jsonb. Use jsonb instead of json and the solution you found simply works.
While stuck with json, a possible workaround is to cast to jsonb and back:
UPDATE profile
SET friends = (friends::jsonb || '["Alice"]')::json
WHERE username = 'David';
You might use an explicit type for jsonb '["Alice"]', too, but that's optional. While the expression is unambiguous like that, the untyped string literal will be coerced to jsonb automatically. If you instead provide a typed value in place of '["Alice"]', the explicit cast may be required.
If friends can be NULL, you'll want to define what should happen then. Currently, nothing happens. Or, to be precise, an update that doesn't change the NULL value.
Then again, if you only have simple arrays of strings, consider the plain Postgres array type text[] instead.

Related

How to expand this dynamic column with only 1 value

This Id column is dynamic type, but only holds 1 value (f3019...). I want to get rid of the array so it only has the field value.
When I try mv-expand Id it doesn't do anything
Also the current query is like:
Id = Target.Properties[0].value
When I try
Id = Target.Properties[0].value[0]
Id returns a blank
The dynamic types can hold arrays and dictionaries, but also scalar types.
The fact that Target.Properties[0].value does not behave like an array indicates that it is not an array, but a string.
The representation of it as an array in the GUI relates to the serving lair and not the way it is actually stored.
Use tostring(parse_json(tostring(Target.Properties[0].value))[0]).
Every element within a dynamic field is also of dynamic type.
When running on a dynamic element, parse_json() returns the element As Is.
If we want the element to get parsed, we first need to convert it to string, using tostring().
parse_json() which is used to parse the string, returns an array (which is a dynamic element).
The first (and only) element of the array is also of a dynamic type.
We use an additional tostring() to convert it to string.
Demo
print value = dynamic('["Hello"]')
| extend value[0] // Null because it's not really an array
| extend result = tostring(parse_json(tostring(value))[0])
value
value_0
result
["Hello"]
Hello
Fiddle
Misleading representation in Azure Monitor:

operator does not exist: text ->> unknown

I am trying to take info from my json field, which is created using c#, enter image description here
SELECT "Price"->>'TotalPrice' FROM "Table"
but I have error in postgres
ERROR: operator does not exist: text ->> unknown LINE 1: SELECT
"Price"->>'Price' FROM "ReadModel"... No operator
matches the given name and argument types. You might need to add
explicit type casts.
The error message is pretty obvious: your column is defined as text not as jsonb or json. But the ->> operator only works with a jsonb or json column, so you will need to cast it:
SELECT "Price"::jsonb ->> 'TotalPrice'
FROM "ReadModel"."MyListingDto"
Unrelated to your problem, but: you should really avoid those dreaded quoted identifiers. They are much more trouble than they are worth it.

How do I insert/escape a regex string to store in jsonb column?

I am using Postgres DB and I have a JSONB column. I am trying to insert a json node, which contains a regex , just for storage purposes.
here is the regex string (email validator):
^[A-Z0-9_!#$%&'*+/=?`{|}~^-]+(?:\.[A-Z0-9_!#$%&'*+/=?`{|}~^-]+↵)*#[A-Z0-9-]+(?:\.[A-Z0-9-]+)*$
I am trying to insert this like so
{
"title": "Testing",
"myregex": "^[A-Z0-9_!#$%&'*+/=?`{|}~^-]+(?:\.[A-Z0-9_!#$%&'*+/=?`{|}~^-]+↵)*#[A-Z0-9-]+(?:\.[A-
Z0-9-]+)*$"
}
However, it keeps throwing error. How can I escape or otherwise get this regex string stored in jsonb?
I don't know that the string you are asking us to escape for your has already been escaped properly for this medium, so what I see as the string might not be what you want. When I copied it from my screen, I got in the middle of it some weird carriage-return like thing or something else non-ASCII, which I removed.
Assuming you got the string into PostgreSQL accurately in the first place as text (for which I use dollar quoting), then the to_jsonb function will convert it into properly escaped JSON
select to_jsonb($JJ$^[A-Z0-9_!#$%&'*+/=?`{|}~^-]+(?:\.[A-Z0-9_!#$%&'*+/=?`{|}~^-]+)*#[A-Z0-9-]+(?:\.[A-Z0-9-]+)*$$JJ$::text);
to_jsonb
---------------------------------------------------------------------------------------------------
"^[A-Z0-9_!#$%&'*+/=?`{|}~^-]+(?:\\.[A-Z0-9_!#$%&'*+/=?`{|}~^-]+)*#[A-Z0-9-]+(?:\\.[A-Z0-9-]+)*$"
Now I don't know if what you see is what I intended you to see, because I might need to escape the escaping of the escapement, which might have been de-escaped incorrectly in the first place. But the general principle should still apply.
Looking in your keywords, seems to be that you want to insert directly via pgadmin. So, PostgreSQL have native JSON format support, I did an example in how to use this:
To show how you can store json objects, follows a dummy table:
$ CREATE TABLE test (id INT, data JSON, datab JSONB);
CREATE TABLE
Trying to check your string on the fly, on basic way. I'm saying to PostgreSQL to convert the string in json and access the 'title' property:
test=# SELECT '{"title": "Testing"}'::json->'title';
?column?
-----------
"Testing"
(1 row)
Now, trying with your json (with some adjustments) - The backslash \ and quote ' are escaped here:
test=# SELECT '{"title": "Testing","myregex": "^[A-Z0-9_!#$%&''*+/=?`{|}~^-]+(?:\\.[A-Z0-9_!#$%&''*+/=?`{|}~^-]+↵)*#[A-Z0-9-]+(?:\\.[A-Z0-9-]+)*$"}'::json->'myregex'
?column?
----------------------------------------------------------------------------------------------------
"^[A-Z0-9_!#$%&'*+/=?`{|}~^-]+(?:\\.[A-Z0-9_!#$%&'*+/=?`{|}~^-]+↵)*#[A-Z0-9-]+(?:\\.[A-Z0-9-]+)*$"
(1 row)
So, to save, simply do the json conversion with escape strings:
test=# INSERT INTO test VALUES (1, '{"title": "Testing","myregex": "^[A-Z0-9_!#$%&''*+/=?`{|}~^-]+(?:\\.[A-Z0-9_!#$%&''*+/=?`{|}~^-]+↵)*#[A-Z0-9-]+(?:\\.[A-Z0-9-]+)*$"}'::json);
INSERT 1
And, we're done.

Postgres: How to store bytea as value in hstore?

I am trying to store a bytea as a value in hstore and I keep getting the following error:
function hstore(unknown, bytea) does not exist
Here is what I have tried:
UPDATE users set store = store || hstore('key1', pgp_pub_encrypt('testval',dearmor('xxxx')));
am trying to store a bytea as a value in hstore
You cannot safely store bytea in hstore without some kind of encoding, because hstore is stored as text in the current text encoding, but bytea has no text encoding and may also contain null bytes that are not legal in text strings.
So you need to encode the bytea as hex, base64, or some other form that makes it into valid text in the current encoding.
The simplest way is to cast it to text, but I recommend instead using encode and decode to/from base64. This encoding is more compact than the text or hex encodings used for bytea's text representation in PostgreSQL, and it's also independent of the value of the bytea_output setting.
e.g.
UPDATE users
SET store = store
|| hstore('key1', encode( pgp_pub_encrypt('testval',dearmor('xxxx'))), 'base64')
WHERE ... ;
There are two variants of the hstore() function taking arrays, one taking a row / record and one taking two text values. The last one is for you:
SELECT hstore('foo','abc'::bytea::text); -- cast bytea to text!
Your attempt failed the rules of function type resolution because there is no explicit cast registered from bytea to text. Postgres falls back to input / output conversion for that, which does not count for function type resolution:
Is there a way to disable function overloading in Postgres
So:
UPDATE users
SET store = store
|| hstore('key1', pgp_pub_encrypt('testval',dearmor('xxxx'))::text)
WHERE ... ;

postgresql to_json() function escapes all doublequote characters

I've written a plpgsql script which generates an array of json objects in a string but after I use to_json() method passing a variable with that string to it, it returns a result which is doublequoted and also every doublequote character is escaped. But I need that string as is.
initial content of jsonResult variable is:
[{"key":{04949429911,"Code":"400"},"value":"20000.00"},{"key":{"InsuranceNumber":"04949429911","Code":"403"},"value":"10000.00"},...]
but after to_json() it looks like this:
"[{\"key\":{04949429911,\"Code\":\"400\"},\"value\":\"20000.00\"},{\"key\":{\"InsuranceNumber\":\"04949429911\",\"Code\":\"403\"},\"value\":\"10000.00\"}...]"
This is the place where everything stored in jsonResult breakes:
UPDATE factor_value SET params = to_json(jsonResult) WHERE id = _id;
What am I doing wrong?
This answer points out that simply casting to json should suffice:
UPDATE factor_value SET params = jsonResult::json WHERE id = _id;
The weird escaping you see is probably due to postgresql not realizing you already have valid JSON and your varchar is just converted to a plain javascript/JSON string.
I needed to convert a bytea column to jsonb and I ended up with escaped characters when using to_json. I also used bytea_data_column::jsonb and postgres said cannot cast to jsonb. Here is how I worked around it:
bytea_data_column::text::jsonb