*{,<replaceable>m</replaceable>} <lineannotation>Match at most <replaceable>m</replaceable> labels — same as </lineannotation>*{0,<replaceable>m</replaceable>}
foo{<replaceable>n</replaceable>,<replaceable>m</replaceable>} <lineannotation>Match at least <replaceable>n</replaceable> but not more than <replaceable>m</replaceable> occurrences of <literal>foo</literal></lineannotation>
foo{,} <lineannotation>Match any number of occurrences of <literal>foo</literal>, including zero</lineannotation>
</synopsis>
In the absence of any explicit quantifier, the default for a star symbol
is to match any number of labels (that is, <literal>{,}</literal>) while
the default for a non-star item is to match exactly once (that
is, <literal>{1}</literal>).
</para>
<para>
There are several modifiers that can be put at the end of a non-star
<type>lquery</type> item to make it match more than just the exact match:
<synopsis>
@ <lineannotation>Match case-insensitively, for example <literal>a@</literal> matches <literal>A</literal></lineannotation>
* <lineannotation>Match any label with this prefix, for example <literal>foo*</literal> matches <literal>foobar</literal></lineannotation>
% <lineannotation>Match initial underscore-separated words</lineannotation>
</synopsis>
The behavior of <literal>%</literal> is a bit complicated. It tries to match
words rather than the entire label. For example
<literal>foo_bar%</literal> matches <literal>foo_bar_baz</literal> but not
<literal>foo_barbaz</literal>. If combined with <literal>*</literal>, prefix
matching applies to each word separately, for example
<literal>foo_bar%*</literal> matches <literal>foo1_bar2_baz</literal> but
not <literal>foo1_br2_baz</literal>.
</para>
<para>
Also, you can write several possibly-modified non-star items separated with
<literal>|</literal> (OR) to match any of those items, and you can put
<literal>!</literal> (NOT) at the start of a non-star group to match any
label that doesn't match any of the alternatives. A quantifier, if any,
goes at the end of the group; it means some number of matches for the
group as a whole (that is, some number of labels matching or not matching
any of the alternatives).
</para>
<para>
Here's an annotated example of <type>lquery</type>:
<programlisting>
Top.*{0,2}.sport*@.!football|tennis{1,}.Russ*|Spain
a. b. c. d. e.
</programlisting>
This query will match any label path that:
</para>
<orderedlist numeration="loweralpha">
<listitem>
<para>
begins with the label <literal>Top</literal>
</para>
</listitem>
<listitem>
<para>
and next has zero to two labels before
</para>
</listitem>
<listitem>
<para>
a label beginning with the case-insensitive prefix <literal>sport</literal>
</para>
</listitem>
<listitem>
<para>
then has one or more labels, none of which
match <literal>football</literal> nor <literal>tennis</literal>
</para>
</listitem>
<listitem>
<para>
and then ends with a label beginning with <literal>Russ</literal> or
exactly matching <literal>Spain</literal>.
</para>
</listitem>
</orderedlist>
</listitem>
<listitem>
<para><type>ltxtquery</type> represents a full-text-search-like
pattern for matching <type>ltree</type> values. An
<type>ltxtquery</type> value contains words, possibly with the
modifiers <literal>@</literal>, <literal>*</literal>, <literal>%</literal> at the end;
the modifiers have the same meanings as in <type>lquery</type>.
Words can be combined with <literal>&</literal> (AND),
<literal>|</literal> (OR), <literal>!</literal> (NOT), and parentheses.
The key difference from
<type>lquery</type> is that <type>ltxtquery</type>