MCPcopy Create free account
hub / github.com/MaterializeInc/materialize / compile

Method compile

src/expr/src/scalar/func/format.rs:857–934  ·  view source on GitHub ↗

Compiles a new `DateTimeFormat` from the input string `s`.

(s: &str)

Source from the content-addressed store, hash-verified

855impl DateTimeFormat {
856 /// Compiles a new `DateTimeFormat` from the input string `s`.
857 pub fn compile(s: &str) -> DateTimeFormat {
858 // The approach here uses the Aho-Corasick string searching algorithm to
859 // repeatedly and efficiently find the next token of interest. Tokens of
860 // interest are typically field specifiers, like "DDDD", or field
861 // modifiers, like "FM". Characters in between tokens of interest are
862 // recorded as literals. We also consider a double quote a token of
863 // interest, as a double quote disables matching of field
864 // specifiers/modifiers until the next double quote.
865
866 struct Match {
867 start: usize,
868 end: usize,
869 token: DateTimeToken,
870 }
871
872 let matcher = AhoCorasickBuilder::new()
873 .match_kind(aho_corasick::MatchKind::LeftmostLongest)
874 .build(DateTimeToken::patterns())
875 .unwrap_or_else(|e| panic!("automaton build error: {e}"));
876
877 let matches: Vec<_> = matcher
878 .find_iter(&s)
879 .map(|m| Match {
880 start: m.start(),
881 end: m.end(),
882 token: DateTimeToken::try_from(
883 u8::try_from(m.pattern().as_u32()).expect("match index fits in a u8"),
884 )
885 .expect("match pattern missing"),
886 })
887 .collect();
888
889 let mut out = Vec::new();
890 let mut pos = 0;
891 let mut in_quotes = false;
892 for i in 0..matches.len() {
893 // Any characters since the last match are to be taken literally.
894 for c in s[pos..matches[i].start].chars() {
895 if !(in_quotes && c == '\\') {
896 // Backslash is an escape character inside of quotes.
897 out.push(DateTimeFormatNode::Literal(c));
898 }
899 }
900
901 if in_quotes {
902 // If we see a format specifier inside of a quoted block, it
903 // is taken literally.
904 for c in matches[i].token.as_literal().chars() {
905 out.push(DateTimeFormatNode::Literal(c))
906 }
907 } else if let Some(field) = matches[i].token.field() {
908 // We found a format specifier. Look backwards for a fill mode
909 // toggle (fill mode is on by default), and forwards for an
910 // ordinal suffix specifier (default is no ordinal suffix).
911 let fill = i == 0
912 || matches[i - 1].end != matches[i].start
913 || !matches[i - 1].token.is_fill_mode_toggle();
914 let ordinal = match matches.get(i + 1) {

Callers 15

environments.tsFile · 0.80
TutorialInsertionWidgetFunction · 0.80
NewWebhookSourceContentFunction · 0.80
useCreateSqlServerSourceFunction · 0.80
useCreatePostgresSourceFunction · 0.80
useCreateMySqlSourceFunction · 0.80
useCreateSourceFunction · 0.80
NewClusterFormFunction · 0.80
NewReplicaFormFunction · 0.80
compileToSqlFunction · 0.80
useSubscribeRequestFunction · 0.80

Calls 14

DateTimeFormatClass · 0.85
expectMethod · 0.80
fieldMethod · 0.80
is_fill_mode_toggleMethod · 0.80
ordinal_modeMethod · 0.80
buildMethod · 0.45
collectMethod · 0.45
mapMethod · 0.45
startMethod · 0.45
patternMethod · 0.45
lenMethod · 0.45
pushMethod · 0.45

Tested by 2

compileToSqlFunction · 0.64
createSourceFunction · 0.64