1010 lines
		
	
	
		
			37 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			1010 lines
		
	
	
		
			37 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!DOCTYPE html>
 | |
| <html><head>
 | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | |
| <meta http-equiv="content-type" content="text/html; charset=UTF-8">
 | |
| <link href="sqlite.css" rel="stylesheet">
 | |
| <title>The JSON1 Extension</title>
 | |
| <!-- path= -->
 | |
| </head>
 | |
| <body>
 | |
| <div class=nosearch>
 | |
| <a href="index.html">
 | |
| <img class="logo" src="images/sqlite370_banner.gif" alt="SQLite" border="0">
 | |
| </a>
 | |
| <div><!-- IE hack to prevent disappearing logo --></div>
 | |
| <div class="tagline desktoponly">
 | |
| Small. Fast. Reliable.<br>Choose any three.
 | |
| </div>
 | |
| <div class="menu mainmenu">
 | |
| <ul>
 | |
| <li><a href="index.html">Home</a>
 | |
| <li class='mobileonly'><a href="javascript:void(0)" onclick='toggle_div("submenu")'>Menu</a>
 | |
| <li class='wideonly'><a href='about.html'>About</a>
 | |
| <li class='desktoponly'><a href="docs.html">Documentation</a>
 | |
| <li class='desktoponly'><a href="download.html">Download</a>
 | |
| <li class='wideonly'><a href='copyright.html'>License</a>
 | |
| <li class='desktoponly'><a href="support.html">Support</a>
 | |
| <li class='desktoponly'><a href="prosupport.html">Purchase</a>
 | |
| <li class='search' id='search_menubutton'>
 | |
| <a href="javascript:void(0)" onclick='toggle_search()'>Search</a>
 | |
| </ul>
 | |
| </div>
 | |
| <div class="menu submenu" id="submenu">
 | |
| <ul>
 | |
| <li><a href='about.html'>About</a>
 | |
| <li><a href='docs.html'>Documentation</a>
 | |
| <li><a href='download.html'>Download</a>
 | |
| <li><a href='support.html'>Support</a>
 | |
| <li><a href='prosupport.html'>Purchase</a>
 | |
| </ul>
 | |
| </div>
 | |
| <div class="searchmenu" id="searchmenu">
 | |
| <form method="GET" action="search">
 | |
| <select name="s" id="searchtype">
 | |
| <option value="d">Search Documentation</option>
 | |
| <option value="c">Search Changelog</option>
 | |
| </select>
 | |
| <input type="text" name="q" id="searchbox" value="">
 | |
| <input type="submit" value="Go">
 | |
| </form>
 | |
| </div>
 | |
| </div>
 | |
| <script>
 | |
| function toggle_div(nm) {
 | |
| var w = document.getElementById(nm);
 | |
| if( w.style.display=="block" ){
 | |
| w.style.display = "none";
 | |
| }else{
 | |
| w.style.display = "block";
 | |
| }
 | |
| }
 | |
| function toggle_search() {
 | |
| var w = document.getElementById("searchmenu");
 | |
| if( w.style.display=="block" ){
 | |
| w.style.display = "none";
 | |
| } else {
 | |
| w.style.display = "block";
 | |
| setTimeout(function(){
 | |
| document.getElementById("searchbox").focus()
 | |
| }, 30);
 | |
| }
 | |
| }
 | |
| function div_off(nm){document.getElementById(nm).style.display="none";}
 | |
| window.onbeforeunload = function(e){div_off("submenu");}
 | |
| /* Disable the Search feature if we are not operating from CGI, since */
 | |
| /* Search is accomplished using CGI and will not work without it. */
 | |
| if( !location.origin || !location.origin.match || !location.origin.match(/http/) ){
 | |
| document.getElementById("search_menubutton").style.display = "none";
 | |
| }
 | |
| /* Used by the Hide/Show button beside syntax diagrams, to toggle the */
 | |
| function hideorshow(btn,obj){
 | |
| var x = document.getElementById(obj);
 | |
| var b = document.getElementById(btn);
 | |
| if( x.style.display!='none' ){
 | |
| x.style.display = 'none';
 | |
| b.innerHTML='show';
 | |
| }else{
 | |
| x.style.display = '';
 | |
| b.innerHTML='hide';
 | |
| }
 | |
| return false;
 | |
| }
 | |
| </script>
 | |
| </div>
 | |
| <div class=fancy>
 | |
| <div class=nosearch>
 | |
| <div class="fancy_title">
 | |
| The JSON1 Extension
 | |
| </div>
 | |
| <div class="fancy_toc">
 | |
| <a onclick="toggle_toc()">
 | |
| <span class="fancy_toc_mark" id="toc_mk">►</span>
 | |
| Table Of Contents
 | |
| </a>
 | |
| <div id="toc_sub"><div class="fancy-toc1"><a href="#overview">1. Overview</a></div>
 | |
| <div class="fancy-toc1"><a href="#compiling_the_json1_extension">2. Compiling the JSON1 Extension</a></div>
 | |
| <div class="fancy-toc1"><a href="#interface_overview">3. Interface Overview</a></div>
 | |
| <div class="fancy-toc2"><a href="#json_arguments">3.1. JSON arguments</a></div>
 | |
| <div class="fancy-toc2"><a href="#path_arguments">3.2. PATH arguments</a></div>
 | |
| <div class="fancy-toc2"><a href="#value_arguments">3.3. VALUE arguments</a></div>
 | |
| <div class="fancy-toc2"><a href="#compatibility">3.4. Compatibility</a></div>
 | |
| <div class="fancy-toc1"><a href="#function_details">4. Function Details</a></div>
 | |
| <div class="fancy-toc2"><a href="#the_json_function">4.1. The json() function</a></div>
 | |
| <div class="fancy-toc2"><a href="#the_json_array_function">4.2. The json_array() function</a></div>
 | |
| <div class="fancy-toc2"><a href="#the_json_array_length_function">4.3. The json_array_length() function</a></div>
 | |
| <div class="fancy-toc2"><a href="#the_json_extract_function">4.4. The json_extract() function</a></div>
 | |
| <div class="fancy-toc2"><a href="#the_json_insert_json_replace_and_json_set_functions">4.5. The json_insert(), json_replace, and json_set() functions</a></div>
 | |
