13

I ran into strange situation working with jsonb type.

Expected behavior


Using short jsonb structure:

{"price": 99.99}

I wrote query like this:

 SELECT * FROM table t WHERE t.data->price > 90.90

And it fail with error operator does not exist: jsonb > numeric the same as text (->>) operator does not exist: text > numeric

Then I wrote comparison as mentioned in many resources:

SELECT * FROM table t WHERE (t.data->>price)::NUMERIC > 90.90

And it's works as expected.

What's strange:


SELECT * FROM table t WHERE t.data->price > '90.90';

a little weird but query above works right.

EXPLAIN: Filter: ((data -> 'price'::text) > '90.90'::jsonb)

But if I change jsonb value to text as: {"price": "99.99"} there is no result any more - empty.

Question: How actually PostgreSQL compare numeric data and what preferable way to do this kind of comparison.

1
  • -> returns a JSON value, not a number Commented Dec 19, 2018 at 8:03

1 Answer 1

19

But you aren't comparing numeric data, are you.

I can see that you think price contains a number, but it doesn't. It contains a JSON value. That might be a number, or it might be text, or an array, or an object, or an object containing arrays of objects containing...

You might say "but the key is called 'price' of course it is a number" but that's no use to PostgreSQL, particularly if I come along and sneakily insert an object containing arrays of objects containing...1

So - if you want a number to compare to you need convert it to a number (t.data->>price)::NUMERIC or convert your target value to JSON and let PostgreSQL do a JSON-based comparison (which might do what you want, it might not - I don't know what the exact rules are for JSON).


1 And that's exactly the sort of thing I would do, even though it is Christmas. I'm a bad person.

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

3 Comments

No doubt operator -> return jsonb value and ->> return text. The question was way jsonb and text are comparable and other types not, for example ( jsonb and numeric throw error). But any way, I got you idea, Thanks.
If you ever want to check the type of something there is a handy system function pg_typeof(<expression>)
Thanks for the answer I've been searching everywhere.

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.