pub struct StringFuncForms {Show 15 fields
pub substring_from_for: bool,
pub substring_leading_for: bool,
pub substring_similar: bool,
pub substring_plain_call_requires_2_or_3_args: bool,
pub substr_from_for: bool,
pub position_in: bool,
pub position_asymmetric_operands: bool,
pub overlay_placing: bool,
pub overlay_requires_placing: bool,
pub trim_from: bool,
pub trim_list_syntax: bool,
pub collation_for_expression: bool,
pub ceil_to_field: bool,
pub floor_to_field: bool,
pub match_against: bool,
}Expand description
Dialect-owned keyword string/scalar special-form syntax accepted by the parser.
The keyword special forms that parse to the StringFunc
AST family — the SQL-standard string special forms and the sibling scalar keyword forms
sharing that node. Split out of CallSyntax at its 16-field line on the grammar
boundary “the flag’s sole AST product is a StringFunc variant” — so the dual
cast/transcode CONVERT stays with the cast core. Each flag is a grammar gate: when off
the keyword head falls through to the ordinary call path or the trailing keyword
surfaces as a clean parse error.
Fields§
§substring_from_for: boolAccept the SUBSTRING(<expr> FROM <start> [FOR <count>]) keyword special form
(SQL-92 E021-06). On for ANSI/PostgreSQL/DuckDB/MySQL/Lenient (each engine
probed accepting); off for SQLite, which has no keyword string forms at all
(probed: near "FROM": syntax error) — there the head falls through to the
ordinary call path and the inner FROM is a clean parse error. The comma
plain-call spelling substring(x, 1, 2) is untouched by this flag: it keeps
parsing as an ordinary FunctionCall everywhere
(every probed engine accepts it). MySQL additionally requires the ( adjacent
to the head for the keyword form — the same IGNORE_SPACE-off demotion the
aggregates and EXTRACT follow, composed via
aggregate_args_require_adjacent_paren
(probed: spaced SUBSTRING ('a' FROM 2) is 1064 while spaced
SUBSTRING ('a', 2) parse-accepts through the demoted generic path).
substring_leading_for: boolAccept the FOR-leading SUBSTRING spellings: the bare
SUBSTRING(<expr> FOR <count>) and the reversed
SUBSTRING(<expr> FOR <count> FROM <start>) order. On for
PostgreSQL/DuckDB/Lenient (both engines probed accepting both orders); off for
MySQL (probed 1064 on both — its grammar is strictly FROM-first), ANSI
(SQL-92’s <character substring function> is FROM-first only), and SQLite.
substring_similar: boolAccept PostgreSQL’s SUBSTRING(<expr> SIMILAR <pattern> ESCAPE <escape>)
regex form (SQL:1999’s regular-expression substring function). On for
PostgreSQL/Lenient; off for DuckDB (probed: parser error — its PG-fork grammar
dropped the production), MySQL, SQLite, and ANSI (an optional-feature form only
PostgreSQL ships). The ESCAPE operand is mandatory, matching pg_query
(SUBSTRING(x SIMILAR p) rejects, probed).
substring_plain_call_requires_2_or_3_args: boolReject a substring(…)/substr(…) plain (comma) call whose argument count is
not 2 or 3 — MySQL’s dedicated grammar admits exactly (str, pos),
(str, pos, len), and the FROM/FOR keyword forms, so SUBSTRING('a'),
SUBSTRING(), and SUBSTRING('a', 2, 3, 4) are ER_PARSE_ERROR (1064) on
mysql:8.4 (all probed) while PostgreSQL parse-accepts any arity
(SUBSTRING() probed accepted — arity is a catalog lookup there, not
grammar). On for MySQL only. Only the adjacent-paren call is checked: a
spaced SUBSTRING ('a') is MySQL’s demoted stored-function path, which
parse-accepts any arity (probed 1046, a binding-class reject).
substr_from_for: boolAccept the SUBSTR head for the same FROM/FOR keyword forms
(SUBSTR(str FROM 2 FOR 3)). On for MySQL/Lenient: MySQL’s SUBSTR is a
full synonym of SUBSTRING including the keyword grammar (probed accepted),
while PostgreSQL and DuckDB have no SUBSTR keyword at all — their substr
is an ordinary catalog function, so the keyword form parse-rejects (both
probed) and the flag stays off. substr is not a keyword in any dialect’s
inventory, so the head is matched textually on an unquoted call only — a
quoted "substr"(…) stays an ordinary call, and every plain substr(a, b)
call is untouched.
position_in: boolAccept the POSITION(<substr> IN <string>) keyword special form (SQL-92
E021-11). On for ANSI/PostgreSQL/DuckDB/MySQL/Lenient; off for SQLite (no
keyword form; its position(a, b) stays an ordinary call that fails only at
binding). There is NO plain-call fallback where the flag is on:
position('b', 'abc') is a parse error on PostgreSQL, DuckDB, and MySQL
(all probed), so a comma after the first operand surfaces as a clean parse
error rather than re-reading as a generic call. The operands are the
restricted b_expr (PostgreSQL’s position_list, DuckDB inheriting it —
POSITION('a' = 'b' IN 'c') parse-accepts on both while
POSITION(1 IN 2 OR 3) rejects, both probed); MySQL’s asymmetric grammar is
position_asymmetric_operands.
position_asymmetric_operands: boolUse MySQL’s asymmetric POSITION operand grammar — bit_expr IN expr — in
place of the standard symmetric b_expr IN b_expr. The needle tightens to
MySQL’s bit_expr (arithmetic/bit operators only — no comparisons:
POSITION('a' = 'b' IN 'c') is 1064, probed) and the haystack widens to a
full expression (POSITION(1 IN 2 OR 3) accepts, probed). On for MySQL only.
overlay_placing: boolAccept the OVERLAY(<target> PLACING <replacement> FROM <start> [FOR <count>])
keyword special form (SQL:1999 T312). On for ANSI/PostgreSQL/DuckDB/Lenient;
off for MySQL (no OVERLAY at all — the keyword form is 1064 and a plain
overlay(…) call parses as a stored-function reference, probed) and SQLite.
FROM <start> is mandatory: OVERLAY(x PLACING y) and
OVERLAY(x PLACING y FOR 1) parse-reject on PostgreSQL and DuckDB (probed).
overlay_requires_placing: boolRequire the PLACING form after OVERLAY( — i.e. drop the plain-call
fallback. DuckDB’s grammar has only the PLACING production:
overlay('abc', 'X', 2, 1), overlay('abc'), and overlay() are all parser
errors there (probed), while PostgreSQL keeps its func_arg_list_opt
alternative so the same spellings parse-accept (probed; arity is a catalog
concern there). On for DuckDB and ANSI (the standard defines no plain
overlay call); off for PostgreSQL/Lenient, where a non-PLACING argument
list falls back to the ordinary call path.
trim_from: boolAccept the restricted TRIM([{BOTH | LEADING | TRAILING}] [<chars>] FROM <source>) keyword special form (SQL-92 E021-09): a side and/or a
trim-character expression, then FROM and exactly one source. On for
ANSI/PostgreSQL/DuckDB/MySQL/Lenient; off for SQLite (probed: syntax error —
its two-argument trim(x, y) plain call is the only spelling). The bare
single-argument TRIM(x) stays an ordinary call everywhere, and TRIM()
rejects wherever the flag is on (PostgreSQL/DuckDB/MySQL all probed rejecting
the empty form). MySQL requires at least one of side/chars before FROM
(TRIM(FROM 'x') is 1064, probed) and holds the keyword form to the adjacent
( like SUBSTRING (spaced TRIM (LEADING …) is 1064 while spaced
TRIM ('abc') parse-accepts through the demoted generic path, both probed);
the looser PostgreSQL tails are trim_list_syntax.
trim_list_syntax: boolAccept PostgreSQL’s loose trim_list tails on the TRIM special form: the
bare TRIM(FROM <list>) (no side, no chars), a side without FROM
(TRIM(TRAILING ' foo '), TRIM(LEADING 'x', 'y')), a multi-expression
source list (TRIM('a' FROM 'b', 'c'), TRIM(BOTH FROM 'a', 'b')), and the
comma plain-call spelling trim('a', 'b') (which PostgreSQL parses through
the same production and we keep as an ordinary call). On for
PostgreSQL/DuckDB/Lenient (every listed form probed parse-accepting on both
engines — DuckDB’s rejects here are binder arity, not grammar); off for MySQL
(each probed 1064), ANSI (the standard’s trim operand takes one source), and
SQLite. Where this is off but trim_from is on, a comma
after the first TRIM operand is a clean parse error — matching MySQL, whose
trim('a', 'b') is 1064 (probed).
collation_for_expression: boolAccept PostgreSQL’s COLLATION FOR (<expr>) common-subexpr — the special form that
reports the collation name derived for its operand. PostgreSQL gives it a dedicated
COLLATION FOR '(' a_expr ')' production (lowered to a
pg_catalog.pg_collation_for(<expr>) call), so only COLLATION immediately trailed
by FOR ( opens it; the parentheses and single a_expr operand are mandatory —
COLLATION FOR 'x', COLLATION FOR (), and a two-argument list all reject
(engine-verified against pg_query). When off, COLLATION keeps its ordinary
type_func_name reading (a plain collation(x) call is unaffected either way). On
for PostgreSQL/Lenient; off elsewhere (no other shipped dialect has the form —
DuckDB overrides PostgreSQL’s true back to false, its COLLATION FOR surface
unprobed). The parsed form keeps its keyword shape as
StringFunc::CollationFor so it round-trips
as written rather than as the lowered call.
ceil_to_field: boolAccept the CEIL/CEILING rounding-field keyword form: CEIL(<expr> TO <field>)
(and the CEILING spelling). No probed oracle grammar admits the TO tail —
engine-verified against pg_query (syntax error at or near "TO"), DuckDB, and
mysql:8.4.10 (all reject) — so this is sqlparser-rs-parity surface only, not a
real-engine grammar; on for Lenient, off for every shipped engine preset. Only
CEIL/CEILING immediately followed by ( opens the speculative read (mirroring
substring_from_for’s shape): the first operand parses
as an ordinary expression, and only a following TO commits to the special form —
a first operand with no TO tail rewinds to the ordinary call path, so the comma
scale spelling CEIL(<expr>, <scale>) is untouched and keeps parsing as a plain
FunctionCall in every dialect regardless of this flag.
When off, CEIL(x TO DAY) is the same clean parse error it is today (an
unexpected TO where a , or ) is expected). The field (DAY, HOUR, …) is
stored as a written Ident, validated (if at all) by the
consuming engine at analysis time, not parse. The parsed form is
StringFunc::CeilTo.
floor_to_field: boolAccept the FLOOR rounding-field keyword form: FLOOR(<expr> TO <field>). No
probed oracle grammar admits the TO tail — engine-verified against pg_query
(syntax error at or near "TO"), DuckDB, and mysql:8.4.10 (all reject) — so this
is sqlparser-rs-parity surface only, not a real-engine grammar; on for Lenient,
off for every shipped engine preset. Unlike CEIL/CEILING, FLOOR has no
synonym spelling to track. Only FLOOR immediately followed by ( opens the
speculative read (mirroring ceil_to_field’s shape): the
first operand parses as an ordinary expression, and only a following TO commits
to the special form — a first operand with no TO tail rewinds to the ordinary
call path, so the comma scale spelling FLOOR(<expr>, <scale>) is untouched and
keeps parsing as a plain FunctionCall in every
dialect regardless of this flag. When off, FLOOR(x TO DAY) is the same clean
parse error it is today (an unexpected TO where a , or ) is expected). The
field (DAY, HOUR, …) is stored as a written Ident,
validated (if at all) by the consuming engine at analysis time, not parse. The
parsed form is StringFunc::FloorTo.
match_against: boolAccept MySQL’s full-text MATCH (<col>, …) AGAINST (<expr> [<modifier>]) special-form
expression (grammar’s MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')').
Only MATCH immediately followed by ( opens it; the column list is comma-separated
column references (a general expression, literal, function call, or empty list all
parse-reject), the AGAINST operand is a bit_expr (so a trailing IN/WITH opens the
modifier rather than an IN predicate), and the optional modifier is exactly one of
IN NATURAL LANGUAGE MODE, IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION,
IN BOOLEAN MODE, or WITH QUERY EXPANSION (all engine-verified on mysql:8.4.10; the
non-reserved AGAINST/QUERY/EXPANSION words are matched contextually, MySQL’s
reserved-only inventory design). The parsed form is
StringFunc::MatchAgainst. Distinct from SQLite’s
infix <expr> MATCH <expr> operator (a binding-power table entry, not this gate). On for
MySQL/Lenient; off elsewhere (no other shipped dialect has the special form).
Implementations§
Trait Implementations§
Source§impl Clone for StringFuncForms
impl Clone for StringFuncForms
Source§fn clone(&self) -> StringFuncForms
fn clone(&self) -> StringFuncForms
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more