@@ -9,14 +9,15 @@ struct ArgusDialect;
99
1010impl Dialect for ArgusDialect {
1111 fn is_identifier_start ( & self , ch : char ) -> bool {
12- ( ch >= 'a' && ch <= 'z' ) || ( ch >= 'A' && ch <= 'Z' ) || ch == '_'
12+ ( ch >= 'a' && ch <= 'z' ) || ( ch >= 'A' && ch <= 'Z' ) || ch == '_' || ch == '$'
1313 }
1414
1515 fn is_identifier_part ( & self , ch : char ) -> bool {
1616 ( ch >= 'a' && ch <= 'z' )
1717 || ( ch >= 'A' && ch <= 'Z' )
1818 || ( ch >= '0' && ch <= '9' )
1919 || ch == '_'
20+ || ch == '$'
2021 }
2122
2223 fn is_delimited_identifier_start ( & self , ch : char ) -> bool {
@@ -174,10 +175,21 @@ fn convert_select(select: &ast::Select) -> Result<LogicalPlan, String> {
174175
175176fn convert_expr ( expr : & Expr ) -> Result < Expression , String > {
176177 match expr {
177- Expr :: Identifier ( ident) => Ok ( Expression :: FieldReference ( ident. value . clone ( ) ) ) ,
178+ Expr :: Identifier ( ident) => {
179+ let value = ident. value . clone ( ) ;
180+ if value. starts_with ( '$' ) {
181+ Ok ( Expression :: JsonPath ( value) )
182+ } else {
183+ Ok ( Expression :: FieldReference ( value) )
184+ }
185+ } ,
178186 Expr :: CompoundIdentifier ( idents) => {
179187 let path = idents. iter ( ) . map ( |i| i. value . clone ( ) ) . collect :: < Vec < _ > > ( ) . join ( "." ) ;
180- Ok ( Expression :: FieldReference ( path) )
188+ if path. starts_with ( '$' ) {
189+ Ok ( Expression :: JsonPath ( path) )
190+ } else {
191+ Ok ( Expression :: FieldReference ( path) )
192+ }
181193 }
182194 Expr :: Value ( val_span) => match & val_span. value {
183195 ast:: Value :: Number ( n, _) => {
@@ -289,4 +301,33 @@ mod tests {
289301 _ => panic ! ( "Expected Select" ) ,
290302 }
291303 }
304+
305+ #[ test]
306+ fn test_parse_jsonpath ( ) {
307+ // Test standard dot notation with $
308+ let sql = "SELECT $.a.b FROM t" ;
309+ let stmt = parse ( sql) . unwrap ( ) ;
310+ match stmt {
311+ Statement :: Select ( LogicalPlan :: Project { projections, .. } ) => {
312+ match & projections[ 0 ] {
313+ Expression :: JsonPath ( p) => assert_eq ! ( p, "$.a.b" ) ,
314+ _ => panic ! ( "Expected JsonPath" ) ,
315+ }
316+ }
317+ _ => panic ! ( "Expected Select Project" ) ,
318+ }
319+
320+ // Test backtick quoted jsonpath with brackets
321+ let sql = "SELECT `$.a[0]` FROM t" ;
322+ let stmt = parse ( sql) . unwrap ( ) ;
323+ match stmt {
324+ Statement :: Select ( LogicalPlan :: Project { projections, .. } ) => {
325+ match & projections[ 0 ] {
326+ Expression :: JsonPath ( p) => assert_eq ! ( p, "$.a[0]" ) ,
327+ _ => panic ! ( "Expected JsonPath" ) ,
328+ }
329+ }
330+ _ => panic ! ( "Expected Select Project" ) ,
331+ }
332+ }
292333}
0 commit comments