use super::types::Token;
use super::queryparser_type::QueryParser;
pub(super) fn builtin_call_name(identifier: &str) -> Option<&'static str> {
let canonical = match identifier.to_ascii_uppercase().as_str() {
"STR" => "str",
"LANG" => "lang",
"LANGMATCHES" => "langmatches",
"DATATYPE" => "datatype",
"BOUND" => "bound",
"IRI" => "iri",
"URI" => "uri",
"BNODE" => "bnode",
"RAND" => "rand",
"ABS" => "abs",
"CEIL" => "ceil",
"FLOOR" => "floor",
"ROUND" => "round",
"CONCAT" => "concat",
"STRLEN" => "strlen",
"UCASE" => "ucase",
"LCASE" => "lcase",
"ENCODE_FOR_URI" => "encode_for_uri",
"CONTAINS" => "contains",
"STRSTARTS" => "strstarts",
"STRENDS" => "strends",
"STRBEFORE" => "strbefore",
"STRAFTER" => "strafter",
"YEAR" => "year",
"MONTH" => "month",
"DAY" => "day",
"HOURS" => "hours",
"MINUTES" => "minutes",
"SECONDS" => "seconds",
"TIMEZONE" => "timezone",
"TZ" => "tz",
"NOW" => "now",
"UUID" => "uuid",
"STRUUID" => "struuid",
"MD5" => "md5",
"SHA1" => "sha1",
"SHA256" => "sha256",
"SHA384" => "sha384",
"SHA512" => "sha512",
"COALESCE" => "coalesce",
"IF" => "if",
"STRLANG" => "strlang",
"STRDT" => "strdt",
"SAMETERM" => "sameterm",
"ISIRI" => "isiri",
"ISURI" => "isuri",
"ISBLANK" => "isblank",
"ISLITERAL" => "isliteral",
"ISNUMERIC" => "isnumeric",
"REGEX" => "regex",
"SUBSTR" => "substr",
"REPLACE" => "replace",
_ => return None,
};
Some(canonical)
}
impl QueryParser {
pub(super) fn classify_identifier(&self, identifier: &str) -> Token {
match identifier.to_uppercase().as_str() {
"SELECT" => Token::Select,
"CONSTRUCT" => Token::Construct,
"ASK" => Token::Ask,
"DESCRIBE" => Token::Describe,
"WHERE" => Token::Where,
"OPTIONAL" => Token::Optional,
"UNION" => Token::Union,
"MINUS" => Token::Minus,
"FILTER" => Token::Filter,
"BIND" => Token::Bind,
"SERVICE" => Token::Service,
"GRAPH" => Token::Graph,
"FROM" => Token::From,
"NAMED" => Token::Named,
"PREFIX" => Token::Prefix,
"BASE" => Token::Base,
"DISTINCT" => Token::Distinct,
"REDUCED" => Token::Reduced,
"ORDER" => Token::OrderBy,
"BY" => Token::OrderBy,
"GROUP" => Token::GroupBy,
"HAVING" => Token::Having,
"LIMIT" => Token::Limit,
"OFFSET" => Token::Offset,
"ASC" => Token::Asc,
"DESC" => Token::Desc,
"AS" => Token::As,
"VALUES" => Token::Values,
"EXISTS" => Token::Exists,
"NOT" => Token::Not,
"IN" => Token::In,
"AND" => Token::And,
"OR" => Token::Or,
"TRUE" => Token::BooleanLiteral(true),
"FALSE" => Token::BooleanLiteral(false),
"INSERT" => Token::Insert,
"DELETE" => Token::Delete,
"UPDATE" => Token::Update,
"CREATE" => Token::Create,
"DROP" => Token::Drop,
"CLEAR" => Token::Clear,
"LOAD" => Token::Load,
"COPY" => Token::Copy,
"MOVE" => Token::Move,
"ADD" => Token::Add,
"DATA" => Token::Data,
"WITH" => Token::With,
"USING" => Token::Using,
"SILENT" => Token::Silent,
"ALL" => Token::All,
"DEFAULT" => Token::Default,
"TO" => Token::To,
_ => {
if let Some(colon_pos) = identifier.find(':') {
let prefix = identifier[..colon_pos].to_string();
let local = identifier[colon_pos + 1..].to_string();
Token::PrefixedName(prefix, local)
} else if let Some(stripped) = identifier.strip_prefix(':') {
let local = stripped.to_string();
Token::PrefixedName("".to_string(), local)
} else if identifier == "a" {
Token::A
} else if let Some(canonical) = builtin_call_name(identifier) {
Token::BuiltIn(canonical.to_string())
} else {
Token::PrefixedName("".to_string(), identifier.to_string())
}
}
}
}
}