Skip to content

Commit cb3947c

Browse files
committed
add is_parsable scalar function
1 parent ed70b4a commit cb3947c

File tree

2 files changed

+59
-2
lines changed

2 files changed

+59
-2
lines changed

src/parse_tables.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,19 @@ static void ParseTablesScalarFunction_struct(DataChunk &args, ExpressionState &s
300300
});
301301
}
302302

303+
static void IsParsableFunction(DataChunk &args, ExpressionState &state, Vector &result) {
304+
UnaryExecutor::Execute<string_t, bool>(args.data[0], result, args.size(),
305+
[](string_t query) -> bool {
306+
try {
307+
Parser parser;
308+
parser.ParseQuery(query.GetString());
309+
return true;
310+
} catch (const std::exception &) {
311+
return false;
312+
}
313+
});
314+
}
315+
303316
// Extension scaffolding
304317
// ---------------------------------------------------
305318

@@ -309,22 +322,26 @@ void RegisterParseTablesFunction(DatabaseInstance &db) {
309322
}
310323

311324
void RegisterParseTableScalarFunction(DatabaseInstance &db) {
312-
// parse tables is overloaded, allowing for an optional boolean argument
325+
// parse_table_names is overloaded, allowing for an optional boolean argument
313326
// that indicates whether to include CTEs in the result
314327
// usage: parse_tables(sql_query [, include_cte])
315328
ScalarFunctionSet set("parse_table_names");
316329
set.AddFunction(ScalarFunction({LogicalType::VARCHAR}, LogicalType::LIST(LogicalType::VARCHAR), ParseTablesScalarFunction));
317330
set.AddFunction(ScalarFunction({LogicalType::VARCHAR, LogicalType::BOOLEAN}, LogicalType::LIST(LogicalType::VARCHAR), ParseTablesScalarFunction));
318-
319331
ExtensionUtil::RegisterFunction(db, set);
320332

333+
// parse_tables_struct is a scalar function that returns a list of structs
321334
auto return_type = LogicalType::LIST(LogicalType::STRUCT({
322335
{"schema", LogicalType::VARCHAR},
323336
{"table", LogicalType::VARCHAR},
324337
{"context", LogicalType::VARCHAR}
325338
}));
326339
ScalarFunction sf("parse_tables", {LogicalType::VARCHAR}, return_type, ParseTablesScalarFunction_struct);
327340
ExtensionUtil::RegisterFunction(db, sf);
341+
342+
// is_parsable is a scalar function that returns a boolean indicating whether the SQL query is parsable (no parse errors)
343+
ScalarFunction is_parsable("is_parsable", {LogicalType::VARCHAR}, LogicalType::BOOLEAN, IsParsableFunction);
344+
ExtensionUtil::RegisterFunction(db, is_parsable);
328345
}
329346

330347
} // namespace duckdb
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# name: test/sql/parser_tools/scalar_functions/is_parsable.test
2+
# description: test is_parsable scalar function
3+
# group: [parse_table_names]
4+
5+
# Before we load the extension, this will fail
6+
statement error
7+
SELECT is_parsable('select * from MyTable');
8+
----
9+
Catalog Error: Scalar Function with name is_parsable does not exist!
10+
11+
# Require statement will ensure this test is run with this extension loaded
12+
require parser_tools
13+
14+
15+
# base case
16+
query I
17+
SELECT is_parsable('select * from MyTable');
18+
----
19+
true
20+
21+
# false
22+
# -----
23+
24+
query I
25+
SELECT is_parsable('select * from');
26+
----
27+
false
28+
29+
query I
30+
SELECT is_parsable('select');
31+
----
32+
false
33+
34+
# true
35+
# -----
36+
37+
query I
38+
SELECT is_parsable('select 1');
39+
----
40+
true

0 commit comments

Comments
 (0)