Fix export generating unparsable code with the new parser (#3351)
This commit is contained in:
parent
2fe398f5b4
commit
3c92765fad
6 changed files with 99 additions and 3 deletions
|
@ -89,12 +89,20 @@ pub fn escape_key(s: &str) -> Cow<'_, str> {
|
|||
#[inline]
|
||||
/// Escapes an id if necessary
|
||||
pub fn escape_rid(s: &str) -> Cow<'_, str> {
|
||||
#[cfg(feature = "experimental-parser")]
|
||||
if let Some(x) = escape_reserved_keyword(s) {
|
||||
return Cow::Owned(x);
|
||||
}
|
||||
escape_numeric(s, BRACKETL, BRACKETR, BRACKET_ESC)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Escapes an ident if necessary
|
||||
pub fn escape_ident(s: &str) -> Cow<'_, str> {
|
||||
#[cfg(feature = "experimental-parser")]
|
||||
if let Some(x) = escape_reserved_keyword(s) {
|
||||
return Cow::Owned(x);
|
||||
}
|
||||
escape_numeric(s, BACKTICK, BACKTICK, BACKTICK_ESC)
|
||||
}
|
||||
|
||||
|
@ -136,6 +144,11 @@ pub fn escape_numeric<'a>(s: &'a str, l: char, r: char, e: &str) -> Cow<'a, str>
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "experimental-parser")]
|
||||
pub fn escape_reserved_keyword(s: &str) -> Option<String> {
|
||||
crate::syn::v2::could_be_reserved_keyword(s).then(|| format!("`{}`", s))
|
||||
}
|
||||
|
||||
#[cfg(feature = "experimental-parser")]
|
||||
#[inline]
|
||||
pub fn escape_numeric<'a>(s: &'a str, l: char, r: char, e: &str) -> Cow<'a, str> {
|
||||
|
|
|
@ -114,6 +114,6 @@ impl Param {
|
|||
|
||||
impl fmt::Display for Param {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "${}", &self.0)
|
||||
write!(f, "${}", &self.0 .0)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,9 +3,54 @@ use crate::{
|
|||
sql::{language::Language, Algorithm},
|
||||
syn::v2::token::{DistanceKind, Keyword, TokenKind},
|
||||
};
|
||||
use phf::phf_map;
|
||||
use phf::{phf_map, phf_set};
|
||||
use unicase::UniCase;
|
||||
|
||||
/// A set of keywords which might in some contexts are dissallowed as an identifier.
|
||||
pub static RESERVED_KEYWORD: phf::Set<UniCase<&'static str>> = phf_set! {
|
||||
UniCase::ascii("ANALYZE"),
|
||||
UniCase::ascii("BEGIN"),
|
||||
UniCase::ascii("BREAK"),
|
||||
UniCase::ascii("CANCEL"),
|
||||
UniCase::ascii("COMMIT"),
|
||||
UniCase::ascii("CONTINUE"),
|
||||
UniCase::ascii("CREATE"),
|
||||
UniCase::ascii("DEFINE"),
|
||||
UniCase::ascii("FOR"),
|
||||
UniCase::ascii("IF"),
|
||||
UniCase::ascii("INFO"),
|
||||
UniCase::ascii("INSERT"),
|
||||
UniCase::ascii("KILL"),
|
||||
UniCase::ascii("LIVE"),
|
||||
UniCase::ascii("OPTION"),
|
||||
UniCase::ascii("RETURN"),
|
||||
UniCase::ascii("RELATE"),
|
||||
UniCase::ascii("REMOVE"),
|
||||
UniCase::ascii("SELECT"),
|
||||
UniCase::ascii("LET"),
|
||||
UniCase::ascii("SHOW"),
|
||||
UniCase::ascii("SLEEP"),
|
||||
UniCase::ascii("THROW"),
|
||||
UniCase::ascii("UPDATE"),
|
||||
UniCase::ascii("USE"),
|
||||
UniCase::ascii("DIFF"),
|
||||
UniCase::ascii("RAND"),
|
||||
UniCase::ascii("NONE"),
|
||||
UniCase::ascii("NULL"),
|
||||
UniCase::ascii("AFTER"),
|
||||
UniCase::ascii("BEFORE"),
|
||||
UniCase::ascii("VALUE"),
|
||||
UniCase::ascii("BY"),
|
||||
UniCase::ascii("ALL"),
|
||||
UniCase::ascii("TRUE"),
|
||||
UniCase::ascii("FALSE"),
|
||||
UniCase::ascii("WHERE"),
|
||||
};
|
||||
|
||||
pub fn could_be_reserved(s: &str) -> bool {
|
||||
RESERVED_KEYWORD.contains(&UniCase::ascii(s))
|
||||
}
|
||||
|
||||
/// A map for mapping keyword strings to a tokenkind,
|
||||
pub(crate) static KEYWORDS: phf::Map<UniCase<&'static str>, TokenKind> = phf_map! {
|
||||
// Keywords
|
||||
|
|
|
@ -10,7 +10,7 @@ mod datetime;
|
|||
mod duration;
|
||||
mod ident;
|
||||
mod js;
|
||||
mod keywords;
|
||||
pub mod keywords;
|
||||
mod number;
|
||||
mod reader;
|
||||
mod strand;
|
||||
|
|
|
@ -15,6 +15,11 @@ mod test;
|
|||
use lexer::Lexer;
|
||||
use parser::{ParseError, ParseErrorKind, Parser};
|
||||
|
||||
/// Takes a string and returns if it could be a reserved keyword in certain contexts.
|
||||
pub fn could_be_reserved_keyword(s: &str) -> bool {
|
||||
lexer::keywords::could_be_reserved(s)
|
||||
}
|
||||
|
||||
/// Parses a SurrealQL [`Query`]
|
||||
///
|
||||
/// During query parsing, the total depth of calls to parse values (including arrays, expressions,
|
||||
|
|
|
@ -345,6 +345,17 @@ async fn define_statement_event() -> Result<(), Error> {
|
|||
assert!(tmp.is_ok());
|
||||
//
|
||||
let tmp = res.remove(0).result?;
|
||||
#[cfg(feature = "parser2")]
|
||||
let val = Value::parse(
|
||||
"{
|
||||
events: { test: 'DEFINE EVENT test ON user WHEN true THEN (CREATE activity SET user = $this, `value` = $after.email, action = $event)' },
|
||||
fields: {},
|
||||
tables: {},
|
||||
indexes: {},
|
||||
lives: {},
|
||||
}",
|
||||
);
|
||||
#[cfg(not(feature = "parser2"))]
|
||||
let val = Value::parse(
|
||||
"{
|
||||
events: { test: 'DEFINE EVENT test ON user WHEN true THEN (CREATE activity SET user = $this, value = $after.email, action = $event)' },
|
||||
|
@ -403,6 +414,17 @@ async fn define_statement_event_when_event() -> Result<(), Error> {
|
|||
assert!(tmp.is_ok());
|
||||
//
|
||||
let tmp = res.remove(0).result?;
|
||||
#[cfg(feature = "parser2")]
|
||||
let val = Value::parse(
|
||||
r#"{
|
||||
events: { test: "DEFINE EVENT test ON user WHEN $event = 'CREATE' THEN (CREATE activity SET user = $this, `value` = $after.email, action = $event)" },
|
||||
fields: {},
|
||||
tables: {},
|
||||
indexes: {},
|
||||
lives: {},
|
||||
}"#,
|
||||
);
|
||||
#[cfg(not(feature = "parser2"))]
|
||||
let val = Value::parse(
|
||||
r#"{
|
||||
events: { test: "DEFINE EVENT test ON user WHEN $event = 'CREATE' THEN (CREATE activity SET user = $this, value = $after.email, action = $event)" },
|
||||
|
@ -461,6 +483,17 @@ async fn define_statement_event_when_logic() -> Result<(), Error> {
|
|||
assert!(tmp.is_ok());
|
||||
//
|
||||
let tmp = res.remove(0).result?;
|
||||
#[cfg(feature = "parser2")]
|
||||
let val = Value::parse(
|
||||
"{
|
||||
events: { test: 'DEFINE EVENT test ON user WHEN $before.email != $after.email THEN (CREATE activity SET user = $this, `value` = $after.email, action = $event)' },
|
||||
fields: {},
|
||||
tables: {},
|
||||
indexes: {},
|
||||
lives: {},
|
||||
}",
|
||||
);
|
||||
#[cfg(not(feature = "parser2"))]
|
||||
let val = Value::parse(
|
||||
"{
|
||||
events: { test: 'DEFINE EVENT test ON user WHEN $before.email != $after.email THEN (CREATE activity SET user = $this, value = $after.email, action = $event)' },
|
||||
|
|
Loading…
Reference in a new issue