3

There does not seem to be an obvious way:

  • select 'a123'::text::jsonb = ERROR: invalid input syntax for type json
  • select '"a123"'::text::jsonb = BAD string because quoted
    check select '"a123"'::text::jsonb = ('{"x":"a123"}'::jsonb)->'x'
    to see that non-quoted is the correct.
  • select '123'::text::jsonb = ('{"x":123}'::jsonb)->'x'; = NOT string

I need '123' and 'a123' as pure JSONb strings.


PS: it is not a duplicate of generic automatic-anything conversion.

1
  • What do you want to achieve? The quoted version is THE valid jsonb string. IMHO there's no other un-quotated representation. Commented Nov 23, 2020 at 19:33

1 Answer 1

5

To convert untyped string literals, that are not wrapped in double-quotes to jsonb (or json), use the to_jsonb() (or to_json()) function:

SELECT to_jsonb(text 'a123');

Note that the input has to be a string type (text, varchar, ...), not an untyped literal. That's how Postgres knows you want a JSON string.

The above text 'a123' is one way to cast an untyped literal. There are others:

For a direct cast to json(b), Postgres expects valid JSON literals (with double-quoted strings):

SELECT '"a123"'::jsonb;  

To translate each value to a specific JSON primitive, you can cast conditionally before the conversion. Example:

SELECT p, CASE WHEN i>2 THEN to_jsonb(p::numeric) ELSE to_jsonb(p) END AS x
FROM   unnest('{ab,12,12,1.2}'::text[]) WITH ORDINALITY t(p,i);

select '"a123"'::text::jsonb = BAD string because quoted

To be precise, the result is not a string, but a jsonb value containing a JSON string. To get the string as Postgres data type text, you need the ->> operator:

select 'a123'::text  = ('{"x":"a123"}'::jsonb)->>'x'

Or (comparing JSON values):

select '"a123"'::jsonb = ('{"x":"a123"}'::jsonb)->'x';

I need '123' and 'a123' as pure JSONb strings.

So:

SELECT '"123"'::jsonb, '"a123"'::jsonb;

Both contain JSON strings.

This also works:

SELECT '123'::jsonb;

.. but contains a JSON numeric.

But this does not work:

SELECT 'a123'::jsonb;  -- error

.. because it's not a valid numeric literal.

The manual has a table of mappings between JSON Primitive Types and Corresponding PostgreSQL Types

Sign up to request clarification or add additional context in comments.

8 Comments

Hum... But the question is about "jsonB-string", not "how to cast to SQL-text"
I need to input SQL-strings and preserve it into the database as correct JSONb types... I need to say to PostgreSQL: plese a 123 is JSONb string, plese a a123 is JSONb string, etc.
jsonb strings (or json for that matter) are represented as double-quoted string literals. Other JSON primitives work without double quotes: null, boolean and numeric.
Ok, but how to input it? select '"a123"'::text::jsonb = ('{"x":"a123"}'::jsonb)->'x' is false, I need to input into database a non-quoted string.
Ah, that's the missing bit. I added the solution at the top.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.