Hi Hacker,

While reading jsonb related code, I found JsonbContainerTypeName() can be optimized. The function currently checks for the less common scalar container type before checking for objects and arrays.

This patch reorders the checks to prioritize the most common cases. The macros JsonContainerIsArray() and JsonContainerIsObject() are simple bit checks and are now evaluated first. This avoids the overhead of calling the JsonbExtractScalar() function in the vast majority of use cases.

I did the following test:

```

CREATE TABLE test_jsonb_types (
    id SERIAL PRIMARY KEY,
    data JSONB
);


INSERT INTO test_jsonb_types (data) VALUES
('{"name": "Alice", "age": 30}'),
('[1, 2, "three"]'),
('"hello world"'),
('12345'),
('true'),
('null');


evantest=# SELECT id, data, jsonb_typeof(data) AS data_type FROM test_jsonb_types;
 id |             data             | data_type
----+------------------------------+-----------
  1 | {"age": 30, "name": "Alice"} | object
  2 | [1, 2, "three"]              | array
  3 | "hello world"                | string
  4 | 12345                        | number
  5 | true                         | boolean
  6 | null                         | null
(6 rows)

```

Best regards,

--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/
From 1468ca2a0bc8b3769cf5cd3ca56dcb24ba16f1b0 Mon Sep 17 00:00:00 2001
From: "Chao Li (Evan)" <[email protected]>
Date: Tue, 26 Aug 2025 13:14:18 +0800
Subject: [PATCH v1] jsonb: Optimize JsonbContainerTypeName by reordering type
 checks

The JsonbContainerTypeName() function currently checks for the less
common scalar container type before checking for objects and arrays.

This commit reorders the checks to prioritize the most common cases. The
macros JsonContainerIsArray() and JsonContainerIsObject() are
simple bit checks and are now evaluated first. This avoids the
overhead of calling the JsonbExtractScalar() function in the vast
majority of use cases.

Author: Chao Li <[email protected]>
---
 src/backend/utils/adt/jsonb.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/backend/utils/adt/jsonb.c b/src/backend/utils/adt/jsonb.c
index da94d424d61..4da4f8fb45c 100644
--- a/src/backend/utils/adt/jsonb.c
+++ b/src/backend/utils/adt/jsonb.c
@@ -160,12 +160,12 @@ JsonbContainerTypeName(JsonbContainer *jbc)
 {
        JsonbValue      scalar;
 
-       if (JsonbExtractScalar(jbc, &scalar))
-               return JsonbTypeName(&scalar);
-       else if (JsonContainerIsArray(jbc))
-               return "array";
-       else if (JsonContainerIsObject(jbc))
+       if (JsonContainerIsObject(jbc))
                return "object";
+       else if (JsonContainerIsArray(jbc) && !JsonContainerIsScalar(jbc))
+               return "array";
+       else if (JsonbExtractScalar(jbc, &scalar))
+               return JsonbTypeName(&scalar);
        else
        {
                elog(ERROR, "invalid jsonb container type: 0x%08x", 
jbc->header);
-- 
2.39.5 (Apple Git-154)

Reply via email to