Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1tEEBD-00662k-Hu for pgsql-hackers@arkaria.postgresql.org; Thu, 21 Nov 2024 20:53:35 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1tEEBC-001M3i-7q for pgsql-hackers@arkaria.postgresql.org; Thu, 21 Nov 2024 20:53:34 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1tEEBB-001M3V-Px for pgsql-hackers@lists.postgresql.org; Thu, 21 Nov 2024 20:53:33 +0000 Received: from mail-pg1-x542.google.com ([2607:f8b0:4864:20::542]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1tEEB5-0036sg-1m for pgsql-hackers@postgresql.org; Thu, 21 Nov 2024 20:53:32 +0000 Received: by mail-pg1-x542.google.com with SMTP id 41be03b00d2f7-7f43259d220so1123258a12.3 for ; Thu, 21 Nov 2024 12:53:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1732222406; x=1732827206; darn=postgresql.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=ruy/5VEsg36K7ZZH4sbedISIHgpcWIe0+5r+UZpJaPM=; b=kwLlWTvWRnhOkxvlj17csMpqsVr0DoqJdejFtfVc2IuSFW+yBwD7btnDsCxXr2qhL6 NQqznvokXZ0n47I1kXaWd82YGhgn4G704WI4Bs99Gq5jQG9XqHefuW0i7J8rR88JIdan Yh/GEqJ/3pyOCA+LNULkrffH4ZUdEec9L0lfbPWHRoJI7JF5J4qvcpZPJDQX3vh/Zebd dYsd7phQDGu+TUuB0WFCom9IMQSLVLkYOQEEeUfnhQSxdZHmMQoLk6BcCWyXf7J3a82/ QyVG7XTNMO6Bz/Ys2NDAQU1iarm5aEtjjSj92yy8zsX1XCGW+v26Zn2SYZRlAyKNVfVN LqYg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732222406; x=1732827206; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ruy/5VEsg36K7ZZH4sbedISIHgpcWIe0+5r+UZpJaPM=; b=RmQz8UhncCJref05UVeCEbqm2c64m4J5F5/oHHLlrr8CZF9LCjM7MetFoYAQTTV+dz jZxuU26t0jGEtHvvsWsgWV9W1ZnXS/ev6vMRzWw3yGfuCNsHUm/HeDVaoCGnKOvZBp3m 6bd5+1+L6avKVfEn1fv8NJnfKF98xNi4MWQlBCACdil5acDXz7XqsmHOGyUmGCOdKhUG 2YN3Ga091VqTEpMHDy4FOEw/q3ojV57cRHC8XvsqINORN8P5yphHUIQauz1Tajfie3Tv XFBySLtydzb5HFj7Cnd0x/C7K8uP0UfF1gIK5ocfKKRzKMd9irgp9rLIr6A1avkHwZqO ztbg== X-Forwarded-Encrypted: i=1; AJvYcCXi8SFpsY0PvV+YUYiBnnXFVBiojK3apeeyaMPIkuH343p+/NxrswvprRt5FpmcSeW+KR9PgF7IBSEd0ULT@postgresql.org X-Gm-Message-State: AOJu0YxdEwK6R2d8b8yiiyvcG/UwpQcWT7AXHjVN1hA/nPsD+nkvMGD/ fy4E5cbjtqDYl9fS4dWOZoR2yTJEKT0Q61MrSHFC5LDWfoE/KmPbBT1HnWTeSjBEVo3aVSrfShD 5MSF6WStrxD7OT48AmhO1Yt98ims= X-Gm-Gg: ASbGncsWuboFjFhSUvLoAcz1KU8ymBawdeV2xzlaUnHJbkzzdNycWI4hjdP3S7qoMQ3 7Ic5A6qVqgDPlbKPZ1ICUBVN3TBvuvhbm+GacLpdIUl45agQsLpycto3O0kWaX6k= X-Google-Smtp-Source: AGHT+IGDKASI3N4mTAoS6rMLjQHIEZLibXEqqYqLofsDnOk+QFZexx4ybDJgxpZ3vexemmHYEt/RKu7e2wObsCcy3JU= X-Received: by 2002:a05:6a20:244a:b0:1d9:21a0:14e0 with SMTP id adf61e73a8af0-1e09e3f0a42mr510503637.12.1732222405667; Thu, 21 Nov 2024 12:53:25 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Alexandra Wang Date: Thu, 21 Nov 2024 14:52:49 -0600 Message-ID: Subject: Re: SQL:2023 JSON simplified accessor support To: Nikita Glukhov Cc: Peter Eisentraut , PostgreSQL Hackers , Andrew Dunstan , "David E. Wheeler" , jian he Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi, On Tue, Nov 19, 2024 at 6:06=E2=80=AFPM Nikita Glukhov wrote: > > Hi, hackers. > > I have implemented dot notation for jsonb using type subscripting back > in April 2023, but failed post it because I left Postgres Professional > company soon after and have not worked anywhere since, not even had > any interest in programming. > > But yesterday I accidentally decided to look what is going on at > commitfests and found this thread. I immediately started to rebase > code from PG16, fixed some bugs, and now I'm ready to present my > version of the patches which is much more complex. > > Unfortunately, I probably won't be able to devote that much time to > the patches as before. Thank you so much, Nikita, for revisiting this topic and sharing your v6 patches! Now that we have two solutions, I=E2=80=99d like to summarize our current options. In Postgres, there are currently three ways to access json/jsonb object fields and array elements: 1. '->' operator (Postgres-specific, predates SQL standard): postgres=3D# select ('{"a": 1, "b": "c", "d": [1, 2, 3]}'::json) -> 'd' -> 0; -- returns 1 2. jsonb subscripting (not available for the plain json type): postgres=3D# select ('{"a": 1, "b": "c", "d": [1, 2, 3]}'::jsonb)['d'][0]; --returns 1 3. json_query() function: postgres=3D# select json_query(jsonb '{"a": 1, "b": "c", "d": [1, 2, 3]}', 'lax $.d[0]'); --returns 1 A few weeks ago, I did the following performance benchmarking of the three approaches: -- setup: create table tbl(id int, col1 jsonb); insert into tbl select i, '{"x":"vx", "y":[{"a":[1,2,3]}, {"b":[1, 2, {"j":"vj"}]}]}' from generate_series(1, 100000)i; -- jsonb_operator.sql SELECT id, col1 -> 'y' -> 1 -> 'b' -> 2 -> 'j' AS jsonb_operator FROM tbl; -- jsonb_subscripting.sql SELECT id, col1['y'][1]['b'][2]['j'] AS jsonb_subscript FROM tbl; -- jsonb_path_query.sql SELECT id, jsonb_path_query(col1, '$.y[1].b[2].j') FROM tbl; # pgbench on my local MacOS machine, using -O3 optimization: pgbench -n -f XXX.sql postgres -T100 Results (Latency | tps): "->" operator: 14ms | 68 jsonb subscripting: 17ms | 58 jsonb_path_query() function: 23ms | 43 So performance from best to worst: "->" operator > jsonb subscripting >> jsonb_path_query() function. I=E2=80=99m excited to see your implementation of dot notation for jsonb us= ing type subscripting! This approach rounds out the three possible ways to implement JSON simplified accessors: ## v1: json_query() implementation Pros: - Fully adheres to the SQL standard. According to the SQL standard, if the JSON simplified accessor is not a JSON item method, it is equivalent to a : JSON_QUERY ( VEP, 'lax $.JC' WITH CONDITIONAL ARRAY WRAPPER NULL ON EMPTY NULL ON ERROR) (I=E2=80=99m skipping that includes a JSON item method, as it is currently outside the scope of both sets of patches.) - Easiest to implement Cons: - Slow due to function call overhead. ## v2-v5: "->" operator implementation We initially chose this approach for its performance benefits. However, while addressing Peter=E2=80=99s feedback on v5, I encountered the following issue: -- setup create table test_json_dot(id serial primary key, test_json json); insert into test_json_dot values (5, '[{"a": 1, "b": 42}, {"a": 2, "b": {"c": 42}}]'); -- problematic query: test1=3D# select id, (test_json).b, json_query(test_json, 'lax $.b' WITH CONDITIONAL WRAPPER NULL ON EMPTY NULL ON ERROR) as expected from test_json_dot; id | b | expected ----+---+----------------- 5 | | [42, {"c": 42}] (1 row) This issue arises from the semantic differences between the "->" operator and json_query=E2=80=99s "lax" mode. One possible workaround is to redefine the "->" operator and modify its implementation. However, since the "->" operator has been in use for a long time, such changes would break backward compatibility. ## v6: jsonb subscription implementation Nikita's patches pass all my functional test cases, including those that failed with the previous approach. Supported formats: - JSON member accessor - JSON wildcard member accessor (Not available in v5, so this is also a plu= s) - JSON array accessor Questions: 1. Since Nikita=E2=80=99s patches did not address the JSON data type, and J= SON currently does not support subscripting, should we limit the initial feature set to JSONB dot-notation for now? In other words, if we aim to fully support JSON simplified accessors for the plain JSON type, should we handle support for plain JSON subscripting as a follow-up effort? 2. I have yet to have a more thorough review of Nikita=E2=80=99s patches. One area I am not familiar with is the hstore-related changes. How relevant is hstore to the JSON simplified accessor? Best, Alex