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]
|
#[inline]
|
||||||
/// Escapes an id if necessary
|
/// Escapes an id if necessary
|
||||||
pub fn escape_rid(s: &str) -> Cow<'_, str> {
|
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)
|
escape_numeric(s, BRACKETL, BRACKETR, BRACKET_ESC)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
/// Escapes an ident if necessary
|
/// Escapes an ident if necessary
|
||||||
pub fn escape_ident(s: &str) -> Cow<'_, str> {
|
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)
|
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")]
|
#[cfg(feature = "experimental-parser")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn escape_numeric<'a>(s: &'a str, l: char, r: char, e: &str) -> Cow<'a, str> {
|
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 {
|
impl fmt::Display for Param {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
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},
|
sql::{language::Language, Algorithm},
|
||||||
syn::v2::token::{DistanceKind, Keyword, TokenKind},
|
syn::v2::token::{DistanceKind, Keyword, TokenKind},
|
||||||
};
|
};
|
||||||
use phf::phf_map;
|
use phf::{phf_map, phf_set};
|
||||||
use unicase::UniCase;
|
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,
|
/// A map for mapping keyword strings to a tokenkind,
|
||||||
pub(crate) static KEYWORDS: phf::Map<UniCase<&'static str>, TokenKind> = phf_map! {
|
pub(crate) static KEYWORDS: phf::Map<UniCase<&'static str>, TokenKind> = phf_map! {
|
||||||
// Keywords
|
// Keywords
|
||||||
|
|
|
@ -10,7 +10,7 @@ mod datetime;
|
||||||
mod duration;
|
mod duration;
|
||||||
mod ident;
|
mod ident;
|
||||||
mod js;
|
mod js;
|
||||||
mod keywords;
|
pub mod keywords;
|
||||||
mod number;
|
mod number;
|
||||||
mod reader;
|
mod reader;
|
||||||
mod strand;
|
mod strand;
|
||||||
|
|
|
@ -15,6 +15,11 @@ mod test;
|
||||||
use lexer::Lexer;
|
use lexer::Lexer;
|
||||||
use parser::{ParseError, ParseErrorKind, Parser};
|
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`]
|
/// Parses a SurrealQL [`Query`]
|
||||||
///
|
///
|
||||||
/// During query parsing, the total depth of calls to parse values (including arrays, expressions,
|
/// 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());
|
assert!(tmp.is_ok());
|
||||||
//
|
//
|
||||||
let tmp = res.remove(0).result?;
|
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(
|
let val = Value::parse(
|
||||||
"{
|
"{
|
||||||
events: { test: 'DEFINE EVENT test ON user WHEN true THEN (CREATE activity SET user = $this, value = $after.email, action = $event)' },
|
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());
|
assert!(tmp.is_ok());
|
||||||
//
|
//
|
||||||
let tmp = res.remove(0).result?;
|
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(
|
let val = Value::parse(
|
||||||
r#"{
|
r#"{
|
||||||
events: { test: "DEFINE EVENT test ON user WHEN $event = 'CREATE' THEN (CREATE activity SET user = $this, value = $after.email, action = $event)" },
|
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());
|
assert!(tmp.is_ok());
|
||||||
//
|
//
|
||||||
let tmp = res.remove(0).result?;
|
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(
|
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)' },
|
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