sql/parsers/create_parser/
json.rs1use snafu::ResultExt;
16use sqlparser::parser::Parser;
17use sqlparser::tokenizer::Token;
18
19use crate::error::{Result, SyntaxSnafu};
20use crate::statements::OptionMap;
21use crate::util;
22
23pub(super) fn parse_json_datatype_options(parser: &mut Parser<'_>) -> Result<OptionMap> {
24 if parser.consume_token(&Token::LParen) {
25 let result = parser
26 .parse_comma_separated0(Parser::parse_sql_option, Token::RParen)
27 .context(SyntaxSnafu)
28 .and_then(|options| {
29 options
30 .into_iter()
31 .map(util::parse_option_string)
32 .collect::<Result<Vec<_>>>()
33 })?;
34 parser.expect_token(&Token::RParen).context(SyntaxSnafu)?;
35 Ok(OptionMap::new(result))
36 } else {
37 Ok(OptionMap::default())
38 }
39}
40
41#[cfg(test)]
42mod tests {
43 use sqlparser::ast::DataType;
44
45 use crate::dialect::GreptimeDbDialect;
46 use crate::parser::{ParseOptions, ParserContext};
47 use crate::statements::OptionMap;
48 use crate::statements::create::{
49 Column, JSON_FORMAT_FULL_STRUCTURED, JSON_FORMAT_PARTIAL, JSON_FORMAT_RAW, JSON_OPT_FORMAT,
50 JSON_OPT_UNSTRUCTURED_KEYS,
51 };
52 use crate::statements::statement::Statement;
53
54 #[test]
55 fn test_parse_json_datatype_options() {
56 fn parse(sql: &str) -> OptionMap {
57 let Statement::CreateTable(mut create_table) = ParserContext::create_with_dialect(
58 sql,
59 &GreptimeDbDialect {},
60 ParseOptions::default(),
61 )
62 .unwrap()
63 .remove(0) else {
64 unreachable!()
65 };
66
67 let Column {
68 column_def,
69 extensions,
70 } = create_table.columns.remove(0);
71 assert_eq!(column_def.name.to_string(), "my_json");
72 assert_eq!(column_def.data_type, DataType::JSON);
73 assert!(column_def.options.is_empty());
74
75 assert!(extensions.json_datatype_options.is_some());
76 extensions.json_datatype_options.unwrap()
77 }
78
79 let sql = r#"
80CREATE TABLE json_data (
81 my_json JSON(format = "partial", unstructured_keys = ["k", "foo.bar", "a.b.c"]),
82 ts TIMESTAMP TIME INDEX,
83)"#;
84 let options = parse(sql);
85 assert_eq!(options.len(), 2);
86 assert_eq!(
87 options.value(JSON_OPT_FORMAT).and_then(|x| x.as_string()),
88 Some(JSON_FORMAT_PARTIAL)
89 );
90 let expected = vec!["k", "foo.bar", "a.b.c"];
91 assert_eq!(
92 options
93 .value(JSON_OPT_UNSTRUCTURED_KEYS)
94 .and_then(|x| x.as_list()),
95 Some(expected)
96 );
97
98 let sql = r#"
99CREATE TABLE json_data (
100 my_json JSON(format = "structured"),
101 ts TIMESTAMP TIME INDEX,
102)"#;
103 let options = parse(sql);
104 assert_eq!(options.len(), 1);
105 assert_eq!(
106 options.value(JSON_OPT_FORMAT).and_then(|x| x.as_string()),
107 Some(JSON_FORMAT_FULL_STRUCTURED)
108 );
109
110 let sql = r#"
111CREATE TABLE json_data (
112 my_json JSON(format = "raw"),
113 ts TIMESTAMP TIME INDEX,
114)"#;
115 let options = parse(sql);
116 assert_eq!(options.len(), 1);
117 assert_eq!(
118 options.value(JSON_OPT_FORMAT).and_then(|x| x.as_string()),
119 Some(JSON_FORMAT_RAW)
120 );
121
122 let sql = r#"
123CREATE TABLE json_data (
124 my_json JSON(),
125 ts TIMESTAMP TIME INDEX,
126)"#;
127 let options = parse(sql);
128 assert!(options.is_empty());
129
130 let sql = r#"
131CREATE TABLE json_data (
132 my_json JSON,
133 ts TIMESTAMP TIME INDEX,
134)"#;
135 let options = parse(sql);
136 assert!(options.is_empty());
137 }
138}