| <div class="fancy-toc2"><a href="#the_json_object_function">4.6. The json_object() function</a></div>
 | |
| <div class="fancy-toc2"><a href="#the_json_patch_function">4.7. The json_patch() function</a></div>
 | |
| <div class="fancy-toc2"><a href="#the_json_remove_function">4.8. The json_remove() function</a></div>
 | |
| <div class="fancy-toc2"><a href="#the_json_type_function">4.9. The json_type() function</a></div>
 | |
| <div class="fancy-toc2"><a href="#the_json_valid_function">4.10. The json_valid() function</a></div>
 | |
| <div class="fancy-toc2"><a href="#the_json_quote_function">4.11. The json_quote() function</a></div>
 | |
| <div class="fancy-toc2"><a href="#the_json_group_array_and_json_group_object_aggregate_sql_functions">4.12. The json_group_array() and json_group_object()
 | |
| aggregate SQL functions</a></div>
 | |
| <div class="fancy-toc2"><a href="#the_json_each_and_json_tree_table_valued_functions">4.13. The json_each() and json_tree() table-valued functions</a></div>
 | |
| <div class="fancy-toc3"><a href="#examples_using_json_each_and_json_tree_">4.13.1. Examples using json_each() and json_tree()</a></div>
 | |
| </div>
 | |
| </div>
 | |
| <script>
 | |
| function toggle_toc(){
 | |
| var sub = document.getElementById("toc_sub")
 | |
| var mk = document.getElementById("toc_mk")
 | |
| if( sub.style.display!="block" ){
 | |
| sub.style.display = "block";
 | |
| mk.innerHTML = "▼";
 | |
| } else {
 | |
| sub.style.display = "none";
 | |
| mk.innerHTML = "►";
 | |
| }
 | |
| }
 | |
| </script>
 | |
| </div>
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| <h1 id="overview"><span>1. </span>Overview</h1>
 | |
| <p>
 | |
| The <b>json1</b> extension is a <a href="loadext.html">loadable extension</a> that
 | |
| implements fifteen <a href="appfunc.html">application-defined SQL functions</a> and
 | |
| two <a href="vtab.html#tabfunc2">table-valued functions</a> that are useful for
 | |
| managing <a href="http://json.org/">JSON</a> content stored in an SQLite database.
 | |
| There are thirteen scalar functions:
 | |
| 
 | |
| </p><ol>
 | |
| <li value='1'>
 | |
| <a href='#jmini'>json</a>(<i>json</i>)
 | |
| </li>
 | |
| 
 | |
| <li value='2'>
 | |
| <a href='#jarray'>json_array</a>(<i>value1</i>,<i>value2</i>,...)
 | |
| </li>
 | |
| 
 | |
| <li value='3'>
 | |
| <a href='#jarraylen'>json_array_length</a>(<i>json</i>)<br><a href='#jarraylen'>json_array_length</a>(<i>json</i>,<i>path</i>)
 | |
| </li>
 | |
| 
 | |
| <li value='4'>
 | |
| <a href='#jex'>json_extract</a>(<i>json</i>,<i>path</i>,...)
 | |
| </li>
 | |
| 
 | |
| <li value='5'>
 | |
| <a href='#jins'>json_insert</a>(<i>json</i>,<i>path</i>,<i>value</i>,...)
 | |
| </li>
 | |
| 
 | |
| <li value='6'>
 | |
| <a href='#jobj'>json_object</a>(<i>label1</i>,<i>value1</i>,...)
 | |
| </li>
 | |
| 
 | |
| <li value='7'>
 | |
| <a href='#jpatch'>json_patch</a>(<i>json</i>1,json2)
 | |
| </li>
 | |
| 
 | |
| <li value='8'>
 | |
| <a href='#jrm'>json_remove</a>(<i>json</i>,<i>path</i>,...)
 | |
| </li>
 | |
| 
 | |
| <li value='9'>
 | |
| <a href='#jrepl'>json_replace</a>(<i>json</i>,<i>path</i>,<i>value</i>,...)
 | |
| </li>
 | |
| 
 | |
| <li value='10'>
 | |
| <a href='#jset'>json_set</a>(<i>json</i>,<i>path</i>,<i>value</i>,...)
 | |
| </li>
 | |
| 
 | |
| <li value='11'>
 | |
| <a href='#jtype'>json_type</a>(<i>json</i>)<br><a href='#jtype'>json_type</a>(<i>json</i>,<i>path</i>)
 | |
| </li>
 | |
| 
 | |
| <li value='12'>
 | |
| <a href='#jvalid'>json_valid</a>(<i>json</i>)
 | |
| </li>
 | |
| 
 | |
| <li value='13'>
 | |
| <a href='#jvalid'>json_quote</a>(<i>value</i>)
 | |
| </li>
 | |
| 
 | |
| 
 | |
| </ol>
 | |
| 
 | |
| <p>There are two aggregate SQL functions:
 | |
| 
 | |
| </p><ol>
 | |
| <li value='14'>
 | |
| <a href='#jgrouparray'>json_group_array</a>(<i>value</i>)
 | |
| </li>
 | |
| 
 | |
| <li value='15'>
 | |
| <a href='#jgroupobject'>json_group_object</a>(name,<i>value</i>)
 | |
| </li>
 | |
| 
 | |
| 
 | |
| </ol>
 | |
| 
 | |
| <p>The two <a href="vtab.html#tabfunc2">table-valued functions</a> are:
 | |
| 
 | |
| </p><ol>
 | |
| <li value='16'>
 | |
| <a href='#jeach'>json_each</a>(<i>json</i>)<br><a href='#jeach'>json_each</a>(<i>json</i>,<i>path</i>)
 | |
| </li>
 | |
| 
 | |
| <li value='17'>
 | |
| <a href='#jtree'>json_tree</a>(<i>json</i>)<br><a href='#jtree'>json_tree</a>(<i>json</i>,<i>path</i>)
 | |
| </li>
 | |
| 
 | |
| 
 | |
| </ol>
 | |
| 
 | |
| 
 | |
| 
 | |
| <style>
 | |
