<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.memcp.org/index.php?action=history&amp;feed=atom&amp;title=JSON</id>
	<title>JSON - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://www.memcp.org/index.php?action=history&amp;feed=atom&amp;title=JSON"/>
	<link rel="alternate" type="text/html" href="https://www.memcp.org/index.php?title=JSON&amp;action=history"/>
	<updated>2026-08-27T04:26:25Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.1</generator>
	<entry>
		<id>https://www.memcp.org/index.php?title=JSON&amp;diff=273&amp;oldid=prev</id>
		<title>Carli: Created page with &quot;= JSON and SQL/JSON in MemCP =  &#039;&#039;&#039;MemCP provides native JSON and SQL/JSON support on its high-performance columnar SQL engine.&#039;&#039;&#039; JSON documents can be filtered, joined, grouped, sorted, modified and assembled into deeply nested application responses without leaving SQL.  The same JSON engine is exposed through both MemCP SQL dialects: applications get MySQL/MariaDB-compatible JSON functions such as &lt;code&gt;JSON_EXTRACT&lt;/code&gt;, &lt;code&gt;JSON_VALUE&lt;/code&gt;, &lt;code&gt;JSON_OBJECT&lt;/...&quot;</title>
		<link rel="alternate" type="text/html" href="https://www.memcp.org/index.php?title=JSON&amp;diff=273&amp;oldid=prev"/>
		<updated>2026-08-26T07:22:04Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;= JSON and SQL/JSON in MemCP =  &amp;#039;&amp;#039;&amp;#039;MemCP provides native JSON and SQL/JSON support on its high-performance columnar SQL engine.&amp;#039;&amp;#039;&amp;#039; JSON documents can be filtered, joined, grouped, sorted, modified and assembled into deeply nested application responses without leaving SQL.  The same JSON engine is exposed through both MemCP SQL dialects: applications get MySQL/MariaDB-compatible JSON functions such as &amp;lt;code&amp;gt;JSON_EXTRACT&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_VALUE&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_OBJECT&amp;lt;/...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= JSON and SQL/JSON in MemCP =&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;MemCP provides native JSON and SQL/JSON support on its high-performance columnar SQL engine.&amp;#039;&amp;#039;&amp;#039; JSON documents can be filtered, joined, grouped, sorted, modified and assembled into deeply nested application responses without leaving SQL.&lt;br /&gt;
