Skip to content

Commit 60fdab5

Browse files
authored
fix(parser): support CAST and TRY_CAST expressions in SQL (#113)
1 parent 0da2546 commit 60fdab5

2 files changed

Lines changed: 117 additions & 0 deletions

File tree

tree-sitter-ggsql/grammar.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ module.exports = grammar({
6060
select_body: $ => prec.left(repeat1(choice(
6161
$.from_clause,
6262
$.window_function, // Window functions like ROW_NUMBER() OVER (...)
63+
$.cast_expression, // CAST(expr AS type), TRY_CAST(expr AS type)
6364
$.function_call, // Regular function calls like COUNT(), SUM()
6465
$.sql_keyword,
6566
$.string,
@@ -175,6 +176,7 @@ module.exports = grammar({
175176
// Token-by-token fallback for any other subquery content
176177
subquery_body: $ => repeat1(choice(
177178
$.window_function,
179+
$.cast_expression,
178180
$.function_call,
179181
$.sql_keyword,
180182
$.string,
@@ -185,6 +187,23 @@ module.exports = grammar({
185187
token(/[^\s;(),'\"]+/)
186188
)),
187189

190+
// CAST/TRY_CAST expression: CAST(expr AS type) or TRY_CAST(expr AS type)
191+
// Higher precedence than function_call to win over treating CAST as a regular function
192+
cast_expression: $ => prec(3, seq(
193+
choice(caseInsensitive('CAST'), caseInsensitive('TRY_CAST')),
194+
'(',
195+
$.positional_arg,
196+
caseInsensitive('AS'),
197+
$.type_name,
198+
')'
199+
)),
200+
201+
// Type name for CAST expressions: DATE, VARCHAR, DECIMAL(10,2), etc.
202+
type_name: $ => seq(
203+
$.identifier,
204+
optional(seq('(', $.number, optional(seq(',', $.number)), ')'))
205+
),
206+
188207
// Function call with parentheses (can be empty like ROW_NUMBER())
189208
// Used in window functions and general SQL
190209
function_call: $ => prec(2, seq(
@@ -288,6 +307,8 @@ module.exports = grammar({
288307
$.number,
289308
$.string,
290309
'*',
310+
// CAST/TRY_CAST expression
311+
$.cast_expression,
291312
// Nested function call
292313
$.function_call,
293314
// Arithmetic/comparison expression (binary operators)

tree-sitter-ggsql/test/corpus/basic.txt

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2240,3 +2240,99 @@ SCALE DISCRETE x RENAMING 'A' => 'Alpha', * => 'Category {}'
22402240
value: (string))
22412241
(renaming_assignment
22422242
value: (string)))))))
2243+
2244+
================================================================================
2245+
CAST expression
2246+
================================================================================
2247+
2248+
SELECT CAST(sale_date AS DATE) as period FROM sales VISUALISE period AS x DRAW point
2249+
2250+
--------------------------------------------------------------------------------
2251+
2252+
(query
2253+
(sql_portion
2254+
(sql_statement
2255+
(select_statement
2256+
(select_body
2257+
(cast_expression
2258+
(positional_arg
2259+
(qualified_name
2260+
(identifier
2261+
(bare_identifier))))
2262+
(type_name
2263+
(identifier
2264+
(bare_identifier))))
2265+
(identifier
2266+
(bare_identifier))
2267+
(identifier
2268+
(bare_identifier))
2269+
(from_clause
2270+
(table_ref
2271+
table: (qualified_name
2272+
(identifier
2273+
(bare_identifier)))))))))
2274+
(visualise_statement
2275+
(visualise_keyword)
2276+
(global_mapping
2277+
(mapping_list
2278+
(mapping_element
2279+
(explicit_mapping
2280+
value: (mapping_value
2281+
(column_reference
2282+
(identifier
2283+
(bare_identifier))))
2284+
name: (aesthetic_name)))))
2285+
(viz_clause
2286+
(draw_clause
2287+
(geom_type)))))
2288+
2289+
================================================================================
2290+
TRY_CAST nested in function argument
2291+
================================================================================
2292+
2293+
SELECT SUM(TRY_CAST(price AS INTEGER)) as total FROM data VISUALISE DRAW bar MAPPING x AS x
2294+
2295+
--------------------------------------------------------------------------------
2296+
2297+
(query
2298+
(sql_portion
2299+
(sql_statement
2300+
(select_statement
2301+
(select_body
2302+
(function_call
2303+
(identifier
2304+
(bare_identifier))
2305+
(function_args
2306+
(function_arg
2307+
(positional_arg
2308+
(cast_expression
2309+
(positional_arg
2310+
(qualified_name
2311+
(identifier
2312+
(bare_identifier))))
2313+
(type_name
2314+
(identifier
2315+
(bare_identifier))))))))
2316+
(identifier
2317+
(bare_identifier))
2318+
(identifier
2319+
(bare_identifier))
2320+
(from_clause
2321+
(table_ref
2322+
table: (qualified_name
2323+
(identifier
2324+
(bare_identifier)))))))))
2325+
(visualise_statement
2326+
(visualise_keyword)
2327+
(viz_clause
2328+
(draw_clause
2329+
(geom_type)
2330+
(mapping_clause
2331+
(mapping_list
2332+
(mapping_element
2333+
(explicit_mapping
2334+
value: (mapping_value
2335+
(column_reference
2336+
(identifier
2337+
(bare_identifier))))
2338+
name: (aesthetic_name)))))))))

0 commit comments

Comments
 (0)