pub enum StringFunc<X: Extension = NoExt> {
Substring {
expr: Box<Expr<X>>,
start: Option<Box<Expr<X>>>,
count: Option<Box<Expr<X>>>,
meta: Meta,
},
SubstringSimilar {
expr: Box<Expr<X>>,
pattern: Box<Expr<X>>,
escape: Box<Expr<X>>,
meta: Meta,
},
Position {
substr: Box<Expr<X>>,
string: Box<Expr<X>>,
meta: Meta,
},
Overlay {
target: Box<Expr<X>>,
replacement: Box<Expr<X>>,
start: Box<Expr<X>>,
count: Option<Box<Expr<X>>>,
meta: Meta,
},
Trim {
side: Option<TrimSide>,
trim_chars: Option<Box<Expr<X>>>,
from: bool,
sources: ThinVec<Expr<X>>,
meta: Meta,
},
CollationFor {
expr: Box<Expr<X>>,
meta: Meta,
},
ConvertUsing {
expr: Box<Expr<X>>,
charset: Ident,
meta: Meta,
},
MatchAgainst {
columns: ThinVec<Expr<X>>,
against: Box<Expr<X>>,
modifier: Option<MatchSearchModifier>,
meta: Meta,
},
CeilTo {
expr: Box<Expr<X>>,
field: Ident,
spelling: CeilSpelling,
meta: Meta,
},
FloorTo {
expr: Box<Expr<X>>,
field: Ident,
meta: Meta,
},
}Expand description
A standard-SQL string special form (SQL-92 E021-06/-09/-11 + SQL:1999 T312;
PostgreSQL’s func_expr_common_subexpr string productions).
One kind-tagged enum for the keyword-argument string functions: each variant
carries exactly its form’s typed fields, and every operand keyword (FROM,
FOR, SIMILAR, ESCAPE, PLACING, IN, LEADING/TRAILING/BOTH) is
grammar, not data. The comma plain-call spellings (substring(x, 1, 2),
trim(x, y), overlay(a, b, c)) are not here — they stay ordinary
FunctionCalls, so the plain-call surface every engine also accepts is
unaffected by the special forms.
Variants§
Substring
SUBSTRING(<expr> FROM <start> [FOR <count>]) and its variants: PostgreSQL
admits FOR <count> alone and the reversed FOR <count> FROM <start>
spelling (both orders fold onto the same fields and render canonically
FROM-first), so at least one of start/count is always present. The
string-pattern form SUBSTRING(x FROM 'pat')/… FOR '#' is this same
production (the regex reading is runtime semantics, not grammar).
Fields
SubstringSimilar
PostgreSQL’s SUBSTRING(<expr> SIMILAR <pattern> ESCAPE <escape>) regex
form (SQL:1999 <regular expression substring function>). All three
operands are mandatory (SUBSTRING(x SIMILAR p) without ESCAPE rejects,
engine-verified).
Fields
Position
POSITION(<substr> IN <string>) (SQL-92 E021-11). The operands are the
restricted b_expr in PostgreSQL/DuckDB (POSITION(1 IN 2 OR 3) rejects)
and MySQL’s asymmetric bit_expr IN expr under
StringFuncForms::position_asymmetric_operands.
There is no plain-call spelling: every keyword-form engine parse-rejects
position(a, b).
Fields
Overlay
OVERLAY(<target> PLACING <replacement> FROM <start> [FOR <count>])
(SQL:1999 T312). FROM <start> is mandatory — OVERLAY(x PLACING y) and
the FOR-without-FROM form parse-reject on every keyword-form engine.
Fields
Trim
TRIM([{BOTH | LEADING | TRAILING}] [<chars>] FROM <sources>…) (SQL-92
E021-09) plus PostgreSQL’s loose trim_list tails under
StringFuncForms::trim_list_syntax: a bare
FROM <list>, a side without FROM (TRIM(TRAILING ' foo ')), and a
multi-expression list (TRIM('a' FROM 'b', 'c')). At least one of
side/from is present — a bare TRIM(x)/TRIM(x, y) is an ordinary
call, never this node.
Fields
trim_chars: Option<Box<Expr<X>>>The trim-character expression written before FROM; None for the
bare-FROM and side-without-FROM forms.
from: boolWhether FROM was written (distinguishes TRIM(TRAILING ' foo ')
from TRIM(TRAILING FROM ' foo ') — both are valid PostgreSQL with
different meanings, so the bit is load-bearing for round-trips).
CollationFor
PostgreSQL’s COLLATION FOR (<expr>) — the common-subexpr that reports the
collation name derived for its operand. PostgreSQL gives it a dedicated
COLLATION FOR '(' a_expr ')' production that lowers to a
pg_catalog.pg_collation_for(<expr>) call, but the surface keyword form is
kept here (not folded to a FunctionCall) so it round-trips as written. The
parentheses and single a_expr operand are mandatory — COLLATION FOR 'x',
COLLATION FOR (), and a two-argument list all parse-reject (engine-verified).
Fields
ConvertUsing
MySQL’s CONVERT(<expr> USING <charset>) transcoding form — reinterprets its
string operand in another character set (the grammar’s
CONVERT '(' expr USING charset_name ')'). Distinct from the comma-form cast
CastSyntax::Convert: this changes the charset, not the type, so it is a string
special form rather than a cast. The operand is a full a_expr
(CONVERT(1+2 USING utf8mb4) parses, engine-verified); charset is a MySQL
charset_name — an ident_or_text (a bare or backtick identifier, or a quoted
string, round-tripping by the Ident’s quote style) or the BINARY transcoding
name (CONVERT(x USING binary)), which reaches here as a bare Ident. Recognized
only under CallSyntax::convert_function; MySQL-only.
Fields
MatchAgainst
MySQL’s full-text search MATCH (<col>, …) AGAINST (<expr> [<modifier>])
(simple_expr: MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')').
The columns are a comma list of column references (bare or 1–3-part dotted
Expr::Columns — an arbitrary expression, literal, function call, or empty
list all parse-reject, engine-verified); against is a MySQL bit_expr (below
the comparison level, so a trailing IN/WITH opens the modifier rather than an
IN predicate). The optional MatchSearchModifier is exactly one of the four
documented combinations; None is the default (no modifier words) and round-trips
as written rather than as an explicit IN NATURAL LANGUAGE MODE. Recognized only
under StringFuncForms::match_against; MySQL-only, and
distinct from SQLite’s infix <expr> MATCH <expr> operator. Semantic constraints
(a full-text index must cover the columns, the operand must be constant) are a
server binding concern, not grammar.
Fields
modifier: Option<MatchSearchModifier>Optional modifier for this syntax.
CeilTo
CEIL(<expr> TO <field>) / CEILING(<expr> TO <field>) — a rounding-field
keyword form distinct from the ordinary CEIL(<expr>) call and the comma-form
scale spelling CEIL(<expr>, <scale>) (which stays an ordinary FunctionCall:
no probed oracle grammar admits the TO tail, engine-verified against pg_query,
DuckDB, and mysql:8.4). The field (DAY, HOUR, …) is stored as written and
validated, if at all, by the consuming engine at analysis time, not parse.
Recognized only under
StringFuncForms::ceil_to_field.
Fields
spelling: CeilSpellingExact source spelling retained for faithful rendering.
FloorTo
FLOOR(<expr> TO <field>) — a rounding-field keyword form distinct from the
ordinary FLOOR(<expr>) call and the comma-form scale spelling
FLOOR(<expr>, <scale>) (which stays an ordinary FunctionCall: no probed
oracle grammar admits the TO tail, engine-verified against pg_query, DuckDB, and
mysql:8.4). Unlike StringFunc::CeilTo, FLOOR has no FLOORING synonym, so
there is no spelling field to track. The field (DAY, HOUR, …) is stored as
written and validated, if at all, by the consuming engine at analysis time, not
parse. Recognized only under
StringFuncForms::floor_to_field.
Trait Implementations§
Source§impl<X: Clone + Extension> Clone for StringFunc<X>
impl<X: Clone + Extension> Clone for StringFunc<X>
Source§fn clone(&self) -> StringFunc<X>
fn clone(&self) -> StringFunc<X>
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl<'de, X> Deserialize<'de> for StringFunc<X>where
X: Deserialize<'de> + Extension,
impl<'de, X> Deserialize<'de> for StringFunc<X>where
X: Deserialize<'de> + Extension,
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
impl<X: Eq + Extension> Eq for StringFunc<X>
Source§impl<X: Extension + Render> Render for StringFunc<X>
impl<X: Extension + Render> Render for StringFunc<X>
Source§fn render(&self, ctx: &RenderCtx<'_>, f: &mut Formatter<'_>) -> Result
fn render(&self, ctx: &RenderCtx<'_>, f: &mut Formatter<'_>) -> Result
Source§fn operand_binding_power(&self) -> Option<BindingPower>
fn operand_binding_power(&self) -> Option<BindingPower>
None (the default) for a self-delimiting node — an atom, call, or
constructor — that never needs parentheses. Read moreSource§impl<X> Serialize for StringFunc<X>
impl<X> Serialize for StringFunc<X>
Source§impl<X: Extension> Spanned for StringFunc<X>
impl<X: Extension> Spanned for StringFunc<X>
impl<X: PartialEq + Extension> StructuralPartialEq for StringFunc<X>
Auto Trait Implementations§
impl<X> Freeze for StringFunc<X>
impl<X> RefUnwindSafe for StringFunc<X>where
X: RefUnwindSafe,
impl<X> Send for StringFunc<X>where
X: Send,
impl<X> Sync for StringFunc<X>where
X: Sync,
impl<X> Unpin for StringFunc<X>where
X: Unpin,
impl<X> UnsafeUnpin for StringFunc<X>
impl<X> UnwindSafe for StringFunc<X>where
X: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> DynAstExt for T
impl<T> DynAstExt for T
Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&dyn Any for downcasting a node back to its concrete type.Source§fn dyn_clone(&self) -> Box<dyn DynAstExt>
fn dyn_clone(&self) -> Box<dyn DynAstExt>
Clone (whose
Self-returning signature cannot go through a vtable).Source§fn dyn_eq(&self, other: &dyn DynAstExt) -> bool
fn dyn_eq(&self, other: &dyn DynAstExt) -> bool
PartialEq (whose &Self argument cannot go through a vtable). Equal
iff other holds the same concrete type and that type deems the values
equal; differently-typed nodes are never equal.