&lt;br /&gt;
The same JSON engine is exposed through both MemCP SQL dialects: applications get MySQL/MariaDB-compatible JSON functions such as &amp;lt;code&amp;gt;JSON_EXTRACT&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_VALUE&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_OBJECT&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_ARRAYAGG&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;JSON_TABLE&amp;lt;/code&amp;gt;, as well as PostgreSQL-compatible &amp;lt;code&amp;gt;json&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;jsonb&amp;lt;/code&amp;gt; operators, constructors, aggregates and JSONPath functions. This makes it possible to migrate JSON-heavy SQL queries or run MemCP beside an existing MySQL or PostgreSQL application. See [[Migration from MySQL and PostgreSQL]] for connection options and [[Supported SQL]] for the wider SQL feature set.&lt;br /&gt;
&lt;br /&gt;
JSON columns validate incoming documents and convert them to MemCP&amp;#039;s native tagged BSON value. Objects and arrays therefore remain structured while they are filtered, joined, sorted or aggregated; they are serialized to JSON only at the SQL/API boundary.&lt;br /&gt;
&lt;br /&gt;
JSON functions also accept ordinary character strings containing JSON. Such strings are parsed when the function needs a JSON value. Use a &amp;lt;code&amp;gt;JSON&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;JSONB&amp;lt;/code&amp;gt; column for repeatedly queried documents so that parsing happens on write instead of on every read.&lt;br /&gt;
&lt;br /&gt;
== MemCP compared with MySQL JSON, MariaDB JSON and PostgreSQL JSONB ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! SQL dialect&lt;br /&gt;
! Familiar JSON syntax in MemCP&lt;br /&gt;
! Internal representation in MemCP&lt;br /&gt;
! Typical use&lt;br /&gt;
|-&lt;br /&gt;
| MySQL&lt;br /&gt;
| &amp;lt;code&amp;gt;JSON_EXTRACT&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_VALUE&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-&amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-&amp;gt;&amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_TABLE&amp;lt;/code&amp;gt;&lt;br /&gt;
| Native immutable BSON&lt;br /&gt;
| Existing MySQL applications and document columns&lt;br /&gt;
|-&lt;br /&gt;
| MariaDB&lt;br /&gt;
| MySQL-style JSON functions and JSONPath&lt;br /&gt;
| Native immutable BSON instead of LONGTEXT&lt;br /&gt;
| MariaDB-compatible SQL and mixed relational/document workloads&lt;br /&gt;
|-&lt;br /&gt;
| PostgreSQL&lt;br /&gt;
| &amp;lt;code&amp;gt;json&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;jsonb&amp;lt;/code&amp;gt; casts, operators, JSONPath and set-returning functions&lt;br /&gt;
| One native BSON representation for both &amp;lt;code&amp;gt;json&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;jsonb&amp;lt;/code&amp;gt;&lt;br /&gt;
| PostgreSQL JSONB queries, containment and relational projection&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Unlike a database that reparses a text document for every JSON expression, a declared MemCP &amp;lt;code&amp;gt;JSON&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;JSONB&amp;lt;/code&amp;gt; column is converted when it is written. Frequently used paths can participate in deterministic computed expressions and computed indexes.&lt;br /&gt;
&lt;br /&gt;
== Quick start ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CREATE TABLE events (&lt;br /&gt;
	id INT PRIMARY KEY,&lt;br /&gt;
	category VARCHAR(40),&lt;br /&gt;
	payload JSON,&lt;br /&gt;
	created_at DATETIME&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
INSERT INTO events VALUES&lt;br /&gt;
	(1, &amp;#039;customer&amp;#039;, &amp;#039;{&amp;quot;customer&amp;quot;:{&amp;quot;name&amp;quot;:&amp;quot;Ada&amp;quot;,&amp;quot;rank&amp;quot;:2},&amp;quot;tags&amp;quot;:[&amp;quot;sql&amp;quot;,&amp;quot;go&amp;quot;]}&amp;#039;, NOW());&lt;br /&gt;
&lt;br /&gt;
SELECT&lt;br /&gt;
	id,&lt;br /&gt;
	JSON_VALUE(payload, &amp;#039;$.customer.name&amp;#039;) AS customer,&lt;br /&gt;
	JSON_EXTRACT(payload, &amp;#039;$.customer.rank&amp;#039;) + 1 AS next_rank&lt;br /&gt;
FROM events&lt;br /&gt;
WHERE JSON_CONTAINS(payload, &amp;#039;&amp;quot;sql&amp;quot;&amp;#039;, &amp;#039;$.tags&amp;#039;)&lt;br /&gt;
ORDER BY JSON_VALUE(payload, &amp;#039;$.customer.rank&amp;#039; RETURNING SIGNED);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
JSON scalars participate in normal SQL coercion. A numeric result of &amp;lt;code&amp;gt;JSON_EXTRACT&amp;lt;/code&amp;gt;, for example, can be added, compared and sorted numerically. &amp;lt;code&amp;gt;NULL&amp;lt;/code&amp;gt; in SQL and the JSON literal &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt; remain distinct where the selected dialect distinguishes them.&lt;br /&gt;
&lt;br /&gt;
== Common MySQL JSON and SQL JSON queries ==&lt;br /&gt;
&lt;br /&gt;
=== Extract a value from JSON in SQL ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SELECT JSON_EXTRACT(payload, &amp;#039;$.customer.rank&amp;#039;) AS rank&lt;br /&gt;
FROM events;&lt;br /&gt;
&lt;br /&gt;
SELECT payload-&amp;gt;&amp;gt;&amp;#039;$.customer.name&amp;#039; AS customer_name&lt;br /&gt;
FROM events;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Filter SQL rows by a JSON attribute ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SELECT id&lt;br /&gt;
FROM events&lt;br /&gt;
WHERE JSON_VALUE(payload, &amp;#039;$.customer.name&amp;#039;) = &amp;#039;Ada&amp;#039;&lt;br /&gt;
	AND JSON_CONTAINS(payload, &amp;#039;&amp;quot;sql&amp;quot;&amp;#039;, &amp;#039;$.tags&amp;#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Order SQL results by a JSON value ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SELECT id, payload&lt;br /&gt;
FROM events&lt;br /&gt;
ORDER BY JSON_VALUE(payload, &amp;#039;$.customer.rank&amp;#039; RETURNING SIGNED), id;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The numeric &amp;lt;code&amp;gt;RETURNING&amp;lt;/code&amp;gt; type prevents lexical ordering such as &amp;lt;code&amp;gt;1, 10, 2&amp;lt;/code&amp;gt;. Eligible deterministic path expressions can be backed by a computed index.&lt;br /&gt;
&lt;br /&gt;
=== Aggregate SQL rows into a JSON array ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SELECT category, JSON_ARRAYAGG(&lt;br /&gt;
	JSON_OBJECT(&amp;#039;id&amp;#039;, id, &amp;#039;payload&amp;#039;, payload)&lt;br /&gt;
) AS documents&lt;br /&gt;
FROM events&lt;br /&gt;
GROUP BY category;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Convert a JSON array into SQL rows ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SELECT item.ord, item.name&lt;br /&gt;
FROM JSON_TABLE(&lt;br /&gt;
	&amp;#039;[{&amp;quot;name&amp;quot;:&amp;quot;Ada&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;Bob&amp;quot;}]&amp;#039;,&lt;br /&gt;
	&amp;#039;$[*]&amp;#039; COLUMNS (&lt;br /&gt;
		ord FOR ORDINALITY,&lt;br /&gt;
		name TEXT PATH &amp;#039;$.name&amp;#039;&lt;br /&gt;
	)&lt;br /&gt;
) AS item;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MySQL and MariaDB syntax ==&lt;br /&gt;
&lt;br /&gt;
MemCP implements the following MySQL/MariaDB-style JSON surface:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Area&lt;br /&gt;
! Functions and operators&lt;br /&gt;
|-&lt;br /&gt;
| Construction and aggregation&lt;br /&gt;
| &amp;lt;code&amp;gt;JSON_ARRAY&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_OBJECT&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_ARRAYAGG&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_OBJECTAGG&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Inspection and extraction&lt;br /&gt;
| &amp;lt;code&amp;gt;JSON_EXTRACT&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_VALUE&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_KEYS&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_LENGTH&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_DEPTH&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_TYPE&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_VALID&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-&amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-&amp;gt;&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Search and comparison&lt;br /&gt;
| &amp;lt;code&amp;gt;JSON_CONTAINS&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_CONTAINS_PATH&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_OVERLAPS&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_SEARCH&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;MEMBER OF&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Modification&lt;br /&gt;
| &amp;lt;code&amp;gt;JSON_SET&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_INSERT&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_REPLACE&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_REMOVE&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_ARRAY_APPEND&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_ARRAY_INSERT&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_MERGE_PATCH&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_MERGE_PRESERVE&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_MERGE&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Conversion and formatting&lt;br /&gt;
| &amp;lt;code&amp;gt;JSON_QUOTE&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_UNQUOTE&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_PRETTY&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_STORAGE_SIZE&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_STORAGE_FREE&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Validation&lt;br /&gt;
| &amp;lt;code&amp;gt;JSON_SCHEMA_VALID&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_SCHEMA_VALIDATION_REPORT&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Relational projection&lt;br /&gt;
| &amp;lt;code&amp;gt;JSON_TABLE&amp;lt;/code&amp;gt;, including path columns and &amp;lt;code&amp;gt;FOR ORDINALITY&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Paths start at &amp;lt;code&amp;gt;$&amp;lt;/code&amp;gt;. Object members, zero-based array indexes, wildcards, recursive descent and &amp;lt;code&amp;gt;last&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;last-N&amp;lt;/code&amp;gt; array indexes are supported.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SELECT JSON_EXTRACT(&lt;br /&gt;
	&amp;#039;{&amp;quot;orders&amp;quot;:[{&amp;quot;total&amp;quot;:10},{&amp;quot;total&amp;quot;:25}]}&amp;#039;,&lt;br /&gt;
	&amp;#039;$.orders[last].total&amp;#039;&lt;br /&gt;
); -- 25&lt;br /&gt;
&lt;br /&gt;
SELECT *&lt;br /&gt;
FROM JSON_TABLE(&lt;br /&gt;
	&amp;#039;[{&amp;quot;name&amp;quot;:&amp;quot;Ada&amp;quot;},{&amp;quot;name&amp;quot;:&amp;quot;Bob&amp;quot;}]&amp;#039;,&lt;br /&gt;
	&amp;#039;$[*]&amp;#039; COLUMNS (&lt;br /&gt;
		ord FOR ORDINALITY,&lt;br /&gt;
		name TEXT PATH &amp;#039;$.name&amp;#039;&lt;br /&gt;
	)&lt;br /&gt;
) AS people;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The upstream references are MariaDB&amp;#039;s [https://mariadb.com/docs/server/reference/sql-functions/special-functions/json-functions JSON functions index] and [https://mariadb.com/docs/server/reference/sql-functions/special-functions/json-functions/jsonpath-expressions JSONPath reference]. MariaDB adds functions over time; the table above is the supported MemCP surface, not a claim that every function in every MariaDB release is available.&lt;br /&gt;
&lt;br /&gt;
== PostgreSQL syntax ==&lt;br /&gt;
&lt;br /&gt;
The PostgreSQL-compatible parser accepts both &amp;lt;code&amp;gt;json&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;jsonb&amp;lt;/code&amp;gt; casts and column declarations. Internally both use the same native BSON representation.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Area&lt;br /&gt;
! Functions and operators&lt;br /&gt;
|-&lt;br /&gt;
| Extraction&lt;br /&gt;
| &amp;lt;code&amp;gt;-&amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-&amp;gt;&amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;#&amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;#&amp;gt;&amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;json_extract_path&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;jsonb_extract_path&amp;lt;/code&amp;gt;, and their &amp;lt;code&amp;gt;_text&amp;lt;/code&amp;gt; variants&lt;br /&gt;
|-&lt;br /&gt;
| jsonb operators&lt;br /&gt;
| &amp;lt;code&amp;gt;@&amp;gt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;lt;@&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;?&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;?|&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;?&amp;amp;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;||&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;-&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;#-&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;@?&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;@@&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Construction and conversion&lt;br /&gt;
| &amp;lt;code&amp;gt;json&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;to_json&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;to_jsonb&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;array_to_json&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;row_to_json&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;json_build_array&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;jsonb_build_array&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;json_build_object&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;jsonb_build_object&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;json_object&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;jsonb_object&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;json_scalar&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;json_serialize&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Inspection and modification&lt;br /&gt;
| &amp;lt;code&amp;gt;json_array_length&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;jsonb_array_length&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;json_typeof&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;jsonb_typeof&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;jsonb_set&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;jsonb_set_lax&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;jsonb_insert&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;json_strip_nulls&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;jsonb_strip_nulls&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;jsonb_pretty&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Set-returning functions&lt;br /&gt;
| &amp;lt;code&amp;gt;json[b]_array_elements[_text]&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;json[b]_each[_text]&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;json[b]_object_keys&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;json[b]_populate_record[set]&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;jsonb_populate_record_valid&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;json[b]_to_record[set]&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| JSONPath&lt;br /&gt;
| &amp;lt;code&amp;gt;jsonb_path_exists&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;jsonb_path_match&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;jsonb_path_query&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;jsonb_path_query_array&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;jsonb_path_query_first&amp;lt;/code&amp;gt;, plus their &amp;lt;code&amp;gt;_tz&amp;lt;/code&amp;gt; variants&lt;br /&gt;
|-&lt;br /&gt;
| Aggregation&lt;br /&gt;
| &amp;lt;code&amp;gt;json_agg&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;jsonb_agg&amp;lt;/code&amp;gt;, strict variants, &amp;lt;code&amp;gt;json_object_agg&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;jsonb_object_agg&amp;lt;/code&amp;gt; and their &amp;lt;code&amp;gt;_strict&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;_unique&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;_unique_strict&amp;lt;/code&amp;gt; variants&lt;br /&gt;
|-&lt;br /&gt;
| SQL/JSON&lt;br /&gt;
| &amp;lt;code&amp;gt;JSON_ARRAY&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_OBJECT&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_ARRAYAGG&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_OBJECTAGG&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_EXISTS&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_QUERY&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_VALUE&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;JSON_TABLE&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SELECT&lt;br /&gt;
	payload-&amp;gt;&amp;#039;customer&amp;#039;-&amp;gt;&amp;gt;&amp;#039;name&amp;#039; AS name,&lt;br /&gt;
	payload @&amp;gt; &amp;#039;{&amp;quot;tags&amp;quot;:[&amp;quot;sql&amp;quot;]}&amp;#039;::jsonb AS has_sql&lt;br /&gt;
FROM events&lt;br /&gt;
ORDER BY payload-&amp;gt;&amp;#039;customer&amp;#039;-&amp;gt;&amp;#039;rank&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
SELECT jsonb_path_query_array(&lt;br /&gt;
	&amp;#039;{&amp;quot;values&amp;quot;:[1,2,3,4]}&amp;#039;::jsonb,&lt;br /&gt;
	&amp;#039;$.values[*] ? (@ &amp;gt; 2)&amp;#039;&lt;br /&gt;
); -- [3,4]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
See PostgreSQL&amp;#039;s official [https://www.postgresql.org/docs/current/functions-json.html JSON functions and operators] and [https://www.postgresql.org/docs/current/functions-aggregate.html aggregate functions] documentation for the source syntax and semantics. The tables above identify the forms currently accepted by MemCP.&lt;br /&gt;
&lt;br /&gt;
== Building nested application documents ==&lt;br /&gt;
&lt;br /&gt;
JSON constructors and aggregates compose with correlated subqueries. This allows a relational schema to emit complete API documents, including arrays nested several levels deep:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
SELECT JSON_OBJECT(&lt;br /&gt;
	&amp;#039;id&amp;#039;, delivery_note.id,&lt;br /&gt;
	&amp;#039;number&amp;#039;, delivery_note.note_number,&lt;br /&gt;
	&amp;#039;date&amp;#039;, delivery_note.delivery_date,&lt;br /&gt;
	&amp;#039;items&amp;#039;, (&lt;br /&gt;
		SELECT JSON_ARRAYAGG(JSON_OBJECT(&lt;br /&gt;
			&amp;#039;id&amp;#039;, delivery_item.id,&lt;br /&gt;
			&amp;#039;sku&amp;#039;, delivery_item.sku,&lt;br /&gt;
			&amp;#039;quantity&amp;#039;, delivery_item.quantity,&lt;br /&gt;
			&amp;#039;serialNumbers&amp;#039;, (&lt;br /&gt;
				SELECT JSON_ARRAYAGG(JSON_OBJECT(&lt;br /&gt;
					&amp;#039;id&amp;#039;, serial_number.id,&lt;br /&gt;
					&amp;#039;value&amp;#039;, serial_number.serial_number&lt;br /&gt;
				))&lt;br /&gt;
				FROM delivery_serial_numbers AS serial_number&lt;br /&gt;
				WHERE serial_number.delivery_item_id = delivery_item.id&lt;br /&gt;
			)&lt;br /&gt;
		))&lt;br /&gt;
		FROM delivery_items AS delivery_item&lt;br /&gt;
		WHERE delivery_item.delivery_note_id = delivery_note.id&lt;br /&gt;
	)&lt;br /&gt;
) AS document&lt;br /&gt;
FROM delivery_notes AS delivery_note&lt;br /&gt;
ORDER BY delivery_note.delivery_date DESC;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;JSON_ARRAYAGG&amp;lt;/code&amp;gt; collects values first and emits one exact-sized BSON array at aggregate finalization. Nested aggregation therefore avoids repeatedly copying a growing JSON string. The same finalization is applied independently to scalar subqueries, groups and set-operation branches.&lt;br /&gt;
&lt;br /&gt;
== Storage and indexing ==&lt;br /&gt;
&lt;br /&gt;
* A declared &amp;lt;code&amp;gt;JSON&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;JSONB&amp;lt;/code&amp;gt; column rejects invalid documents on &amp;lt;code&amp;gt;INSERT&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;UPDATE&amp;lt;/code&amp;gt;.&lt;br /&gt;
* MemCP stores one native BSON value, not both a JSON string and a parsed tree. BSON is a normal tagged SCM value and needs no JSON-specific storage engine.&lt;br /&gt;
* Serialization is canonical rather than lexical: insignificant whitespace is not retained, object key order is deterministic, and duplicate object keys do not remain separate.&lt;br /&gt;
* JSON extraction expressions can be used in &amp;lt;code&amp;gt;WHERE&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;GROUP BY&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;ORDER BY&amp;lt;/code&amp;gt;. Eligible deterministic expressions can be materialized as computed columns and served by computed indexes, so document-style tables do not require reparsing every row for each query.&lt;br /&gt;
&lt;br /&gt;
For frequently filtered or sorted attributes, keep the JSON payload for flexibility and expose the hot path as a deterministic expression used consistently by queries. Fully relational columns remain preferable for keys, high-selectivity joins and attributes with strong schema constraints.&lt;br /&gt;
&lt;br /&gt;
== Compatibility notes ==&lt;br /&gt;
&lt;br /&gt;
MemCP aims at practical query compatibility, but it does not preserve PostgreSQL&amp;#039;s textual &amp;lt;code&amp;gt;json&amp;lt;/code&amp;gt; representation separately from &amp;lt;code&amp;gt;jsonb&amp;lt;/code&amp;gt;, nor MariaDB&amp;#039;s LONGTEXT representation. Native BSON is used for both dialects. Applications that depend on original whitespace, duplicate-key preservation or byte-for-byte round trips should store the original document in a separate text column.&lt;br /&gt;
&lt;br /&gt;
Unknown or newly introduced upstream JSON functions should be treated as unsupported until they appear in the supported tables above and in MemCP&amp;#039;s compatibility tests.&lt;br /&gt;
&lt;br /&gt;
== Frequently asked questions about SQL JSON in MemCP ==&lt;br /&gt;
&lt;br /&gt;
=== Does MemCP support MySQL JSON functions? ===&lt;br /&gt;
&lt;br /&gt;
Yes. MemCP supports commonly used MySQL JSON functions and operators for construction, extraction, search, modification, aggregation, schema validation and &amp;lt;code&amp;gt;JSON_TABLE&amp;lt;/code&amp;gt;. The complete currently supported surface is listed under [[#MySQL and MariaDB syntax]].&lt;br /&gt;
&lt;br /&gt;
=== Can MemCP run JSON_EXTRACT and JSON_VALUE on a string? ===&lt;br /&gt;
&lt;br /&gt;
Yes. Both functions accept valid JSON text. A declared &amp;lt;code&amp;gt;JSON&amp;lt;/code&amp;gt; column is more efficient for repeated queries because MemCP validates and converts the document when it is written.&lt;br /&gt;
&lt;br /&gt;
=== Does MemCP support PostgreSQL JSONB? ===&lt;br /&gt;
&lt;br /&gt;
Yes. The PostgreSQL-compatible parser supports &amp;lt;code&amp;gt;json&amp;lt;/code&amp;gt;/&amp;lt;code&amp;gt;jsonb&amp;lt;/code&amp;gt; casts, extraction and containment operators, JSONPath, constructors, aggregates and set-returning JSON functions. MemCP represents both SQL types with the same immutable BSON value internally.&lt;br /&gt;
&lt;br /&gt;
=== Can MemCP index a field inside a JSON document? ===&lt;br /&gt;
&lt;br /&gt;
JSON extraction can be used as a deterministic computed expression. When eligible, MemCP can materialize that expression and use a computed index for filters or ordering by the extracted JSON attribute.&lt;br /&gt;
&lt;br /&gt;
=== Should all application data be stored in one JSON column? ===&lt;br /&gt;
&lt;br /&gt;
It is possible to use a document-style table containing an ID, timestamps and a JSON payload. Relational columns are still preferable for primary keys, frequently joined keys and strongly constrained attributes. A hybrid schema normally gives the optimizer more options while retaining JSON flexibility.&lt;br /&gt;
&lt;br /&gt;
[[Category:SQL]]&lt;br /&gt;
[[Category:JSON]]&lt;br /&gt;
[[Category:MySQL]]&lt;br /&gt;
[[Category:PostgreSQL]]&lt;/div&gt;</summary>
		<author><name>Carli</name></author>
	</entry>
</feed>