| .jans {color: #050;}
 | |
| .jex {color: #025;}
 | |
| </style>
 | |
| 
 | |
| 
 | |
| <a name="howtocompile"></a>
 | |
| 
 | |
| <h1 id="compiling_the_json1_extension"><span>2. </span>Compiling the JSON1 Extension</h1>
 | |
| 
 | |
| <p>
 | |
| The <a href="loadext.html">loadable extensions</a> documentation describes
 | |
| how to <a href="loadext.html#build">compile loadable extensions</a> as shared libraries.  The
 | |
| techniques described there work fine for the json1 module.
 | |
| 
 | |
| </p><p>
 | |
| The json1 source code is included with the SQLite <a href="amalgamation.html">amalgamation</a>, though
 | |
| it is disabled by default.  Add the <a href="compile.html#enable_json1">-DSQLITE_ENABLE_JSON1</a> compile-time
 | |
| option to enable the json1 extension that is built into the <a href="amalgamation.html">amalgamation</a>.
 | |
| The standard makefiles include -DSQLITE_ENABLE_JSON1 when building the
 | |
| <a href="cli.html">command-line shell</a> and some of the test utilities so this extension is
 | |
| normally available in the <a href="cli.html">command-line shell</a>.
 | |
| 
 | |
| </p><h1 id="interface_overview"><span>3. </span>Interface Overview</h1>
 | |
| 
 | |
| <p>
 | |
| The json1 extension (currently) stores JSON as ordinary text.
 | |
| 
 | |
| </p><p>
 | |
| Backwards compatibility constraints mean that SQLite is only able to
 | |
| store values that are NULL, integers, floating-point numbers, text,
 | |
| and BLOBs.  It is not possible to add a sixth "JSON" type.
 | |
| 
 | |
| </p><p>
 | |
| The json1 extension does not (currently) support a binary encoding
 | |
| of JSON.  Experiments have been unable to find a binary encoding
 | |
| that is significantly smaller or faster than a plain text encoding.
 | |
| (The present implementation parses JSON text at over 1 GB/s.)
 | |
| All json1 functions currently throw an error if any of their
 | |
| arguments are BLOBs because BLOBs are reserved
 | |
| for a future enhancement in which BLOBs will store the binary encoding
 | |
| for JSON.
 | |
| 
 | |
| </p><p>
 | |
| The "1" at the end of the name for the json1 extension is deliberate.
 | |
| The designers anticipate that there will be future incompatible JSON
 | |
| extensions building upon the lessons learned from json1.
 | |
| Once sufficient experience is gained, some kind of
 | |
| JSON extension might be folded into the SQLite core.  For now,
 | |
| JSON support remains an extension.
 | |
| 
 | |
| </p><h2 id="json_arguments"><span>3.1. </span>JSON arguments</h2>
 | |
| 
 | |
| <p>
 | |
| For functions that accept JSON as their first argument, that argument
 | |
| can be a JSON object, array, number, string, or null.  SQLite numeric
 | |
| values and NULL values are interpreted as JSON numbers and nulls, respectively.
 | |
| SQLite text values can be understood as JSON objects, arrays, or strings.
 | |
| If an SQLite text value that is not a well-formed JSON object, array, or
 | |
| string is passed into json1 function, that function will usually throw
 | |
| an error.  (Exceptions to this rule are <a href="json1.html#jvalid">json_valid()</a> and
 | |
| <a href="json1.html#jquote">json_quote()</a>.)
 | |
| 
 | |
| </p><p>
 | |
| For the purposes of determining validity, leading and trailing whitespace
 | |
| on JSON inputs is ignored.  Interior whitespace is also ignored, in accordance
 | |
| with the JSON spec.  These routines accept exactly the 
 | |
| <a href="http://www.rfc-editor.org/rfc/rfc7159.txt">rfc-7159 JSON syntax</a>
 | |
| — no more and no less.
 | |
| 
 | |
| <a name="jsonpath"></a>
 | |
| 
 | |
| </p><h2 id="path_arguments"><span>3.2. </span>PATH arguments</h2>
 | |
| 
 | |
| <p>
 | |
| For functions that accept PATH arguments, that PATH must be well-formed or
 | |
| else the function will throw an error.
 | |
| A well-formed PATH is a text value that begins with exactly one
 | |
| '$' character followed by zero or more instances
 | |
| of ".<i>objectlabel</i>" or "[<i>arrayindex</i>]".
 | |
| 
 | |
| </p><p>
 | |
| The <i>arrayindex</i> is usually a non-negative integer <i>N</i>.  In
 | |
| that case, the array element selected is the <i>N</i>-th element
 | |
| of the array, starting with zero on the left.
 | |
| The <i>arrayindex</i> can also be of the form "<b>#-</b><i>N</i>"
 | |
| in which case the element selected is the <i>N</i>-th from the
 | |
| right.  The last element of the array is "<b>#-1</b>".  Think of
 | |
| the "#" characters as the "number of elements in the array".  Then
 | |
| the expression "#-1" evaluates is the integer that corresponds to 
 | |
| the last entry in the array.
 | |
| 
 | |
| </p><h2 id="value_arguments"><span>3.3. </span>VALUE arguments</h2>
 | |
| 
 | |
| <p>
 | |
| For functions that accept "<i>value</i>" arguments (also shown as
 | |
| "<i>value1</i>" and "<i>value2</i>"),
 | |
| those arguments is usually understood
 | |
| to be a literal strings that are quoted and becomes JSON string values
 | |
| in the result.  Even if the input <i>value</i> strings look like 
 | |
| well-formed JSON, they are still interpreted as literal strings in the
 | |
| result.
 | |
| 
 | |
| </p><p>
 | |
| However, if a <i>value</i> argument come directly from the result of another
 | |
| json1 function, then the argument is understood to be actual JSON and
 | |
| the complete JSON is inserted rather than a quoted string.
 | |
| 
 | |
| </p><p>
 | |
| For example, in the following call to json_object(), the <i>value</i>
 | |
| argument looks like a well-formed JSON array.  However, because it is just
 | |
| ordinary SQL text, it is interpreted as a literal string and added to the
 | |
| result as a quoted string:
 | |
| 
 | |
| <ul>
 | |
| <li><span class='jex'>json_object('ex','[52,3.14159]')</span>
 | |
| <span class='jans'>→ '{"ex":"[52,3.14159]"}'</span></li>
 | |
| 
 | |
| </ul>
 | |
| 
 | |
| 
 | |
| </p><p>
 | |
| But if the <i>value</i> argument in the outer json_object() call is the
 | |
| result of another json1 function like <a href="json1.html#jmini">json()</a> or <a href="json1.html#jarray">json_array()</a>, then
 | |
| the value is understood to be actual JSON and is inserted as such:
 | |
| 
 | |
| <ul>
 | |
| <li><span class='jex'>json_object('ex',json('[52,3.14159]'))</span>
 | |
| <span class='jans'>→ '{"ex":[52,3.14159]}'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_object('ex',json_array(52,3.14159))</span>
 | |
| <span class='jans'>→ '{"ex":[52,3.14159]}'</span></li>
 | |
| 
 | |
| </ul>
 | |
| 
 | |
| 
 | |
| </p><p>
 | |
| To be clear: "<i>json</i>" arguments are always interpreted as JSON
 | |
| regardless of where the value for that argument comes from.  But
 | |
| "<i>value</i>" arguments are only interpreted as JSON if those arguments
 | |
| come directly from another json1 function.
 | |
| 
 | |
| </p><h2 id="compatibility"><span>3.4. </span>Compatibility</h2>
 | |
| 
 | |
| <p>
 | |
| The json1 extension uses the <a href="c3ref/value_subtype.html">sqlite3_value_subtype()</a> and
 | |
| <a href="c3ref/result_subtype.html">sqlite3_result_subtype()</a> interfaces that were introduced with
 | |
| SQLite version 3.9.0 (2015-10-14)
 | |
| The json1 extension will not work
 | |
| in earlier versions of SQLite.
 | |
| 
 | |
| </p><p>
 | |
| The current implementation of this JSON library uses a recursive descent
 | |
| parser.  In order to avoid using excess stack space, any JSON input that has
 | |
| more than 2000 levels of nesting is considered invalid.   Limits on nesting
 | |
| depth are allowed for compatible implementations of JSON by
 | |
| <a href="https://tools.ietf.org/html/rfc7159#section-9">RFC-7159 section 9</a>.
 | |
| 
 | |
| 
 | |
| </p><h1 id="function_details"><span>4. </span>Function Details</h1>
 | |
| 
 | |
| <p>The following sections provide additional detail on the operation of
 | |
| the various functions that are part of the json1 extension.
 | |
| 
 | |
| <a name="jmini"></a>
 | |
| 
 | |
| </p><h2 id="the_json_function"><span>4.1. </span>The json() function</h2>
 | |
| 
 | |
| <p>The json(X) function verifies that its argument X is a valid
 | |
| JSON string and returns a minified version of that JSON string
 | |
| (with all unnecessary whitespace removed).  If X is not a well-formed
 | |
| JSON string, then this routine throws an error.
 | |
| 
 | |
| </p><p>If the argument X to json(X) contains JSON objects with duplicate
 | |
| labels, then it is undefined whether or not the duplicates are
 | |
| preserved.  The current implementation preserves duplicates.
 | |
| However, future enhancements
 | |
| to this routine may choose to silently remove duplicates.
 | |
| 
 | |
| </p><p>
 | |
| Example:
 | |
| 
 | |
| <ul>
 | |
| <li><span class='jex'>json(' { "this" : "is", "a": [ "test" ] } ')</span>
 | |
| <span class='jans'>→ '{"this":"is","a":["test"]}'</span></li>
 | |
| 
 | |
| </ul>
 | |
| 
 | |
| 
 | |
| <a name="jarray"></a>
 | |
| 
 | |
| </p><h2 id="the_json_array_function"><span>4.2. </span>The json_array() function</h2>
 | |
| 
 | |
| <p>The json_array() SQL function accepts zero or more arguments and
 | |
| returns a well-formed JSON array that is composed from those arguments.
 | |
| If any argument to json_array() is a BLOB then an error is thrown.
 | |
| 
 | |
| </p><p>An argument with SQL type TEXT it is normally converted into a quoted 
 | |
| JSON string.  However, if the argument is the output from another json1
 | |
| function, then it is stored as JSON.  This allows calls to json_array()
 | |
| and <a href="json1.html#jobj">json_object()</a> to be nested.  The <a href="json1.html#jmini">json()</a> function can also
 | |
| be used to force strings to be recognized as JSON.
 | |
| 
 | |
| </p><p>Examples:
 | |
| 
 | |
| <ul>
 | |
| <li><span class='jex'>json_array(1,2,'3',4)</span>
 | |
| <span class='jans'>→ '[1,2,"3",4]'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_array('[1,2]')</span>
 | |
| <span class='jans'>→ '["[1,2]"]'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_array(json_array(1,2))</span>
 | |
| <span class='jans'>→ '[[1,2]]'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_array(1,null,'3','[4,5]','{"six":7.7}')</span>
 | |
| <span class='jans'>→ '[1,null,"3","[4,5]","{\"six\":7.7}"]'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_array(1,null,'3',json('[4,5]'),json('{"six":7.7}'))</span>
 | |
| <span class='jans'>→ '[1,null,"3",[4,5],{"six":7.7}]'</span></li>
 | |
| 
 | |
| </ul>
 | |
| 
 | |
| 
 | |
| 
 | |
| <a name="jarraylen"></a>
 | |
| 
 | |
| </p><h2 id="the_json_array_length_function"><span>4.3. </span>The json_array_length() function</h2>
 | |
| 
 | |
| <p>The json_array_length(X) function returns the number of elements
 | |
| in the JSON array X, or 0 if X is some kind of JSON value other
 | |
| than an array.  The json_array_length(X,P) locates the array at path P
 | |
| within X and returns the length of that array, or 0 if path P locates
 | |
| an element or X other than a JSON array, and NULL if path P does not
 | |
| locate any element of X.  Errors are thrown if either X is not 
 | |
| well-formed JSON or if P is not a well-formed path.
 | |
| 
 | |
| </p><p>Examples:
 | |
| 
 | |
| <ul>
 | |
| <li><span class='jex'>json_array_length('[1,2,3,4]')</span>
 | |
| <span class='jans'>→ 4</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_array_length('[1,2,3,4]', '$')</span>
 | |
| <span class='jans'>→ 4</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_array_length('[1,2,3,4]', '$[2]')</span>
 | |
| <span class='jans'>→ 0</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_array_length('{"one":[1,2,3]}')</span>
 | |
| <span class='jans'>→ 0</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_array_length('{"one":[1,2,3]}', '$.one')</span>
 | |
| <span class='jans'>→ 3</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_array_length('{"one":[1,2,3]}', '$.two')</span>
 | |
| <span class='jans'>→ NULL</span></li>
 | |
| 
 | |
| </ul>
 | |
| 
 | |
| 
 | |
| 
 | |
| <a name="jex"></a>
 | |
| 
 | |
| </p><h2 id="the_json_extract_function"><span>4.4. </span>The json_extract() function</h2>
 | |
| 
 | |
| <p>The json_extract(X,P1,P2,...) extracts and returns one or more 
 | |
| values from the
 | |
| well-formed JSON at X.  If only a single path P1 is provided, then the
 | |
| SQL datatype of the result is NULL for a JSON null, INTEGER or REAL
 | |
| for a JSON numeric value, an INTEGER zero for a JSON false value,
 | |
| an INTEGER one for a JSON true value, the dequoted text for a 
 | |
| JSON string value, and a text representation for JSON object and array values.
 | |
| If there are multiple path arguments (P1, P2, and so forth) then this
 | |
| routine returns SQLite text which is a well-formed JSON array holding
 | |
| the various values.
 | |
| 
 | |
| </p><p>Examples:
 | |
| 
 | |
| <ul>
 | |
| <li><span class='jex'>json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$')</span>
 | |
| <span class='jans'>→ '{"a":2,"c":[4,5,{"f":7}]}'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.c')</span>
 | |
| <span class='jans'>→ '[4,5,{"f":7}]'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.c[2]')</span>
 | |
| <span class='jans'>→ '{"f":7}'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.c[2].f')</span>
 | |
| <span class='jans'>→ 7</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_extract('{"a":2,"c":[4,5],"f":7}','$.c','$.a')</span>
 | |
| <span class='jans'>→ '[[4,5],2]'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_extract('{"a":2,"c":[4,5],"f":7}','$.c[#-1]')</span>
 | |
| <span class='jans'>→ 5</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.x')</span>
 | |
| <span class='jans'>→ NULL</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_extract('{"a":2,"c":[4,5,{"f":7}]}', '$.x', '$.a')</span>
 | |
| <span class='jans'>→ '[null,2]'</span></li>
 | |
| 
 | |
| </ul>
 | |
|   
 | |
| 
 | |
| <a name="jins"></a>
 | |
| 
 | |
| <a name="jrepl"></a>
 | |
| 
 | |
| <a name="jset"></a>
 | |
| 
 | |
| </p><h2 id="the_json_insert_json_replace_and_json_set_functions"><span>4.5. </span>The json_insert(), json_replace, and json_set() functions</h2>
 | |
| 
 | |
| <p>The json_insert(), json_replace, and json_set() functions all take
 | |
| a single JSON value as their first argument followed by zero or more
 | |
| pairs of path and value arguments, and return a new JSON string formed
 | |
| by updating the input JSON by the path/value pairs.  The functions
 | |
| differ only in how they deal with creating new values and overwriting
 | |
| preexisting values.
 | |
| 
 | |
| </p><center>
 | |
| <table border="1" cellpadding="3" cellspacing="0">
 | |
| <tr>
 | |
| <th>Function</th><th>Overwrite if already exists?</th><th>Create if does not exist?
 | |
| </th></tr><tr>
 | |
| <td>json_insert()</td><td align="'center'">No</td><td align="'center'">Yes
 | |
| </td></tr><tr>
 | |
| <td>json_replace()</td><td align="'center'">Yes</td><td align="'center'">No
 | |
| </td></tr><tr>
 | |
| <td>json_set()</td><td align="'center'">Yes</td><td align="'center'">Yes
 | |
| </td></tr></table></center>
 | |
| 
 | |
| <p>The json_insert(), json_replace(), and json_set() functions always
 | |
| take an odd number of arguments.  The first argument is always the original
 | |
| JSON to be edited.  Subsequent arguments occur in pairs with the first
 | |
| element of each pair being a path and the second element being the value
 | |
| to insert or replace or set on that path.
 | |
| 
 | |
| </p><p>Edits occurs sequentially from left to right.  Changes caused by
 | |
| prior edits can affect the path search for subsequent edits.
 | |
| 
 | |
| </p><p>If the value of a path/value pair is an SQLite TEXT value, then it
 | |
| is normally inserted as a quoted JSON string, even if the string looks
 | |
| like valid JSON.  However, if the value is the result of another
 | |
| json1 function (such as <a href="json1.html#jmini">json()</a> or <a href="json1.html#jarray">json_array()</a> or <a href="json1.html#jobj">json_object()</a>)
 | |
| then it is interpreted as JSON and is inserted as JSON retaining all
 | |
| of its substructure.
 | |
| 
 | |
| </p><p>These routines throw an error if the first JSON argument is not
 | |
| well-formed or if any PATH argument is not well-formed or if any
 | |
| argument is a BLOB.
 | |
| 
 | |
| </p><p>To append an element onto the end of an array, using json_insert()
 | |
| with an array index of "#".  Examples:
 | |
| 
 | |
| <ul>
 | |
| <li><span class='jex'>json_insert('[1,2,3,4]','$[#]',99)</span>
 | |
| <span class='jans'>→ '[1,2,3,4,99]'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_insert('[1,[2,3],4]','$[1][#]',99)</span>
 | |
| <span class='jans'>→ '[1,[2,3,99],4]'</span></li>
 | |
| 
 | |
| </ul>
 | |
| 
 | |
| 
 | |
| </p><p>Other examples:
 | |
| 
 | |
| <ul>
 | |
| <li><span class='jex'>json_insert('{"a":2,"c":4}', '$.a', 99)</span>
 | |
| <span class='jans'>→ '{"a":2,"c":4}'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_insert('{"a":2,"c":4}', '$.e', 99)</span>
 | |
| <span class='jans'>→ '{"a":2,"c":4,"e":99}'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_replace('{"a":2,"c":4}', '$.a', 99)</span>
 | |
| <span class='jans'>→ '{"a":99,"c":4}'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_replace('{"a":2,"c":4}', '$.e', 99)</span>
 | |
| <span class='jans'>→ '{"a":2,"c":4}'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_set('{"a":2,"c":4}', '$.a', 99)</span>
 | |
| <span class='jans'>→ '{"a":99,"c":4}'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_set('{"a":2,"c":4}', '$.e', 99)</span>
 | |
| <span class='jans'>→ '{"a":2,"c":4,"e":99}'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_set('{"a":2,"c":4}', '$.c', '[97,96]')</span>
 | |
| <span class='jans'>→ '{"a":2,"c":"[97,96]"}'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_set('{"a":2,"c":4}', '$.c', json('[97,96]'))</span>
 | |
| <span class='jans'>→ '{"a":2,"c":[97,96]}'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_set('{"a":2,"c":4}', '$.c', json_array(97,96))</span>
 | |
| <span class='jans'>→ '{"a":2,"c":[97,96]}'</span></li>
 | |
| 
 | |
| </ul>
 | |
| 
 | |
| 
 | |
| <a name="jobj"></a>
 | |
| 
 | |
| </p><h2 id="the_json_object_function"><span>4.6. </span>The json_object() function</h2>
 | |
| 
 | |
| <p>The json_object() SQL function accepts zero or more pairs of arguments
 | |
| and returns a well-formed JSON object that is composed from those arguments.
 | |
| The first argument of each pair is the label and the second argument of
 | |
| each pair is the value.
 | |
| If any argument to json_object() is a BLOB then an error is thrown.
 | |
| 
 | |
| </p><p>The json_object() function currently allows duplicate labels without
 | |
| complaint, though this might change in a future enhancement.
 | |
| 
 | |
| </p><p>An argument with SQL type TEXT it is normally converted into a quoted 
 | |
| JSON string even if the input text is well-formed JSON.  
 | |
| However, if the argument is the direct result from another json1
 | |
| function, then it is treated as JSON and all of its JSON type information
 | |
| and substructure is preserved.  This allows calls to json_object()
 | |
| and <a href="json1.html#jarray">json_array()</a> to be nested.  The <a href="json1.html#jmini">json()</a> function can also
 | |
| be used to force strings to be recognized as JSON.
 | |
| 
 | |
| </p><p>Examples:
 | |
| 
 | |
| <ul>
 | |
| <li><span class='jex'>json_object('a',2,'c',4)</span>
 | |
| <span class='jans'>→ '{"a":2,"c":4}'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_object('a',2,'c','{e:5}')</span>
 | |
| <span class='jans'>→ '{"a":2,"c":"{e:5}"}'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_object('a',2,'c',json_object('e',5))</span>
 | |
| <span class='jans'>→ '{"a":2,"c":{"e":5}}'</span></li>
 | |
| 
 | |
| </ul>
 | |
| 
 | |
| 
 | |
| <a name="jpatch"></a>
 | |
| 
 | |
| </p><h2 id="the_json_patch_function"><span>4.7. </span>The json_patch() function</h2>
 | |
| 
 | |
| <p>The json_patch(T,P) SQL function runs the
 | |
| <a href="https://tools.ietf.org/html/rfc7396">RFC-7396</a> MergePatch algorithm
 | |
| to apply patch P against input T.  The patched copy of T is returned.
 | |
| 
 | |
| </p><p>MergePatch can add, modify, or delete elements of a JSON Object,
 | |
| and so for JSON Objects, the json_patch() routine is a generalized
 | |
| replacement for <a href="json1.html#jset">json_set()</a> and <a href="json1.html#jrm">json_remove()</a>.  However, MergePatch
 | |
| treats JSON Array objects as atomic.  MergePatch cannot append to an
 | |
| Array nor modify individual elements of an Array.  It can only insert,
 | |
| replace, or delete the whole Array as a single unit.  Hence, json_patch()
 | |
| is not as useful when dealing with JSON that includes Arrays,
 | |
| especially Arrays with lots of substructure.
 | |
| 
 | |
| </p><p>Examples:
 | |
| 
 | |
| <ul>
 | |
| <li><span class='jex'>json_patch('{"a":1,"b":2}','{"c":3,"d":4}')</span>
 | |
| <span class='jans'>→ '{"a":1,"b":2,"c":3,"d":4}'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_patch('{"a":[1,2],"b":2}','{"a":9}')</span>
 | |
| <span class='jans'>→ '{"a":9,"b":2}'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_patch('{"a":[1,2],"b":2}','{"a":null}')</span>
 | |
| <span class='jans'>→ '{"b":2}'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_patch('{"a":1,"b":2}','{"a":9,"b":null,"c":8}')</span>
 | |
| <span class='jans'>→ '{"a":9,"c":8}'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_patch('{"a":{"x":1,"y":2},"b":3}','{"a":{"y":9},"c":8}')</span>
 | |
| <span class='jans'>→ '{"a":{"x":1,"y":9},"b":3,"c":8}'</span></li>
 | |
| 
 | |
| </ul>
 | |
| 
 | |
| 
 | |
| <a name="jrm"></a>
 | |
| 
 | |
| </p><h2 id="the_json_remove_function"><span>4.8. </span>The json_remove() function</h2>
 | |
| 
 | |
| <p>The json_remove(X,P,...) function takes a single JSON value as its
 | |
| first argument followed by zero or more path arguments.
 | |
| The json_remove(X,P,...) function returns
 | |
| a new JSON value that is the X with all the elements 
 | |
| identified by path arguments removed.  Paths that select elements
 | |
| not found in X are silently ignored.
 | |
| 
 | |
| </p><p>Removals occurs sequentially from left to right.  Changes caused by
 | |
| prior removals can affect the path search for subsequent arguments.
 | |
| 
 | |
| </p><p>If the json_remove(X) function is called with no path arguments,
 | |
| then it returns the input X reformatted, with excess whitespace
 | |
| removed.
 | |
| 
 | |
| </p><p>The json_remove() function throws an error if the first argument
 | |
| is not well-formed JSON or if any later argument is not a well-formed
 | |
| path, or if any argument is a BLOB.
 | |
| 
 | |
| </p><p>Examples:
 | |
| 
 | |
| <ul>
 | |
| <li><span class='jex'>json_remove('[0,1,2,3,4]','$[2]')</span>
 | |
| <span class='jans'>→ '[0,1,3,4]'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_remove('[0,1,2,3,4]','$[2]','$[0]')</span>
 | |
| <span class='jans'>→ '[1,3,4]'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_remove('[0,1,2,3,4]','$[0]','$[2]')</span>
 | |
| <span class='jans'>→ '[1,2,4]'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_remove('[0,1,2,3,4]','$[#-1]','$[0]')</span>
 | |
| <span class='jans'>→ '[1,2,3]'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_remove('{"x":25,"y":42}')</span>
 | |
| <span class='jans'>→ '{"x":25,"y":42}'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_remove('{"x":25,"y":42}','$.z')</span>
 | |
| <span class='jans'>→ '{"x":25,"y":42}'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_remove('{"x":25,"y":42}','$.y')</span>
 | |
| <span class='jans'>→ '{"x":25}'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_remove('{"x":25,"y":42}','$')</span>
 | |
| <span class='jans'>→ NULL</span></li>
 | |
| 
 | |
| </ul>
 | |
| 
 | |
| 
 | |
| <a name="jtype"></a>
 | |
| 
 | |
| </p><h2 id="the_json_type_function"><span>4.9. </span>The json_type() function</h2>
 | |
| 
 | |
| <p>The json_type(X) function returns the "type" of the outermost element
 | |
| of X.  The json_type(X,P) function returns the "type" of the element
 | |
| in X that is selected by path P.  The "type" returned by json_type() is
 | |
| one of the following an SQL text values:
 | |
| 'null', 'true', 'false', 'integer', 'real', 'text', 'array', or 'object'.
 | |
| If the path P in json_type(X,P) selects an element that does not exist
 | |
| in X, then this function returns NULL.
 | |
| 
 | |
| </p><p>The json_type() function throws an error if any of its arguments are
 | |
| not well-formed or is a BLOB.
 | |
| 
 | |
| </p><p>Examples:
 | |
| 
 | |
| <ul>
 | |
| <li><span class='jex'>json_type('{"a":[2,3.5,true,false,null,"x"]}')</span>
 | |
| <span class='jans'>→ 'object'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_type('{"a":[2,3.5,true,false,null,"x"]}','$')</span>
 | |
| <span class='jans'>→ 'object'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a')</span>
 | |
| <span class='jans'>→ 'array'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[0]')</span>
 | |
| <span class='jans'>→ 'integer'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[1]')</span>
 | |
| <span class='jans'>→ 'real'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[2]')</span>
 | |
| <span class='jans'>→ 'true'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[3]')</span>
 | |
| <span class='jans'>→ 'false'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[4]')</span>
 | |
| <span class='jans'>→ 'null'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[5]')</span>
 | |
| <span class='jans'>→ 'text'</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_type('{"a":[2,3.5,true,false,null,"x"]}','$.a[6]')</span>
 | |
| <span class='jans'>→ NULL</span></li>
 | |
| 
 | |
| </ul>
 | |
| 
 | |
| 
 | |
| <a name="jvalid"></a>
 | |
| 
 | |
| </p><h2 id="the_json_valid_function"><span>4.10. </span>The json_valid() function</h2>
 | |
| 
 | |
| <p>The json_valid(X) function return 1 if the argument X is well-formed
 | |
| JSON and return 0 if the argument X is not well-formed JSON.
 | |
| 
 | |
| </p><p>Examples:
 | |
| 
 | |
| <ul>
 | |
| <li><span class='jex'>json_valid('{"x":35}')</span>
 | |
| <span class='jans'>→ 1</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_valid('{"x":35')</span>
 | |
| <span class='jans'>→ 0</span></li>
 | |
| 
 | |
| </ul>
 | |
| 
 | |
| 
 | |
| <a name="jquote"></a>
 | |
| 
 | |
| </p><h2 id="the_json_quote_function"><span>4.11. </span>The json_quote() function</h2>
 | |
| 
 | |
| <p>The json_quote(X) function converts the SQL value X (a number or a
 | |
| string) into its corresponding JSON representation. 
 | |
| 
 | |
| </p><p>Examples:
 | |
| 
 | |
| <ul>
 | |
| <li><span class='jex'>json_quote(3.14159)</span>
 | |
| <span class='jans'>→ 3.14159</span></li>
 | |
| 
 | |
| <li><span class='jex'>json_quote('verdant')</span>
 | |
| <span class='jans'>→ "verdant"</span></li>
 | |
| 
 | |
| </ul>
 | |
| 
 | |
| 
 | |
| <a name="jgrouparray"></a>
 | |
| <a name="jgroupobject"></a>
 | |
| 
 | |
| </p><h2 id="the_json_group_array_and_json_group_object_aggregate_sql_functions"><span>4.12. </span>The json_group_array() and json_group_object()
 | |
| aggregate SQL functions</h2>
 | |
| 
 | |
| <p>The json_group_array(X) function is an 
 | |
| <a href="lang_aggfunc.html">aggregate SQL function</a> that returns a JSON array
 | |
| comprised of all X values in the aggregation.
 | |
| Similarly, the json_group_object(NAME,VALUE) function returns a JSON object
 | |
| comprised of all NAME/VALUE pairs in the aggregation.
 | |
| 
 | |
| 
 | |
| <a name="jeach"></a>
 | |
| 
 | |
| <a name="jtree"></a>
 | |
| 
 | |
| </p><h2 id="the_json_each_and_json_tree_table_valued_functions"><span>4.13. </span>The json_each() and json_tree() table-valued functions</h2>
 | |
| 
 | |
| <p>The json_each(X) and json_tree(X) <a href="vtab.html#tabfunc2">table-valued functions</a> walk the
 | |
| JSON value provided as their first argument and return one row for each
 | |
| element.  The json_each(X) function only walks the immediate children
 | |
| of the top-level array or object or 
 | |
| or just the top-level element itself if the top-level
 | |
| element is a primitive value.
 | |
| The json_tree(X) function recursively walks through the
 | |
| JSON substructure starting with the top-level element.  
 | |
| 
 | |
| </p><p>The json_each(X,P) and json_tree(X,P) functions work just like
 | |
| their one-argument counterparts except that they treat the element
 | |
| identified by path P as the top-level element.
 | |
| 
 | |
| </p><p>The schema for the table returned by json_each() and json_tree() is
 | |
| as follows:
 | |
| 
 | |
| </p><blockquote><pre>
 | |
| CREATE TABLE json_tree(
 | |
|     key ANY,             -- key for current element relative to its parent
 | |
|     value ANY,           -- value for the current element
 | |
|     type TEXT,           -- 'object','array','string','integer', etc.
 | |
|     atom ANY,            -- value for primitive types, null for array & object
 | |
|     id INTEGER,          -- integer ID for this element
 | |
|     parent INTEGER,      -- integer ID for the parent of this element
 | |
|     fullkey TEXT,        -- full path describing the current element
 | |
|     path TEXT,           -- path to the container of the current row
 | |
|     json JSON HIDDEN,    -- 1st input parameter: the raw JSON
 | |
|     root TEXT HIDDEN     -- 2nd input parameter: the PATH at which to start
 | |
| );
 | |
| </pre></blockquote>
 | |
| 
 | |
| <p>
 | |
| The "key" column is the integer array index for elements of a JSON array 
 | |
| and the text label for elements of a JSON object.  The key column is
 | |
| NULL in all other cases.
 | |
| 
 | |
| </p><p>
 | |
| The "atom" column is the SQL value corresponding to primitive elements - 
 | |
| elements other than JSON arrays and objects.  The "atom" column is NULL
 | |
| for a JSON array or object.  The "value" column is the same as the
 | |
| "atom" column for primitive JSON elements but takes on the text JSON value
 | |
| for arrays and objects.
 | |
| 
 | |
| </p><p>
 | |
| The "type" column is an SQL text value taken from ('null', 'true', 'false',
 | |
| 'integer', 'real', 'text', 'array', 'object') according to the type of
 | |
| the current JSON element.
 | |
| 
 | |
| </p><p>
 | |
| The "id" column is an integer that identifies a specific JSON element
 | |
| within the complete JSON string.  The "id" integer is an internal housekeeping
 | |
| number, the computation of which might change in future releases.  The
 | |
| only guarantee is that the "id" column will be different for every row.
 | |
| 
 | |
| </p><p>
 | |
| The "parent" column is always NULL for json_each().
 | |
| For json_tree(),
 | |
| the "parent" column is the "id" integer for the parent of the current
 | |
| element, or NULL for the top-level JSON element or the element identified
 | |
| by the root path in the second argument.
 | |
| 
 | |
| </p><p>
 | |
| The "fullkey" column is a text path that uniquely identifies the current
 | |
| row element within the original JSON string.  The complete key to the
 | |
| true top-level element is returned even if an alternative starting point
 | |
| is provided by the "root" argument.
 | |
| 
 | |
| </p><p>
 | |
| The "path" column is the path to the array or object container the holds 
 | |
| the current row, or the path to the current row in the case where the 
 | |
| iteration starts on a primitive type and thus only provides a single
 | |
| row of output.
 | |
| 
 | |
| </p><h3 id="examples_using_json_each_and_json_tree_"><span>4.13.1. </span>Examples using json_each() and json_tree()</h3>
 | |
| 
 | |
| <p>Suppose the table "CREATE TABLE user(name,phone)" stores zero or
 | |
| more phone numbers as a JSON array object in the user.phone field.
 | |
| To find all users who have any phone number with a 704 area code:
 | |
| 
 | |
| </p><blockquote><pre>
 | |
| SELECT DISTINCT user.name
 | |
|   FROM user, json_each(user.phone)
 | |
|  WHERE json_each.value LIKE '704-%';
 | |
| </pre></blockquote>
 | |
| 
 | |
| <p>Now suppose the user.phone field contains plain text if the user
 | |
| has only a single phone number and a JSON array if the user has multiple
 | |
| phone numbers.  The same question is posed: "Which users have a phone number
 | |
| in the 704 area code?"  But now the json_each() function can only be called
 | |
| for those users that have two or more phone numbers since json_each()
 | |
| requires well-formed JSON as its first argument:
 | |
| 
 | |
| </p><blockquote><pre>
 | |
| SELECT name FROM user WHERE phone LIKE '704-%'
 | |
| UNION
 | |
| SELECT user.name
 | |
|   FROM user, json_each(user.phone)
 | |
|  WHERE json_valid(user.phone)
 | |
|    AND json_each.value LIKE '704-%';
 | |
| </pre></blockquote>
 | |
| 
 | |
| <p>Consider a different database with "CREATE TABLE big(json JSON)".
 | |
| To see a complete line-by-line decomposition of the data:
 | |
| 
 | |
| </p><blockquote><pre>
 | |
| SELECT big.rowid, fullkey, value
 | |
|   FROM big, json_tree(big.json)
 | |
|  WHERE json_tree.type NOT IN ('object','array');
 | |
| </pre></blockquote>
 | |
| 
 | |
| <p>In the previous, the "type NOT IN ('object','array')" term of the
 | |
| WHERE clause suppresses containers and only lets through leaf elements.
 | |
| The same effect could be achieved this way:
 | |
| 
 | |
| </p><blockquote><pre>
 | |
| SELECT big.rowid, fullkey, atom
 | |
|   FROM big, json_tree(big.json)
 | |
|  WHERE atom IS NOT NULL;
 | |
| </pre></blockquote>
 | |
| 
 | |
| <p>Suppose each entry in the BIG table is a JSON object 
 | |
| with a '$.id' field that is a unique identifier
 | |
| and a '$.partlist' field that can be a deeply nested object.
 | |
| You want to find the id of every entry that contains one
 | |
| or more references to uuid '6fa5181e-5721-11e5-a04e-57f3d7b32808' anywhere
 | |
| in its '$.partlist'.
 | |
| 
 | |
| </p><blockquote><pre>
 | |
| SELECT DISTINCT json_extract(big.json,'$.id')
 | |
|   FROM big, json_tree(big.json, '$.partlist')
 | |
|  WHERE json_tree.key='uuid'
 | |
|    AND json_tree.value='6fa5181e-5721-11e5-a04e-57f3d7b32808';
 | |
| </pre></blockquote>
 | |
| 
 |