Skip to content

Commit 9c48e6c

Browse files
committed
Track nested model properties in DuckDB parser
1 parent 0fd228f commit 9c48e6c

2 files changed

Lines changed: 35 additions & 9 deletions

File tree

sidemantic-duckdb/src/sidemantic_extension.cpp

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -312,18 +312,22 @@ static bool ExtractModelNameProperty(const std::string &body, std::string &name,
312312
size_t pos = open + 1;
313313
bool in_single_quote = false;
314314
bool in_double_quote = false;
315-
int depth = 0;
315+
int paren_depth = 0;
316+
int bracket_depth = 0;
317+
int brace_depth = 0;
316318

317319
while (pos < body.size()) {
318-
while (pos < body.size() && depth == 0 &&
319-
(std::isspace(body[pos]) || body[pos] == ',')) {
320+
while (pos < body.size() && paren_depth == 0 && bracket_depth == 0 &&
321+
brace_depth == 0 && (std::isspace(body[pos]) || body[pos] == ',')) {
320322
pos++;
321323
}
322-
if (pos >= body.size() || (depth == 0 && body[pos] == ')')) {
324+
if (pos >= body.size() ||
325+
(paren_depth == 0 && bracket_depth == 0 && brace_depth == 0 && body[pos] == ')')) {
323326
return false;
324327
}
325328

326-
if (depth == 0 && StartsWithNameProperty(body, pos)) {
329+
if (paren_depth == 0 && bracket_depth == 0 && brace_depth == 0 &&
330+
StartsWithNameProperty(body, pos)) {
327331
pos += 4;
328332
while (pos < body.size() && std::isspace(body[pos])) {
329333
pos++;
@@ -391,13 +395,27 @@ static bool ExtractModelNameProperty(const std::string &body, std::string &name,
391395
} else if (ch == '"') {
392396
in_double_quote = true;
393397
} else if (ch == '(') {
394-
depth++;
398+
paren_depth++;
395399
} else if (ch == ')') {
396-
if (depth == 0) {
400+
if (paren_depth > 0) {
401+
paren_depth--;
402+
} else if (bracket_depth == 0 && brace_depth == 0) {
397403
return false;
398404
}
399-
depth--;
400-
} else if (ch == ',' && depth == 0) {
405+
} else if (ch == '[') {
406+
bracket_depth++;
407+
} else if (ch == ']') {
408+
if (bracket_depth > 0) {
409+
bracket_depth--;
410+
}
411+
} else if (ch == '{') {
412+
brace_depth++;
413+
} else if (ch == '}') {
414+
if (brace_depth > 0) {
415+
brace_depth--;
416+
}
417+
} else if (ch == ',' && paren_depth == 0 && bracket_depth == 0 &&
418+
brace_depth == 0) {
401419
break;
402420
}
403421
pos++;

sidemantic-duckdb/test/sql/sidemantic.test

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,14 @@ orders
117117
products
118118
test_model
119119

120+
statement ok
121+
SEMANTIC CREATE MODEL nested_props_model (metadata {owner analytics, name internal}, table orders, primary_key order_id);
122+
123+
query I
124+
SELECT count(*) FROM sidemantic_models() WHERE model_name = 'nested_props_model';
125+
----
126+
1
127+
120128
# Test repeated YAML load replaces same-name model instead of failing on duplicates
121129
statement ok
122130
SELECT * FROM sidemantic_load('

0 commit comments

Comments
 (0)