From 36894e63fb84ee6a8179009a99c5023a6994b533 Mon Sep 17 00:00:00 2001
From: kgs <kgs@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Date: Fri, 8 May 2009 19:54:37 +0000
Subject: [PATCH] setting up guides sync

git-svn-id: svn://svn.open-ils.org/ILS/trunk@13102 dcc99617-32d9-48b4-a31d-7c20da2025e4
---
 docs/Guides/compugrammar.xpr | 259 +++++++++++++++
 docs/Guides/grammar.html     | 151 +++++++++
 docs/Guides/grammar.xml      | 291 +++++++++++++++++
 docs/Guides/grammar2.html    |  56 ++++
 docs/Guides/grammar2.pdf     | Bin 0 -> 15319 bytes
 docs/Guides/grammar2.xml     | 227 +++++++++++++
 docs/Guides/grammar3.xml     | 755 +++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 1739 insertions(+)
 create mode 100644 docs/Guides/compugrammar.xpr
 create mode 100644 docs/Guides/grammar.html
 create mode 100644 docs/Guides/grammar.xml
 create mode 100644 docs/Guides/grammar2.html
 create mode 100644 docs/Guides/grammar2.pdf
 create mode 100644 docs/Guides/grammar2.xml
 create mode 100644 docs/Guides/grammar3.xml

