Fix inconsitent numeric object key (#4851)

This commit is contained in:
Mees Delzenne 2024-09-20 17:18:46 +02:00 committed by GitHub
parent 8cca86028b
commit eff4936dc3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 28 additions and 15 deletions

View file

@ -79,15 +79,12 @@ pub fn escape_ident(s: &str) -> Cow<'_, str> {
#[inline]
pub fn escape_normal<'a>(s: &'a str, l: char, r: char, e: &str) -> Cow<'a, str> {
// Loop over each character
for x in s.bytes() {
// Check if character is allowed
if !(x.is_ascii_alphanumeric() || x == b'_') {
return Cow::Owned(format!("{l}{}{r}", s.replace(r, e)));
}
// Is there no need to escape the value?
if s.bytes().all(|x| x.is_ascii_alphanumeric() || x == b'_') {
return Cow::Borrowed(s);
}
// Output the value
Cow::Borrowed(s)
Cow::Owned(format!("{l}{}{r}", s.replace(r, e)))
}
pub fn escape_reserved_keyword(s: &str) -> Option<String> {

View file

@ -3,9 +3,10 @@ use std::collections::BTreeMap;
use reblessive::Stk;
use crate::{
sql::{Block, Geometry, Number, Object, Strand, Value},
sql::{Block, Geometry, Object, Strand, Value},
syn::{
error::bail,
lexer::compound,
parser::{enter_object_recursion, mac::expected, ParseResult, Parser},
token::{t, Glued, Span, TokenKind},
},
@ -602,10 +603,8 @@ impl Parser<'_> {
match token.kind {
x if Self::kind_is_keyword_like(x) => {
self.pop_peek();
let str = self.lexer.reader.span(token.span);
// Lexer should ensure that the token is valid utf-8
let str = std::str::from_utf8(str).unwrap().to_owned();
Ok(str)
let str = self.lexer.span_str(token.span);
Ok(str.to_string())
}
TokenKind::Identifier => {
self.pop_peek();
@ -616,9 +615,16 @@ impl Parser<'_> {
let str = self.next_token_value::<Strand>()?.0;
Ok(str)
}
TokenKind::Digits | TokenKind::Glued(Glued::Number) => {
let number = self.next_token_value::<Number>()?.to_string();
Ok(number)
TokenKind::Digits => {
self.pop_peek();
let span = self.lexer.lex_compound(token, compound::number)?.span;
let str = self.lexer.span_str(span);
Ok(str.to_string())
}
TokenKind::Glued(Glued::Number) => {
self.pop_peek();
let str = self.lexer.span_str(token.span);
Ok(str.to_string())
}
_ => unexpected!(self, token, "an object key"),
}

View file

@ -38,6 +38,16 @@ fn parse_coordinate() {
assert_eq!(x.y(), -18.0);
}
#[test]
fn parse_numeric_object_key() {
let v = test_parse!(parse_value_table, "{ 00: 0 }").unwrap();
let Value::Object(object) = v else {
panic!("not an object");
};
assert!(object.len() == 1);
assert_eq!(object.get("00").cloned(), Some(Value::Number(Number::Int(0))));
}
#[test]
fn parse_like_operator() {
test_parse!(parse_value_field, "a ~ b").unwrap();