diff --git a/docs/Guides/compugrammar.xpr b/docs/Guides/compugrammar.xpr
new file mode 100644
index 0000000000..6235c751e1
--- /dev/null
+++ b/docs/Guides/compugrammar.xpr
@@ -0,0 +1,259 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+    <meta>
+        <filters directoryPatterns="CVS" filePatterns=""
+            positiveFilePatterns="" showHiddenFiles="false"/>
+        <options/>
+    </meta>
+    <projectTree name="compugrammar.xpr">
+        <folder name="css">
+            <file
+                name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/css/sample1.css"/>
+            <file
+                name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/css/sample1.xhtml"/>
+            <file
+                name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/css/sample2.css"/>
+            <file
+                name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/css/sample2.xhtml"/>
+            <file
+                name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/css/sample3.css"/>
+            <file
+                name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/css/sample3.xhtml"
+            />
+        </folder>
+        <folder name="fo">
+            <folder name="Basic Font Attributes">
+                <file
+                    name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/fo/Basic%20Font%20Attributes/bold.fo"/>
+                <file
+                    name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/fo/Basic%20Font%20Attributes/bold.xml"
+                />
+            </folder>
+            <folder name="Block Properties">
+                <file
+                    name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/fo/Block%20Properties/borders.fo"/>
+                <file
+                    name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/fo/Block%20Properties/borders.xml"
+                />
+            </folder>
+            <folder name="Character Sets">
+                <file
+                    name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/fo/Character%20Sets/adobe-standard.fo"/>
+                <file
+                    name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/fo/Character%20Sets/adobe-standard.xml"
+                />
+            </folder>
+            <folder name="Extended Font Attributes">
+                <file
+                    name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/fo/Extended%20Font%20Attributes/aspect.fo"/>
+                <file
+                    name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/fo/Extended%20Font%20Attributes/aspect.xml"
+                />
+            </folder>
+            <folder name="Invoice">
+                <file
+                    name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/fo/Invoice/invoice.xml"/>
+                <file
+                    name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/fo/Invoice/invoice.xsd"/>
+                <file
+                    name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/fo/Invoice/invoice.xsl"
+                />
+            </folder>
+            <folder name="Miscellaneous">
+                <file
+                    name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/fo/Miscellaneous/fontAttributes.fo"/>
+                <file
+                    name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/fo/Miscellaneous/helloWorld.fo"/>
+                <file
+                    name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/fo/Miscellaneous/leaders.fo"/>
+                <file
+                    name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/fo/Miscellaneous/pageLayout.fo"/>
+                <file
+                    name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/fo/Miscellaneous/table.fo"
+                />
+            </folder>
+            <folder name="Paragraph Attributes">
+                <file
+                    name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/fo/Paragraph%20Attributes/pagebreak.fo"/>
+                <file
+                    name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/fo/Paragraph%20Attributes/pagebreak.xml"
+                />
+            </folder>
+            <folder name="Text Block Attributes">
+                <file
+                    name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/fo/Text%20Block%20Attributes/align.fo"/>
+                <file
+                    name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/fo/Text%20Block%20Attributes/align.xml"
+                />
+            </folder>
+            <file
+                name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/fo/macro.xsl"
+            />
+        </folder>
+        <folder name="nvdl">
+            <file
+                name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/nvdl/xhtml-xforms.nvdl"/>
+            <file
+                name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/nvdl/xhtml-xforms.xml"
+            />
+        </folder>
+        <folder name="relaxng">
+            <file
+                name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/relaxng/personal.rnc"/>
+            <file
+                name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/relaxng/personal.rng"/>
+            <file
+                name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/relaxng/personal.xml"
+            />
+        </folder>
+        <folder name="schematron">
+            <folder name="1.5">
+                <folder name="attributes">
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/attributes/followed-bad.xml"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/attributes/followed-good.xml"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/attributes/followed.dtd"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/attributes/followed.sch"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/attributes/length-bad.xml"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/attributes/length-bad1.xml"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/attributes/length-bad2.xml"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/attributes/length-good.xml"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/attributes/length.dtd"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/attributes/length.sch"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/attributes/name-bad.xml"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/attributes/name.dtd"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/attributes/name.sch"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/attributes/present-bad.xml"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/attributes/present.dtd"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/attributes/present.sch"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/attributes/required-bad1.xml"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/attributes/required-bad2.xml"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/attributes/required-good.xml"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/attributes/required.dtd"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/attributes/required.sch"
+                    />
+                </folder>
+                <folder name="author">
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/author/author.sch"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/author/source1.xml"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/author/source2.xml"
+                    />
+                </folder>
+                <folder name="paragraph">
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/paragraph/paragraph.sch"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/paragraph/source1.xml"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/paragraph/source2.xml"
+                    />
+                </folder>
+                <folder name="percent">
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/percent/percent-bad1.xml"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/percent/percent-bad2.xml"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/percent/percent-good.xml"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/percent/percent.dtd"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/percent/percent.sch"
+                    />
+                </folder>
+                <folder name="po">
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/po/po-bad.xml"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/po/po-schema.sch"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/po/po.xml"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/po/po.xsd"
+                    />
+                </folder>
+                <folder name="tournament">
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/tournament/tournament-schema.sch"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/tournament/Tournament.rng"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/tournament/Tournament.xml"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/1.5/tournament/Tournament.xsd"
+                    />
+                </folder>
+            </folder>
+            <folder name="iso">
+                <folder name="tournament">
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/iso/tournament/tournament-schema.sch"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/iso/tournament/Tournament.rng"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/iso/tournament/Tournament.xml"/>
+                    <file
+                        name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/schematron/iso/tournament/Tournament.xsd"
+                    />
+                </folder>
+            </folder>
+        </folder>
+        <folder name="svg">
+            <file
+                name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/svg/batik3D.svg"/>
+            <file
+                name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/svg/sales.xml"/>
+            <file
+                name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/svg/sales.xsl"
+            />
+        </folder>
+        <folder
+            path="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/dita/"/>
+        <folder
+            path="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/docbook/"/>
+        <folder
+            path="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/ooxml/"/>
+        <folder
+            path="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/tei/"/>
+        <folder
+            path="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/xhtml/"/>
+        <file
+            name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/personal-schema.css"/>
+        <file
+            name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/personal-schema.xml"/>
+        <file
+            name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/personal.css"/>
+        <file
+            name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/personal.dtd"/>
+        <file
+            name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/personal.xml"/>
+        <file
+            name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/personal.xsd"/>
+        <file
+            name="../../Documents%20and%20Settings/KAREN%20SCHNEIDER/OxygenXMLAuthor/samples/personal.xsl"
+        />
+    </projectTree>
+</project>
diff --git a/docs/Guides/grammar.html b/docs/Guides/grammar.html
new file mode 100644
index 0000000000..36587da957
--- /dev/null
+++ b/docs/Guides/grammar.html
@@ -0,0 +1,151 @@
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Grammar of JSON Queries</title><meta name="generator" content="DocBook XSL Stylesheets V1.74.3"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="article" lang="en"><div class="titlepage"><div><div><h1 class="title"><a name="id1165551"></a>Grammar of JSON Queries</h1></div><div><div class="author"><h3 class="author"><span class="firstname">Scott</span> <span class="surname">McKellar</span></h3></div></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="sect1"><a href="#id1165745">Introduction</a></span></dt><dt><span class="sect1"><a href="#id1165792">Primitives</a></span></dt><dt><span class="sect1"><a href="#id1165795">Query</a></span></dt></dl></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1165745"></a>Introduction</h2></div></div></div><p>
+			The format of this grammar approximates Extended Backus-Naur notation.  However it
+			is intended as input to human beings, not to parser generators such as Lex or
+			Yacc.  Do not expect formal rigor.  Sometimes narrative text will explain things
+			that are clumsy to express in formal notation.  More often, the text will restate
+			or summarize the formal productions.
+		</p><p>
+			Conventions:
+		</p><div class="orderedlist"><ol type="1"><li>
+				The grammar is a series of productions.
+			</li><li>
+				A production consists of a name, followed by "::=", followed by a
+				definition for the name.  The name identifies a grammatical construct that can
+				appear on the right side of another production.
+			</li><li>
+				Literals (including punctuation) are enclosed in single quotes, or in double
+				quotes if case is not significant.
+			</li><li>
+				A single quotation mark within a literal is escaped with a preceding backslash.
+			</li><li>
+				If a construct can be defined more than one way, then the alternatives may appear
+				in separate productions; or, they may appear in the same production, separated by
+				pipe symbols.  The choice between these representations is of only cosmetic
+				significance.
+			</li><li>
+				A construct enclosed within square brackets is optional.
+			</li><li>
+				A construct enclosed within curly braces may be repeated zero or more times.
+			</li><li>
+				JSON allows arbitrary white space between tokens.  To avoid ugly clutter, this
+				grammar ignores the optional white space.
+			</li><li>
+				In many cases a production defines a JSON object, i.e. a list of name-value pairs,
+				separated by commas.  Since the order of these name/value pairs is not significant,
+				the grammar will not try to show all the possible sequences.  In general it will
+				present the required pairs first, if any, followed by any optional elements.
+			</li></ol></div><p>
+			Since both EBNF and JSON use curly braces and square brackets, pay close attention to
+			whether these characters are in single quotes.  If they're in single quotes, they are
+			literal elements of the JSON notation.  Otherwise they are elements of the EBNF notation.
+		</p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1165792"></a>Primitives</h2></div></div></div><p>
+			We'll start by defining some primitives, to get them out of the way.  They're
+			mostly just what you would expect.
+		</p><table width="100%" cellpadding="5" bgcolor="#F5DCB3" border="1" class="productionset" summary="EBNF"><tr><td><table border="0" width="99%" cellpadding="0" bgcolor="#F5DCB3" class="productionset" summary="EBNF productions"><tr><td align="left" valign="top" width="3%">[1]</td><td align="right" valign="top" width="10%">
+					string
+				</td><td valign="top" width="5%" align="center"><code>::=</code></td><td valign="top" width="52%">
+					'&#8221;' chars '&#8221;'
+				</td><td align="left" valign="top" width="30%"> </td></tr><tr><td align="left" valign="top" width="3%">[2]</td><td align="right" valign="top" width="10%">
+					chars
+				</td><td valign="top" width="5%" align="center"><code>::=</code></td><td valign="top" width="52%">
+					any valid sequence of UTF-8 characters, with certain special characters
+					escaped according to JSON rules
+				</td><td align="left" valign="top" width="30%"> </td></tr><tr><td align="left" valign="top" width="3%">[3]</td><td align="right" valign="top" width="10%">
+					integer_literal
+				</td><td valign="top" width="5%" align="center"><code>::=</code></td><td valign="top" width="52%">
+					[ sign ] digit { digit }
+				</td><td align="left" valign="top" width="30%"> </td></tr><tr><td align="left" valign="top" width="3%">[4]</td><td align="right" valign="top" width="10%">
+					sign
+				</td><td valign="top" width="5%" align="center"><code>::=</code></td><td valign="top" width="52%">
+					'+' | '-'
+				</td><td align="left" valign="top" width="30%"> </td></tr><tr><td align="left" valign="top" width="3%">[5]</td><td align="right" valign="top" width="10%">
+					digit
+				</td><td valign="top" width="5%" align="center"><code>::=</code></td><td valign="top" width="52%">
+				</td><td align="left" valign="top" width="30%"> </td></tr><tr><td align="left" valign="top" width="3%">[6]</td><td align="right" valign="top" width="10%">
+					integer_string
+				</td><td valign="top" width="5%" align="center"><code>::=</code></td><td valign="top" width="52%">
+					'&#8221;'  integer_literal  '&#8221;'
+				</td><td align="left" valign="top" width="30%"> </td></tr><tr><td align="left" valign="top" width="3%">[7]</td><td align="right" valign="top" width="10%">
+					integer
+				</td><td valign="top" width="5%" align="center"><code>::=</code></td><td valign="top" width="52%">
+					integer_literal  |  integer_string
+				</td><td align="left" valign="top" width="30%"> </td></tr><tr><td align="left" valign="top" width="3%">[8]</td><td align="right" valign="top" width="10%">
+					number
+				</td><td valign="top" width="5%" align="center"><code>::=</code></td><td valign="top" width="52%">
+					any valid character sequence that is numeric according to JSON rules
+				</td><td align="left" valign="top" width="30%"> </td></tr></table></td></tr></table><p>
+			When json_query requires an integral value, it will usually accept a quoted string and
+			convert it to an integer by brute force &#8211; to zero if necessary.  Likewise it may
+			truncate a floating point number to an integral value.  Scientific notation will be
+			accepted but may not give the intended results.
+		</p><table width="100%" cellpadding="5" bgcolor="#F5DCB3" border="1" class="productionset" summary="EBNF"><tr><td><table border="0" width="99%" cellpadding="0" bgcolor="#F5DCB3" class="productionset" summary="EBNF productions"><tr><td align="left" valign="top" width="3%">[9]</td><td align="right" valign="top" width="10%">
+					boolean
+				</td><td valign="top" width="5%" align="center"><code>::=</code></td><td valign="top" width="52%">
+					'true'  |  'false'  |  string  |  number
+				</td><td align="left" valign="top" width="30%"> </td></tr></table></td></tr></table><p>
+			The preferred way to encode a boolean is with the JSON reserved word true or false,
+			in lower case without quotation marks.  The string &#8220;<code class="literal">trueK</code>&#8221;, in
+			upper, lower, or mixed case, is another way to encode true.  Any other string
+			evaluates to false.
+		</p><p>
+			As an accommodation to perl, numbers may be used as booleans.  A numeric value of 1
+			means true, and any other numeric value means false.
+		</p><p>
+			Any other valid JSON value, such as an array, will be accepted as a boolean but interpreted
+			as false.
+		</p><p>
+			The last couple of primitives aren't really very primitive, but we introduce them here
+			for convenience:
+		</p><table width="100%" cellpadding="5" bgcolor="#F5DCB3" border="1" class="productionset" summary="EBNF"><tr><td><table border="0" width="99%" cellpadding="0" bgcolor="#F5DCB3" class="productionset" summary="EBNF productions"><tr><td align="left" valign="top" width="3%">[10]</td><td align="right" valign="top" width="10%">
+					class_name
+				</td><td valign="top" width="5%" align="center"><code>::=</code></td><td valign="top" width="52%">
+					string
+				</td><td align="left" valign="top" width="30%"> </td></tr></table></td></tr></table><p>
+			A class_name is a special case of a string: the name of a class as defined
+			by the IDL.  The class may refer either to a database table or to a
+			source_definition, which is a subquery.
+		</p><table width="100%" cellpadding="5" bgcolor="#F5DCB3" border="1" class="productionset" summary="EBNF"><tr><td><table border="0" width="99%" cellpadding="0" bgcolor="#F5DCB3" class="productionset" summary="EBNF productions"><tr><td align="left" valign="top" width="3%">[11]</td><td align="right" valign="top" width="10%">
+					field_name
+				</td><td valign="top" width="5%" align="center"><code>::=</code></td><td valign="top" width="52%">
+					string
+				</td><td align="left" valign="top" width="30%"> </td></tr></table></td></tr></table><p>
+			A field_name is another special case of a string: the name of a non-virtual
+			field as defined by the IDL.  A field_name is also a column name for the
+			table corresponding to the relevant class.
+		</p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id1165795"></a>Query</h2></div></div></div><p>
+			The following production applies not only to the main query but also to
+			most subqueries.
+		</p><table width="100%" cellpadding="5" bgcolor="#F5DCB3" border="1" class="productionset" summary="EBNF"><tr><td><table border="0" width="99%" cellpadding="0" bgcolor="#F5DCB3" class="productionset" summary="EBNF productions"><tr><td align="left" valign="top" width="3%">[12]</td><td align="right" valign="top" width="10%">
+					query
+				</td><td valign="top" width="5%" align="center"><code>::=</code></td><td valign="top" width="52%">
+					'{'<br>
+					'&#8221;from&#8221;'  ':'  from_list<br>
+					[ ','  '&#8221;select&#8221;'    ':'  select_list ]<br>
+					[ ','  '&#8221;where&#8221;'     ':'  where_condition ]<br>
+					[ ','  '&#8221;having&#8221;'    ':'  where_condition ]<br>
+					[ ','  '&#8221;order_by&#8221;'  ':'  order_by_list ]<br>
+					[ ','  '&#8221;limit&#8221;'     ':'  integer ]<br>
+					[ ','  '&#8221;offset&#8221;'    ':'  integer ]<br>
+					[ ','  '&#8221;distinct&#8221;'  ':'  boolean ]<br>
+					[ ','  '&#8221;no_i18n&#8221;'   ':'  boolean ]<br>
+					'}'
+				</td><td align="left" valign="top" width="30%"> </td></tr></table></td></tr></table><p>
+			Except for the <code class="literal">&#8220;distinct&#8221;</code> and <code class="literal">&#8220;no_i18n&#8221;</code>
+			entries, each name/value pair represents a major clause of the SELECT statement.
+			The name/value pairs may appear in any order.
+		</p><p>
+			There is no name/value pair for the GROUP BY clause, because json_query
+			generates it automatically according to information encoded elsewhere.
+		</p><p>
+			The <code class="literal">&#8220;distinct&#8221;</code> entry, if present and true, tells json_query
+			that it may have to create a GROUP BY clause.  If not present, it defaults to false.
+		</p><p>
+			The <code class="literal">&#8220;no_i18n&#8221;</code> entry, if present and true, tells json_query to
+			suppress internationalization.  If not present, it defaults to false.  (Note that
+			<code class="literal">&#8220;no_i18n&#8221;</code> contains the digit one, not the letter ell.)
+		</p><p>
+			The values for <code class="literal">&#8220;limit&#8221;</code> and <code class="literal">&#8220;offset&#8221;</code>
+			provide the arguments of the LIMIT and OFFSET clauses, respectively, of the
+			SQL statement.  Each value should be non-negative, if present, or else the
+			SQL won't work.
+		</p></div></div></body></html>
diff --git a/docs/Guides/grammar.xml b/docs/Guides/grammar.xml
new file mode 100644
index 0000000000..2601682f90
--- /dev/null
+++ b/docs/Guides/grammar.xml
@@ -0,0 +1,291 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V4.5//EN"
+	"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<article xmlns="http://docbook.org/ns/docbook">
+
+	<artheader>
+		<title>Grammar of JSON Queries</title>
+		<author>
+			<firstname>Scott</firstname>
+			<surname>McKellar</surname>
+		</author>
+	</artheader>
+
+	<sect1><title>Introduction</title>
+		<para>
+			The format of this grammar approximates Extended Backus-Naur notation.  However it
+			is intended as input to human beings, not to parser generators such as Lex or
+			Yacc.  Do not expect formal rigor.  Sometimes narrative text will explain things
+			that are clumsy to express in formal notation.  More often, the text will restate
+			or summarize the formal productions.
+		</para>
+		<para>
+			Conventions:
+		</para>
+		<orderedlist>
+			<listitem>
+				The grammar is a series of productions.
+			</listitem>
+			<listitem>
+				A production consists of a name, followed by "::=", followed by a
+				definition for the name.  The name identifies a grammatical construct that can
+				appear on the right side of another production.
+			</listitem>
+			<listitem>
+				Literals (including punctuation) are enclosed in single quotes, or in double
+				quotes if case is not significant.
+			</listitem>
+			<listitem>
+				A single quotation mark within a literal is escaped with a preceding backslash.
+			</listitem>
+			<listitem>
+				If a construct can be defined more than one way, then the alternatives may appear
+				in separate productions; or, they may appear in the same production, separated by
+				pipe symbols.  The choice between these representations is of only cosmetic
+				significance.
+			</listitem>
+			<listitem>
+				A construct enclosed within square brackets is optional.
+			</listitem>
+			<listitem>
+				A construct enclosed within curly braces may be repeated zero or more times.
+			</listitem>
+			<listitem>
+				JSON allows arbitrary white space between tokens.  To avoid ugly clutter, this
+				grammar ignores the optional white space.
+			</listitem>
+			<listitem>
+				In many cases a production defines a JSON object, i.e. a list of name-value pairs,
+				separated by commas.  Since the order of these name/value pairs is not significant,
+				the grammar will not try to show all the possible sequences.  In general it will
+				present the required pairs first, if any, followed by any optional elements.
+			</listitem>
+		</orderedlist>
+
+		<para>
+			Since both EBNF and JSON use curly braces and square brackets, pay close attention to
+			whether these characters are in single quotes.  If they're in single quotes, they are
+			literal elements of the JSON notation.  Otherwise they are elements of the EBNF notation.
+		</para>
+	</sect1>
+
+	<sect1><title>Primitives</title>
+		<para>
+			We'll start by defining some primitives, to get them out of the way.  They're
+			mostly just what you would expect.
+		</para>
+
+		<productionset>
+			<production>
+				<lhs>
+					string
+				</lhs>
+				<rhs>
+					'”' chars '”'
+				</rhs>
+			</production>
+
+			<production>
+				<lhs>
+					chars
+				</lhs>
+				<rhs>
+					any valid sequence of UTF-8 characters, with certain special characters
+					escaped according to JSON rules
+				</rhs>
+			</production>
+
+			<production>
+				<lhs>
+					integer_literal
+				</lhs>
+				<rhs>
+					[ sign ] digit { digit }
+				</rhs>
+			</production>
+
+			<production>
+				<lhs>
+					sign
+				</lhs>
+				<rhs>
+					'+' | '-'
+				</rhs>
+			</production>
+
+			<production>
+				<lhs>
+					digit
+				</lhs>
+				digit =  '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
+				<rhs>
+				</rhs>
+			</production>
+
+			<production>
+				<lhs>
+					integer_string
+				</lhs>
+				<rhs>
+					'”'  integer_literal  '”'
+				</rhs>
+			</production>
+
+			<production>
+				<lhs>
+					integer
+				</lhs>
+				<rhs>
+					integer_literal  |  integer_string
+				</rhs>
+			</production>
+
+			<production>
+				<lhs>
+					number
+				</lhs>
+				<rhs>
+					any valid character sequence that is numeric according to JSON rules
+				</rhs>
+			</production>
+
+		</productionset>
+
+		<para>
+			When json_query requires an integral value, it will usually accept a quoted string and
+			convert it to an integer by brute force – to zero if necessary.  Likewise it may
+			truncate a floating point number to an integral value.  Scientific notation will be
+			accepted but may not give the intended results.
+		</para>
+
+		<productionset>
+
+			<production>
+				<lhs>
+					boolean
+				</lhs>
+				<rhs>
+					'true'  |  'false'  |  string  |  number
+				</rhs>
+			</production>
+
+		</productionset>
+
+		<para>
+			The preferred way to encode a boolean is with the JSON reserved word true or false,
+			in lower case without quotation marks.  The string “<literal>true</literal>”, in
+			upper, lower, or mixed case, is another way to encode true.  Any other string
+			evaluates to false.
+		</para>
+		<para>
+			As an accommodation to perl, numbers may be used as booleans.  A numeric value of 1
+			means true, and any other numeric value means false.
+		</para>
+		<para>
+			Any other valid JSON value, such as an array, will be accepted as a boolean but interpreted
+			as false.
+		</para>
+		<para>
+			The last couple of primitives aren't really very primitive, but we introduce them here
+			for convenience:
+		</para>
+
+		<productionset>
+
+			<production>
+				<lhs>
+					class_name
+				</lhs>
+				<rhs>
+					string
+				</rhs>
+			</production>
+
+		</productionset>
+
+		<para>
+			A class_name is a special case of a string: the name of a class as defined
+			by the IDL.  The class may refer either to a database table or to a
+			source_definition, which is a subquery.
+		</para>
+
+		<productionset>
+
+			<production>
+				<lhs>
+					field_name
+				</lhs>
+				<rhs>
+					string
+				</rhs>
+			</production>
+
+		</productionset>
+
+		<para>
+			A field_name is another special case of a string: the name of a non-virtual
+			field as defined by the IDL.  A field_name is also a column name for the
+			table corresponding to the relevant class.
+		</para>
+
+	</sect1>
+
+	<sect1><title>Query</title>
+
+		<para>
+			The following production applies not only to the main query but also to
+			most subqueries.
+		</para>
+
+		<productionset>
+
+			<production>
+				<lhs>
+					query
+				</lhs>
+				<rhs>
+					'{'<sbr/>
+					'”from”'  ':'  from_list<sbr/>
+					[ ','  '”select”'    ':'  select_list ]<sbr/>
+					[ ','  '”where”'     ':'  where_condition ]<sbr/>
+					[ ','  '”having”'    ':'  where_condition ]<sbr/>
+					[ ','  '”order_by”'  ':'  order_by_list ]<sbr/>
+					[ ','  '”limit”'     ':'  integer ]<sbr/>
+					[ ','  '”offset”'    ':'  integer ]<sbr/>
+					[ ','  '”distinct”'  ':'  boolean ]<sbr/>
+					[ ','  '”no_i18n”'   ':'  boolean ]<sbr/>
+					'}'
+				</rhs>
+			</production>
+
+		</productionset>
+
+		<para>
+			Except for the <literal>“distinct”</literal> and <literal>“no_i18n”</literal>
+			entries, each name/value pair represents a major clause of the SELECT statement.
+			The name/value pairs may appear in any order.
+		</para>
+		<para>
+			There is no name/value pair for the GROUP BY clause, because json_query
+			generates it automatically according to information encoded elsewhere.
+		</para>
+		<para>
+			The <literal>“distinct”</literal> entry, if present and true, tells json_query
+			that it may have to create a GROUP BY clause.  If not present, it defaults to false.
+		</para>
+		<para>
+			The <literal>“no_i18n”</literal> entry, if present and true, tells json_query to
+			suppress internationalization.  If not present, it defaults to false.  (Note that
+			<literal>“no_i18n”</literal> contains the digit one, not the letter ell.)
+		</para>
+		<para>
+			The values for <literal>“limit”</literal> and <literal>“offset”</literal>
+			provide the arguments of the LIMIT and OFFSET clauses, respectively, of the
+			SQL statement.  Each value should be non-negative, if present, or else the
+			SQL won't work.
+		</para>
+
+	</sect1>
+
+</article>
diff --git a/docs/Guides/grammar2.html b/docs/Guides/grammar2.html
new file mode 100644
index 0000000000..163431bf89
--- /dev/null
+++ b/docs/Guides/grammar2.html
@@ -0,0 +1,56 @@
+<html><head>
+      <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+   <title>Grammar of JSON Queries</title><meta name="generator" content="DocBook XSL-NS Stylesheets V1.74.3-pre"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="article" lang="en"><div class="titlepage"><div><div><h2 class="title"><a name="d0e1"></a>Grammar of JSON Queries</h2></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="sect1"><a href="#d0e28">Introduction</a></span></dt><dt><span class="sect1"><a href="#d0e65">Primitives</a></span></dt><dt><span class="sect1"><a href="#d0e194">Query</a></span></dt></dl></div><p>
+		<span class="author"><span class="firstname">Scott</span> <span class="surname">McKellar</span></span>
+	</p><p>
+		
+	</p><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d0e28"></a>Introduction</h2></div></div></div><p> The format of this grammar approximates Extended Backus-Naur notation. However it is
+			intended as input to human beings, not to parser generators such as Lex or Yacc. Do not
+			expect formal rigor. Sometimes narrative text will explain things that are clumsy to
+			express in formal notation. More often, the text will restate or summarize the formal
+			productions. </p><p> Conventions: </p><div class="orderedlist"><ol type="1"><li><p>The grammar is a series of productions.</p></li><li><p>A production consists of a name, followed by "::=", followed by a definition
+					for the name. The name identifies a grammatical construct that can appear on the
+					right side of another production.</p></li><li><p>Literals (including punctuation) are enclosed in 'single quotes', or in
+					"double quotes" if case is not significant.</p></li><li><p>A single quotation mark within a literal is escaped with a preceding
+					backslash: 'dog\'s tail'.</p></li><li><p>If a construct can be defined more than one way, then the alternatives may
+					appear in separate productions; or, they may appear in the same production,
+					separated by pipe symbols. The choice between these representations is of only
+					cosmetic significance.</p></li><li><p>A construct enclosed within square brackets is optional.</p></li><li><p>A construct enclosed within curly braces may be repeated zero or more
+					times.</p></li><li><p>JSON allows arbitrary white space between tokens. To avoid ugly clutter, this
+					grammar ignores the optional white space. </p></li><li><p>In many cases a production defines a JSON object, i.e. a list of name-value
+					pairs, separated by commas. Since the order of these name/value pairs is not
+					significant, the grammar will not try to show all the possible sequences. In
+					general it will present the required pairs first, if any, followed by any
+					optional elements.</p></li></ol></div><p> Since both EBNF and JSON use curly braces and square brackets, pay close attention to
+			whether these characters are in single quotes. If they're in single quotes, they are
+			literal elements of the JSON notation. Otherwise they are elements of the EBNF notation.
+		</p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d0e65"></a>Primitives</h2></div></div></div><p> We'll start by defining some primitives, to get them out of the way. They're mostly
+			just what you would expect. </p><table width="100%" cellpadding="5" bgcolor="#F5DCB3" border="1" class="productionset" summary="EBNF"><tr><td><table border="0" width="99%" cellpadding="0" bgcolor="#F5DCB3" class="productionset" summary="EBNF productions"><tr><td align="left" valign="top" width="3%">[1]</td><td align="right" valign="top" width="10%"><a name="ebnf.string"></a> string </td><td valign="top" width="5%" align="center"><code>::=</code></td><td valign="top" width="52%"> '"' chars '"' </td><td align="left" valign="top" width="30%">&nbsp;</td></tr><tr><td align="left" valign="top" width="3%">[2]</td><td align="right" valign="top" width="10%"><a name="ebnf.chars"></a> chars </td><td valign="top" width="5%" align="center"><code>::=</code></td><td valign="top" width="52%"> any valid sequence of UTF-8 characters, with certain special characters
+					escaped according to JSON rules </td><td align="left" valign="top" width="30%">&nbsp;</td></tr><tr><td align="left" valign="top" width="3%">[3]</td><td align="right" valign="top" width="10%"><a name="ebnf.int_literal"></a> integer_literal </td><td valign="top" width="5%" align="center"><code>::=</code></td><td valign="top" width="52%"> [ sign ] digit { digit } </td><td align="left" valign="top" width="30%">&nbsp;</td></tr><tr><td align="left" valign="top" width="3%">[4]</td><td align="right" valign="top" width="10%"><a name="ebnf.sign"></a> sign </td><td valign="top" width="5%" align="center"><code>::=</code></td><td valign="top" width="52%"> '+' | '-' </td><td align="left" valign="top" width="30%">&nbsp;</td></tr><tr><td align="left" valign="top" width="3%">[5]</td><td align="right" valign="top" width="10%"><a name="ebnf.digits"></a> digit </td><td valign="top" width="5%" align="center"><code>::=</code></td><td valign="top" width="52%">digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'</td><td align="left" valign="top" width="30%">&nbsp;</td></tr><tr><td align="left" valign="top" width="3%">[6]</td><td align="right" valign="top" width="10%"><a name="ebnf.int_string"></a> integer_string </td><td valign="top" width="5%" align="center"><code>::=</code></td><td valign="top" width="52%"> '"' integer_literal '"' </td><td align="left" valign="top" width="30%">&nbsp;</td></tr><tr><td align="left" valign="top" width="3%">[7]</td><td align="right" valign="top" width="10%"><a name="ebnf.int"></a> integer </td><td valign="top" width="5%" align="center"><code>::=</code></td><td valign="top" width="52%"> integer_literal | integer_string </td><td align="left" valign="top" width="30%">&nbsp;</td></tr><tr><td align="left" valign="top" width="3%">[8]</td><td align="right" valign="top" width="10%"><a name="ebnf.num"></a> number </td><td valign="top" width="5%" align="center"><code>::=</code></td><td valign="top" width="52%"> any valid character sequence that is numeric according to JSON rules </td><td align="left" valign="top" width="30%">&nbsp;</td></tr></table></td></tr></table><p> When json_query requires an integral value, it will usually accept a quoted string
+			and convert it to an integer by brute force &#8211; to zero if necessary. Likewise it may
+			truncate a floating point number to an integral value. Scientific notation will be
+			accepted but may not give the intended results. </p><table width="100%" cellpadding="5" bgcolor="#F5DCB3" border="1" class="productionset" summary="EBNF"><tr><td><table border="0" width="99%" cellpadding="0" bgcolor="#F5DCB3" class="productionset" summary="EBNF productions"><tr><td align="left" valign="top" width="3%">[9]</td><td align="right" valign="top" width="10%"><a name="ebnf.bool"></a> boolean </td><td valign="top" width="5%" align="center"><code>::=</code></td><td valign="top" width="52%"> 'true' | 'false' | string | number </td><td align="left" valign="top" width="30%">&nbsp;</td></tr></table></td></tr></table><p> The preferred way to encode a boolean is with the JSON reserved word true or false,
+			in lower case without quotation marks. The string <code class="literal">true</code>, in upper,
+			lower, or mixed case, is another way to encode true. Any other string evaluates to
+			false. </p><p> As an accommodation to perl, numbers may be used as booleans. A numeric value of 1
+			means true, and any other numeric value means false. </p><p> Any other valid JSON value, such as an array, will be accepted as a boolean but
+			interpreted as false. </p><p> The last couple of primitives aren't really very primitive, but we introduce them
+			here for convenience: </p><table width="100%" cellpadding="5" bgcolor="#F5DCB3" border="1" class="productionset" summary="EBNF"><tr><td><table border="0" width="99%" cellpadding="0" bgcolor="#F5DCB3" class="productionset" summary="EBNF productions"><tr><td align="left" valign="top" width="3%">[10]</td><td align="right" valign="top" width="10%"><a name="ebnf.classname"></a> class_name </td><td valign="top" width="5%" align="center"><code>::=</code></td><td valign="top" width="52%"> string </td><td align="left" valign="top" width="30%">&nbsp;</td></tr></table></td></tr></table><p> A class_name is a special case of a string: the name of a class as defined by the
+			IDL. The class may refer either to a database table or to a source_definition, which is
+			a subquery. </p><table width="100%" cellpadding="5" bgcolor="#F5DCB3" border="1" class="productionset" summary="EBNF"><tr><td><table border="0" width="99%" cellpadding="0" bgcolor="#F5DCB3" class="productionset" summary="EBNF productions"><tr><td align="left" valign="top" width="3%">[11]</td><td align="right" valign="top" width="10%"><a name="ebnf.field_name"></a> field_name </td><td valign="top" width="5%" align="center"><code>::=</code></td><td valign="top" width="52%"> string </td><td align="left" valign="top" width="30%">&nbsp;</td></tr></table></td></tr></table><p> A field_name is another special case of a string: the name of a non-virtual field as
+			defined by the IDL. A field_name is also a column name for the table corresponding to
+			the relevant class. </p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="d0e194"></a>Query</h2></div></div></div><p> The following production applies not only to the main query but also to most
+			subqueries. </p><table width="100%" cellpadding="5" bgcolor="#F5DCB3" border="1" class="productionset" summary="EBNF"><tr><td><table border="0" width="99%" cellpadding="0" bgcolor="#F5DCB3" class="productionset" summary="EBNF productions"><tr><td align="left" valign="top" width="3%">[12]</td><td align="right" valign="top" width="10%"><a name="ebnf.query"></a> query </td><td valign="top" width="5%" align="center"><code>::=</code></td><td valign="top" width="52%"> '{'<br> '"from"' ':' from_list<br> [ ',' '"select"' ':' select_list
+					]<br> [ ',' '"where"' ':' where_condition ]<br> [ ',' '"having"' ':'
+					where_condition ]<br> [ ',' '"order_by"' ':' order_by_list ]<br> [ ','
+					'"limit"' ':' integer ]<br> [ ',' '"offset"' ':' integer ]<br> [ ','
+					'"distinct"' ':' boolean ]<br> [ ',' '"no_i18n"' ':' boolean ]<br> '}'
+				</td><td align="left" valign="top" width="30%">&nbsp;</td></tr></table></td></tr></table><p> Except for the <code class="literal">"distinct"</code> and <code class="literal">no_i18n</code> entries,
+			each name/value pair represents a major clause of the SELECT statement. The name/value
+			pairs may appear in any order. </p><p> There is no name/value pair for the GROUP BY clause, because json_query generates it
+			automatically according to information encoded elsewhere. </p><p> The <code class="literal">"distinct"</code> entry, if present and true, tells json_query that
+			it may have to create a GROUP BY clause. If not present, it defaults to false. </p><p> The <code class="literal">"no_i18n"</code> entry, if present and true, tells json_query to
+			suppress internationalization. If not present, it defaults to false. (Note that
+				<code class="literal">"no_i18n"</code> contains the digit one, not the letter ell.) </p><p> The values for <code class="literal">limit</code> and <code class="literal">offset</code> provide the
+			arguments of the LIMIT and OFFSET clauses, respectively, of the SQL statement. Each
+			value should be non-negative, if present, or else the SQL won't work. </p></div></div></body></html>
\ No newline at end of file
diff --git a/docs/Guides/grammar2.pdf b/docs/Guides/grammar2.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..cc42294a17bd5c000aa045fc3919e6bea3963786
GIT binary patch
literal 15319
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

literal 0
HcmV?d00001

diff --git a/docs/Guides/grammar2.xml b/docs/Guides/grammar2.xml
new file mode 100644
index 0000000000..5dd2215185
--- /dev/null
+++ b/docs/Guides/grammar2.xml
@@ -0,0 +1,227 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<article version="5.0" xmlns="http://docbook.org/ns/docbook"
+	xmlns:xi="http://www.w3.org/2003/XInclude" xmlns:xlink="http://www.w3.org/1999/xlink">
+
+	<title>Grammar of JSON Queries</title>
+
+	<para>
+		<author>
+			<personname>
+				<firstname>Scott</firstname>
+				<surname>McKellar</surname>
+			</personname>
+			<affiliation>
+				<orgname>Equinox Software, Inc.</orgname>
+			</affiliation>
+		</author>
+	</para>
+
+	<para>
+		<info>
+			<copyright>
+				<year>2009</year>
+				<holder>Creative Commons Attribution-Share Alike 3.0 United States License.</holder>
+			</copyright>
+		</info>
+	</para>
+
+
+
+	<sect1>
+		<title>Introduction</title>
+		<para> The format of this grammar approximates Extended Backus-Naur notation. However it is
+			intended as input to human beings, not to parser generators such as Lex or Yacc. Do not
+			expect formal rigor. Sometimes narrative text will explain things that are clumsy to
+			express in formal notation. More often, the text will restate or summarize the formal
+			productions. </para>
+		<para> Conventions: </para>
+		<orderedlist>
+			<listitem>
+				<para>The grammar is a series of productions.</para>
+			</listitem>
+			<listitem>
+				<para>A production consists of a name, followed by "::=", followed by a definition
+					for the name. The name identifies a grammatical construct that can appear on the
+					right side of another production.</para>
+			</listitem>
+			<listitem>
+				<para>Literals (including punctuation) are enclosed in 'single quotes', or in
+					"double quotes" if case is not significant.</para>
+			</listitem>
+			<listitem>
+				<para>A single quotation mark within a literal is escaped with a preceding
+					backslash: 'dog\'s tail'.</para>
+			</listitem>
+			<listitem>
+				<para>If a construct can be defined more than one way, then the alternatives may
+					appear in separate productions; or, they may appear in the same production,
+					separated by pipe symbols. The choice between these representations is of only
+					cosmetic significance.</para>
+			</listitem>
+			<listitem>
+				<para>A construct enclosed within square brackets is optional.</para>
+			</listitem>
+			<listitem>
+				<para>A construct enclosed within curly braces may be repeated zero or more
+					times.</para>
+			</listitem>
+			<listitem>
+				<para>JSON allows arbitrary white space between tokens. To avoid ugly clutter, this
+					grammar ignores the optional white space. </para>
+			</listitem>
+			<listitem>
+				<para>In many cases a production defines a JSON object, i.e. a list of name-value
+					pairs, separated by commas. Since the order of these name/value pairs is not
+					significant, the grammar will not try to show all the possible sequences. In
+					general it will present the required pairs first, if any, followed by any
+					optional elements.</para>
+			</listitem>
+		</orderedlist>
+
+		<para> Since both EBNF and JSON use curly braces and square brackets, pay close attention to
+			whether these characters are in single quotes. If they're in single quotes, they are
+			literal elements of the JSON notation. Otherwise they are elements of the EBNF notation.
+		</para>
+	</sect1>
+
+	<sect1>
+		<title>Primitives</title>
+		<para> We'll start by defining some primitives, to get them out of the way. They're mostly
+			just what you would expect. </para>
+
+		<productionset>
+			<production xml:id="ebnf.string">
+				<lhs> string </lhs>
+				<rhs> '"' chars '"' </rhs>
+			</production>
+
+			<production xml:id="ebnf.chars">
+				<lhs> chars </lhs>
+				<rhs> any valid sequence of UTF-8 characters, with certain special characters
+					escaped according to JSON rules </rhs>
+			</production>
+
+			<production xml:id="ebnf.int_literal">
+				<lhs> integer_literal </lhs>
+				<rhs> [ sign ] digit { digit } </rhs>
+			</production>
+
+			<production xml:id="ebnf.sign">
+				<lhs> sign </lhs>
+				<rhs> '+' | '-' </rhs>
+			</production>
+
+			<production xml:id="ebnf.digits">
+				<lhs> digit </lhs>
+				<rhs>digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'</rhs>
+			</production>
+
+			<production xml:id="ebnf.int_string">
+				<lhs> integer_string </lhs>
+				<rhs> '"' integer_literal '"' </rhs>
+			</production>
+
+			<production xml:id="ebnf.int">
+				<lhs> integer </lhs>
+				<rhs> integer_literal | integer_string </rhs>
+			</production>
+
+			<production xml:id="ebnf.num">
+				<lhs> number </lhs>
+				<rhs> any valid character sequence that is numeric according to JSON rules </rhs>
+			</production>
+
+		</productionset>
+
+		<para> When json_query requires an integral value, it will usually accept a quoted string
+			and convert it to an integer by brute force – to zero if necessary. Likewise it may
+			truncate a floating point number to an integral value. Scientific notation will be
+			accepted but may not give the intended results. </para>
+
+		<productionset>
+
+			<production xml:id="ebnf.bool">
+				<lhs> boolean </lhs>
+				<rhs> 'true' | 'false' | string | number </rhs>
+			</production>
+
+		</productionset>
+
+		<para> The preferred way to encode a boolean is with the JSON reserved word true or false,
+			in lower case without quotation marks. The string <literal>true</literal>, in upper,
+			lower, or mixed case, is another way to encode true. Any other string evaluates to
+			false. </para>
+		<para> As an accommodation to perl, numbers may be used as booleans. A numeric value of 1
+			means true, and any other numeric value means false. </para>
+		<para> Any other valid JSON value, such as an array, will be accepted as a boolean but
+			interpreted as false. </para>
+		<para> The last couple of primitives aren't really very primitive, but we introduce them
+			here for convenience: </para>
+
+		<productionset>
+
+			<production xml:id="ebnf.classname">
+				<lhs> class_name </lhs>
+				<rhs> string </rhs>
+			</production>
+
+		</productionset>
+
+		<para> A class_name is a special case of a string: the name of a class as defined by the
+			IDL. The class may refer either to a database table or to a source_definition, which is
+			a subquery. </para>
+
+		<productionset>
+
+			<production xml:id="ebnf.field_name">
+				<lhs> field_name </lhs>
+				<rhs> string </rhs>
+			</production>
+
+		</productionset>
+
+		<para> A field_name is another special case of a string: the name of a non-virtual field as
+			defined by the IDL. A field_name is also a column name for the table corresponding to
+			the relevant class. </para>
+
+	</sect1>
+
+	<sect1>
+		<title>Query</title>
+
+		<para> The following production applies not only to the main query but also to most
+			subqueries. </para>
+
+		<productionset>
+
+			<production xml:id="ebnf.query">
+				<lhs> query </lhs>
+				<rhs> '{'<sbr/> '"from"' ':' from_list<sbr/> [ ',' '"select"' ':' select_list
+					]<sbr/> [ ',' '"where"' ':' where_condition ]<sbr/> [ ',' '"having"' ':'
+					where_condition ]<sbr/> [ ',' '"order_by"' ':' order_by_list ]<sbr/> [ ','
+					'"limit"' ':' integer ]<sbr/> [ ',' '"offset"' ':' integer ]<sbr/> [ ','
+					'"distinct"' ':' boolean ]<sbr/> [ ',' '"no_i18n"' ':' boolean ]<sbr/> '}'
+				</rhs>
+			</production>
+
+		</productionset>
+
+		<para> Except for the <literal>"distinct"</literal> and <literal>no_i18n</literal> entries,
+			each name/value pair represents a major clause of the SELECT statement. The name/value
+			pairs may appear in any order. </para>
+		<para> There is no name/value pair for the GROUP BY clause, because json_query generates it
+			automatically according to information encoded elsewhere. </para>
+		<para> The <literal>"distinct"</literal> entry, if present and true, tells json_query that
+			it may have to create a GROUP BY clause. If not present, it defaults to false. </para>
+		<para> The <literal>"no_i18n"</literal> entry, if present and true, tells json_query to
+			suppress internationalization. If not present, it defaults to false. (Note that
+				<literal>"no_i18n"</literal> contains the digit one, not the letter ell.) </para>
+		<para> The values for <literal>limit</literal> and <literal>offset</literal> provide the
+			arguments of the LIMIT and OFFSET clauses, respectively, of the SQL statement. Each
+			value should be non-negative, if present, or else the SQL won't work. </para>
+
+	</sect1>
+
+
+</article>
diff --git a/docs/Guides/grammar3.xml b/docs/Guides/grammar3.xml
new file mode 100644
index 0000000000..32b6e22438
--- /dev/null
+++ b/docs/Guides/grammar3.xml
@@ -0,0 +1,755 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V4.5//EN"
+	"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
+
+<article xmlns="http://docbook.org/ns/docbook">
+
+	<artheader>
+		<title>Grammar of JSON Queries</title>
+		<author>
+			<firstname>Scott</firstname>
+			<surname>McKellar</surname>
+		</author>
+	</artheader>
+
+	<sect1><title>Introduction</title>
+		<para>
+			The format of this grammar approximates Extended Backus-Naur notation.  However it
+			is intended as input to human beings, not to parser generators such as Lex or
+			Yacc.  Do not expect formal rigor.  Sometimes narrative text will explain things
+			that are clumsy to express in formal notation.  More often, the text will restate
+			or summarize the formal productions.
+		</para>
+		<para>
+			Conventions:
+		</para>
+		<orderedlist>
+			<listitem>
+				The grammar is a series of productions.
+			</listitem>
+			<listitem>
+				A production consists of a name, followed by "::=", followed by a
+				definition for the name.  The name identifies a grammatical construct that can
+				appear on the right side of another production.
+			</listitem>
+			<listitem>
+				Literals (including punctuation) are enclosed in single quotes, or in double
+				quotes if case is not significant.
+			</listitem>
+			<listitem>
+				A single quotation mark within a literal is escaped with a preceding backslash.
+			</listitem>
+			<listitem>
+				If a construct can be defined more than one way, then the alternatives may appear
+				in separate productions; or, they may appear in the same production, separated by
+				pipe symbols.  The choice between these representations is of only cosmetic
+				significance.
+			</listitem>
+			<listitem>
+				A construct enclosed within square brackets is optional.
+			</listitem>
+			<listitem>
+				A construct enclosed within curly braces may be repeated zero or more times.
+			</listitem>
+			<listitem>
+				JSON allows arbitrary white space between tokens.  To avoid ugly clutter, this
+				grammar ignores the optional white space.
+			</listitem>
+			<listitem>
+				In many cases a production defines a JSON object, i.e. a list of name-value pairs,
+				separated by commas.  Since the order of these name/value pairs is not significant,
+				the grammar will not try to show all the possible sequences.  In general it will
+				present the required pairs first, if any, followed by any optional elements.
+			</listitem>
+		</orderedlist>
+
+		<para>
+			Since both EBNF and JSON use curly braces and square brackets, pay close attention to
+			whether these characters are in single quotes.  If they're in single quotes, they are
+			literal elements of the JSON notation.  Otherwise they are elements of the EBNF notation.
+		</para>
+	</sect1>
+
+	<sect1><title>Primitives</title>
+		<para>
+			We'll start by defining some primitives, to get them out of the way.  They're
+			mostly just what you would expect.
+		</para>
+
+		<productionset>
+			<production>
+				<lhs>
+					string
+				</lhs>
+				<rhs>
+					'”' chars '”'
+				</rhs>
+			</production>
+
+			<production>
+				<lhs>
+					chars
+				</lhs>
+				<rhs>
+					any valid sequence of UTF-8 characters, with certain special characters
+					escaped according to JSON rules
+				</rhs>
+			</production>
+
+			<production>
+				<lhs>
+					integer_literal
+				</lhs>
+				<rhs>
+					[ sign ] digit { digit }
+				</rhs>
+			</production>
+
+			<production>
+				<lhs>
+					sign
+				</lhs>
+				<rhs>
+					'+' | '-'
+				</rhs>
+			</production>
+
+			<production>
+				<lhs>
+					digit
+				</lhs>
+				digit =  '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
+				<rhs>
+				</rhs>
+			</production>
+
+			<production>
+				<lhs>
+					integer_string
+				</lhs>
+				<rhs>
+					'”'  integer_literal  '”'
+				</rhs>
+			</production>
+
+			<production>
+				<lhs>
+					integer
+				</lhs>
+				<rhs>
+					integer_literal  |  integer_string
+				</rhs>
+			</production>
+
+			<production>
+				<lhs>
+					number
+				</lhs>
+				<rhs>
+					any valid character sequence that is numeric according to JSON rules
+				</rhs>
+			</production>
+
+		</productionset>
+
+		<para>
+			When json_query requires an integral value, it will usually accept a quoted string and
+			convert it to an integer by brute force – to zero if necessary.  Likewise it may
+			truncate a floating point number to an integral value.  Scientific notation will be
+			accepted but may not give the intended results.
+		</para>
+
+		<productionset>
+
+			<production>
+				<lhs>
+					boolean
+				</lhs>
+				<rhs>
+					'true'  |  'false'  |  string  |  number
+				</rhs>
+			</production>
+
+		</productionset>
+
+		<para>
+			The preferred way to encode a boolean is with the JSON reserved word true or false,
+			in lower case without quotation marks.  The string “<literal>true</literal>”, in
+			upper, lower, or mixed case, is another way to encode true.  Any other string
+			evaluates to false.
+		</para>
+		<para>
+			As an accommodation to perl, numbers may be used as booleans.  A numeric value of 1
+			means true, and any other numeric value means false.
+		</para>
+		<para>
+			Any other valid JSON value, such as an array, will be accepted as a boolean but interpreted
+			as false.
+		</para>
+		<para>
+			The last couple of primitives aren't really very primitive, but we introduce them here
+			for convenience:
+		</para>
+
+		<productionset>
+
+			<production>
+				<lhs>
+					class_name
+				</lhs>
+				<rhs>
+					string
+				</rhs>
+			</production>
+
+		</productionset>
+
+		<para>
+			A class_name is a special case of a string: the name of a class as defined
+			by the IDL.  The class may refer either to a database table or to a
+			source_definition, which is a subquery.
+		</para>
+
+		<productionset>
+
+			<production>
+				<lhs>
+					field_name
+				</lhs>
+				<rhs>
+					string
+				</rhs>
+			</production>
+
+		</productionset>
+
+		<para>
+			A field_name is another special case of a string: the name of a non-virtual
+			field as defined by the IDL.  A field_name is also a column name for the
+			table corresponding to the relevant class.
+		</para>
+
+	</sect1>
+
+	<sect1><title>Query</title>
+
+		<para>
+			The following production applies not only to the main query but also to
+			most subqueries.
+		</para>
+
+		<productionset>
+
+			<production>
+				<lhs>
+					query
+				</lhs>
+				<rhs>
+					'{'<sbr/>
+					'”from”'  ':'  from_list<sbr/>
+					[ ','  '”select”'    ':'  select_list ]<sbr/>
+					[ ','  '”where”'     ':'  where_condition ]<sbr/>
+					[ ','  '”having”'    ':'  where_condition ]<sbr/>
+					[ ','  '”order_by”'  ':'  order_by_list ]<sbr/>
+					[ ','  '”limit”'     ':'  integer ]<sbr/>
+					[ ','  '”offset”'    ':'  integer ]<sbr/>
+					[ ','  '”distinct”'  ':'  boolean ]<sbr/>
+					[ ','  '”no_i18n”'   ':'  boolean ]<sbr/>
+					'}'
+				</rhs>
+			</production>
+
+		</productionset>
+
+		<para>
+			Except for the <literal>“distinct”</literal> and <literal>“no_i18n”</literal>
+			entries, each name/value pair represents a major clause of the SELECT statement.
+			The name/value pairs may appear in any order.
+		</para>
+		<para>
+			There is no name/value pair for the GROUP BY clause, because json_query
+			generates it automatically according to information encoded elsewhere.
+		</para>
+		<para>
+			The <literal>“distinct”</literal> entry, if present and true, tells json_query
+			that it may have to create a GROUP BY clause.  If not present, it defaults to false.
+		</para>
+		<para>
+			The <literal>“no_i18n”</literal> entry, if present and true, tells json_query to
+			suppress internationalization.  If not present, it defaults to false.  (Note that
+			<literal>“no_i18n”</literal> contains the digit one, not the letter ell.)
+		</para>
+		<para>
+			The values for <literal>“limit”</literal> and <literal>“offset”</literal>
+			provide the arguments of the LIMIT and OFFSET clauses, respectively, of the
+			SQL statement.  Each value should be non-negative, if present, or else the
+			SQL won't work.
+		</para>
+
+	</sect1>
+
+	<sect1><title>FROM Clause</title>
+		<para>
+			The object identified by <literal>“from”</literal> encodes the FROM clause of
+			the SQL.  The associated value may be a string, an array, or a JSON object.
+		</para>
+
+		<productionset>
+
+			<production>
+				<lhs>
+					from_list
+				</lhs>
+				<rhs>
+					class_name
+				</rhs>
+			</production>
+
+		</productionset>
+
+		<para>
+			If <literal>from_list</literal> is a <literal>class_name</literal>, the
+			json_query inserts the corresponding table name or subquery into the FROM
+			clause, using the <literal>class_name</literal> as an alias for the table
+			or subquery.  The class must be defined as non-virtual in the IDL.
+		</para>
+
+		<productionset>
+
+			<production>
+				<lhs>
+					from_list
+				</lhs>
+				<rhs>
+					'['  string  {  ','  parameter  }  ']'
+				</rhs>
+			</production>
+
+			<production>
+				<lhs>
+					parameter
+				</lhs>
+				<rhs>
+					string  |  number  |  'null'
+				</rhs>
+			</production>
+
+		</productionset>
+
+		<para>
+			If from_list is a JSON array, then it represents a table-like function from
+			which the SQL statement will select rows, using a SELECT clause consisting
+			of “SELECT *” (regardless of the select_list supplied by the method parameter).
+		</para>
+		<para>
+			The first entry in the array is the name of the function.  It must be a string
+			naming a stored function.  Each subsequent entry is a function parameter.  If
+			it is a string or a number, json_query will insert it into a comma-separated
+			parameter list, enclosed in quotes, with any special characters escaped as needed.
+			If it is the JSON reserved word <literal>null</literal>, json_query will insert
+			it into the parameter list as a null value.
+		</para>
+		<para>
+			If <literal>from_list</literal> is a JSON object, it must contain exactly one entry.
+			The key of this entry must be the name of a non-virtual class defined in the IDL.
+			This class will be the top-level class of the FROM clause, the only one named
+			outside of a JOIN clause.
+		</para>
+
+		<productionset>
+
+			<production>
+				<lhs>
+					from_list
+				</lhs>
+				<rhs>
+					'{' class_name ':' join_list '}'
+				</rhs>
+			</production>
+
+			<production>
+				<lhs>
+					join_list
+				</lhs>
+				<rhs>
+					class_name
+				</rhs>
+			</production>
+
+			<production>
+				<lhs>
+					join_list
+				</lhs>
+				<rhs>
+					'{' join_def { ',' join_def } '}'
+				</rhs>
+			</production>
+
+		</productionset>
+
+		<para>
+			If the associated data is a <literal>class_name</literal>, json_query will
+			construct an INNER JOIN clause joining the class to the top-level clause,
+			using the columns specified by the IDL for such a join.
+		</para>
+		<para>
+			Otherwise, the associated data must be a JSON object with one or more entries,
+			each entry defining a join:
+		</para>
+		
+		<productionset>
+
+			<production>
+				<lhs>
+					join_def
+				</lhs>
+				<rhs>
+					class_name  ':'<sbr/>
+					'{'<sbr/>
+					[  '”type”'      ':'  string      ]<sbr/>
+					[  '”field”'     ':'  field_name  ]<sbr/>
+					[  '”fkey”'      ':'  field_name  ]<sbr/>
+					[  '”filter”'    ':'  where_condition  ]<sbr/>
+					[  '”filter_op”' ':'  string      ]<sbr/>
+					[  '”join”'      ':'  join_list   ]<sbr/>
+					'}'
+
+				</rhs>
+			</production>
+			
+		</productionset>
+
+		<para>
+			The data portion of the <literal>“join_type”</literal> entry tells json_query
+			whether to use a left join, right join, full join, or inner join.  The values
+			<literal>“left”</literal>, <literal>“right”</literal>, and <literal>“full”</literal>,
+			in upper, lower, or mixed case, have the obvious meanings.  If the
+			<literal>“join_type”</literal> entry has any other value, or is not present,
+			json_query constructs an inner join.
+		</para>
+		<para>
+			The <literal>“field”</literal> and <literal>“fkey”</literal> attributes specify the
+			columns to be equated in the join condition.  The <literal>“field”</literal> 
+			attribute refers to the column in the joined table, i.e. the one named by the
+			<literal>join_def</literal>.  The <literal>“fkey”</literal> attribute refers to the
+			corresponding column in the other table, i.e. the one named outside the
+			<literal>join_def</literal> – either the top-level table or a table named by some
+			other <literal>join_def</literal>.
+		</para>
+		<para>
+			It may be tempting to suppose that <literal>“fkey”</literal> stands for “foreign key”,
+			and therefore refers to a column in the child table that points to the key of a
+			parent table.  Resist the temptation; the labels are arbitrary.  The json_query
+			method doesn't care which table is the parent and which is the child.
+		</para>
+		<para>
+			These relationships are best explained with an example.  The following <literal>from_list</literal>:
+		</para>
+
+		<informalexample><programlisting language="JSON">
+	{
+	    "aou": {
+	        "asv": {
+	        "type" : "left",
+	        "fkey" : "id",
+	        "field" : "owner"
+	        }
+	    }
+	}
+		</programlisting></informalexample>
+
+		<para>
+			...turns into the following FROM clause:
+		</para>
+
+		<informalexample><programlisting language="SQL">
+	FROM
+	    actor.org_unit AS "aou"
+	        LEFT JOIN action.survey AS "asv"
+	            ON ( "asv".owner = "aou".id )
+		</programlisting></informalexample>
+
+		<para>
+			Note in this example that <literal>“fkey”</literal> refers to a column of the
+			class <literal>“aou”</literal>, and <literal>“field”</literal> refers to a
+			column of the class <literal>“asv”</literal>.
+		</para>
+		<para>
+			If you specify only one of the two columns, json_query will try to identify the
+			other one from the IDL. However, if you specify only the column from the parent
+			table, this attempt will probably fail.
+		</para>
+		<para>
+			If you specify both columns, json_query will use the column names you specify,
+			without verifying them with a lookup in the IDL.  By this means you can perform
+			a join using a linkage that the IDL doesn't define.  Of course, if the columns
+			don't exist in the database, the query will fail when json_query tries to execute it.
+		</para>
+		<para>
+			Using the columns specified, either explicitly or implicitly, the json_query
+			method constructs a join condition.  With raw SQL it is possible (though
+			rarely useful) to join two tables by an inequality.  However the json_query
+			method always uses a simple equality condition.
+		</para>
+		<para>
+			Using a <literal>“filter”</literal> entry in the join_def, you can apply one
+			or more additional conditions to the JOIN clause, typically to restrict the
+			join to certain rows of the joined table.  The data associated with the
+			<literal>“filter”</literal> key is the same sort of
+			<literal>where_condition</literal> that you use for a WHERE clause
+			(discussed below).
+		</para>
+		<para>
+			If the string associated with the <literal>“filter_op”</literal> entry is
+			<literal>“OR”</literal> in upper, lower, or mixed case, then the json_query
+			method uses OR to connect the standard join condition to any additional
+			conditions supplied by a <literal>“filter”</literal> entry.
+		</para>
+		<para>
+			(Note that if the <literal>where_condition</literal> supplies multiple
+			conditions, they will be connected by AND.  You will probably want to move
+			them down a layer – enclose them in parentheses, in effect – to avoid a
+			confusing mixture of ANDs and ORs.)
+		</para>
+		<para>
+			If the <literal>“filter_op”</literal> entry carries any other value, or if
+			it is absent, then the json_query method uses AND.  In the absence of a
+			<literal>“filter”</literal> entry, <literal>“filter_op”</literal> has no effect.
+		</para>
+		<para>
+			A <literal>“join”</literal> entry in a <literal>join_def</literal> specifies
+			another layer of join.  The class named in the subjoin is joined to the class
+			named by the <literal>join_def</literal> to which it is subordinate.  By this
+			means you can encode multiple joins in a hierarchy.
+		</para>
+	</sect1>
+
+	<sect1><title>SELECT Clause</title>
+		<para>
+			If a query does not contain an entry for <literal>“select”</literal>, json_query
+			will construct a default SELECT clause.  The default includes every non-virtual
+			field from the top-level class of the FROM clause, as defined by the IDL.  The
+			result is similar to SELECT *, except:
+		</para>
+
+		<itemizedlist>
+			<listitem>
+				The default includes only the fields defined in the IDL.
+			</listitem>
+			<listitem>
+				The columns will appear in the same order in which they appear in the IDL,
+				regardless of the order in which the database defines them.
+			</listitem>
+		</itemizedlist>
+
+		<para>
+			There are other ways to specify a default SELECT list, as shown below.
+		</para>
+		<para>
+			If a <literal>“select”</literal> entry is present, the associated value must
+			be a JSON object, keyed on class names:
+		</para>
+
+		<productionset>
+
+			<production>
+				<lhs>
+					select_list
+				</lhs>
+				<rhs>
+					'{' class_name ':' field_list { ',' class_name ':' field_list } '}'
+				</rhs>
+			</production>
+
+		</productionset>
+
+		<para>
+			The <literal>class_name</literal> must identify either the top-level class or
+			a class belonging to one of the joins.  Otherwise json_query will silently
+			ignore the <literal>select_list</literal>.
+		</para>
+
+		<productionset>
+
+			<production>
+				<lhs>
+					field_list
+				</lhs>
+				<rhs>
+					'null'  |  '”*”'
+				</rhs>
+			</production>
+
+		</productionset>
+
+		<para>
+			If a field_list is either the JSON reserved word <literal>null</literal>
+			(in lower case) or an asterisk in double quotes, json_query constructs a
+			default SELECT list – provided that the class is the top-level class of the
+			query.  If the class belongs to a join somewhere, json_query ignores the
+			<literal>field_list</literal>.
+		</para>
+		<para>
+			More commonly, the <literal>field_list</literal> is a JSON array of zero or
+			more field specifications:
+		</para>
+
+		<productionset>
+
+			<production>
+				<lhs>
+					field_list
+				</lhs>
+				<rhs>
+					'['  [  field_spec  {  ','  field_spec  }  ]  ']'
+				</rhs>
+			</production>
+
+		</productionset>
+
+		<para>
+			If the array is empty, json_query will construct a default SELECT list for
+			the class – again, provided that the class is the top-level class in the query.
+		</para>
+		<para>
+			In the simplest case, a field specification may name a non-virtual field
+			defined in the IDL:
+		</para>
+
+		<productionset>
+
+			<production>
+				<lhs>
+					field_spec
+				</lhs>
+				<rhs>
+					field_name
+				</rhs>
+			</production>
+
+		</productionset>
+
+		<para>
+			In some cases json_query constructs a call to the
+			<literal>oils_i18n_xlate</literal> function to internationalize the value of the
+			selected column.  Specifically, it does so if all the following are true:
+		</para>
+
+		<itemizedlist>
+			<listitem>
+				the settings file defines a locale;
+			</listitem>
+			<listitem>
+				in the field definition for the field in the IDL, the tag
+				<literal>“il8n”</literal> is present and true;
+			</listitem>
+			<listitem>
+				the query does <emphasis>not</emphasis> include the 
+				<literal>“no_il8n”</literal> tag (or includes it with a value of false).
+			</listitem>
+		</itemizedlist>
+
+		<para>
+			A field specification may be a JSON object:
+		</para>
+
+		<productionset>
+
+			<production>
+				<lhs>
+					field_spec
+				</lhs>
+				<rhs>
+					'{'<sbr/>
+					'”column”'  ':'  <sbr/>
+					[ ',' '”alias”'  ':'  string  ]<sbr/>
+					[ ',' '”aggregate”'  ':'  boolean  ]<sbr/>
+					[ ',' transform_spec  ]<sbr/>
+					'}'
+
+				</rhs>
+			</production>
+
+		</productionset>
+
+		<para>
+			The <literal>“column”</literal> entry provides the column name, which must
+			be defined as non-virtual in the IDL.
+		</para>
+		<para>
+			The <literal>“alias”</literal> entry provides a column alias.  If no alias
+			is specified, json_query uses the column name as its own alias.
+		</para>
+		<para>
+			The <literal>“aggregate”</literal> entry has no effect on the SELECT clause
+			itself.  Rather, it affects the construction of a GROUP BY class.  If there
+			is an <literal>“aggregate”</literal> entry for any field, then json_query builds
+			a GROUP BY clause listing every column that is <emphasis>not</emphasis> tagged
+			for aggregation (or that carries an <literal>“aggregate”</literal> entry with
+			a value of false).  If <emphasis>all</emphasis> columns are tagged for
+			aggregation, then json_query omits the GROUP BY clause.
+		</para>
+
+		<productionset>
+
+			<production>
+				<lhs>
+					transform_spec
+				</lhs>
+				<rhs>
+					'”transform”'  ':'  string  ]<sbr/>
+					[ ',' '”result_field”  ':'  string  ]<sbr/>
+					[ ',' '”params”  ':' param_list  ]
+				</rhs>
+			</production>
+
+		</productionset>
+
+		<para>
+			When a <literal>transform_spec</literal> is present, json_query selects the
+			return value of a function instead of selecting the column directly.  The entry
+			for <literal>“transform”</literal> provides the name of the function, and the
+			column name (as specified by the <literal>“column”</literal> tag), qualified by
+			the class name, is the argument to the function.  For example, you might use such
+			a function to format a date or time, or otherwise transform a column value.
+			You might also use an aggregate function such as SUM, COUNT, or MAX (possibly
+			together with the <literal>“aggregate”</literal> tag).
+		</para>
+		<para>
+			The <literal>“result_field”</literal> entry, when present, specifies a subcolumn
+			of the function's return value.  The resulting SQL encloses the function call
+			in parentheses, and follows it with a period and the subcolumn name.
+		</para>
+		<para>
+			The <literal>“params”</literal> entry, if present, provides a possibly empty
+			array of additional parameter values, either strings, numbers, or nulls:
+		</para>
+
+		<productionset>
+
+			<production>
+				<lhs>
+					param_list
+				</lhs>
+				<rhs>
+					'['  [  parameter  {  ','  parameter  }  ]  ']'
+				</rhs>
+			</production>
+
+		</productionset>
+
+		<para>
+			Such parameter values are enclosed in single quotes, with any special characters
+			escaped as needed, and inserted after the column name as additional parameters
+			to the function.  You might, for example, use an additional parameter to provide
+			a format string for a reformatting function.
+		</para>
+	</sect1>
+
+	<sect1><title>WHERE Clause</title>
+	</sect1>
+
+	<sect1><title>ORDER BY Clause</title>
+	</sect1>
+
+</article>
-- 
2.11.0