Skip to content

Conversation

betodealmeida
Copy link
Contributor

Add support for parsing INSTALL extension in DuckDB (https://duckdb.org/docs/stable/extensions/installing_extensions.html).

@betodealmeida betodealmeida force-pushed the duckdb-install-extensions branch from 2fe1a45 to 327c4ae Compare September 12, 2025 17:15
Copy link
Collaborator

@georgesittas georgesittas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the contribution!

@@ -1584,6 +1584,11 @@ class Detach(Expression):
arg_types = {"this": True, "exists": False}


# https://duckdb.org/docs/sql/statements/load_and_install.html
class Install(Expression):
arg_types = {"this": True, "from_": False, "force": False}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's just name the arg "from" and use **kwargs expansion to avoid hitting a reserved keyword python syntax error. We do the same for exp.Show.

@@ -208,3 +208,53 @@ def test_token_repr(self):
repr(Tokenizer().tokenize("foo")),
"[<Token token_type: TokenType.VAR, text: foo, line: 1, col: 3, start: 0, end: 2, comments: []>]",
)

def test_duckdb_install_tokens(self):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this, there's no precedence of doing this for other dialects. It's a pretty trivial code path.

Comment on lines +1838 to +1843
# Test parsing with FROM clause
install_with_from = parse_one("INSTALL spatial FROM community", dialect="duckdb")
self.assertIsInstance(install_with_from, exp.Install)
self.assertEqual(install_with_from.args["this"].name, "spatial")
self.assertEqual(install_with_from.args["from_"].name, "community")
self.assertFalse(install_with_from.args.get("force", False))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can consolidate these tests with the validate_identity ones if we want to...

# An example
assert self.validate_identity("INSTALL httpfs").assert_is(exp.Install).name == "spatial"

@@ -1262,3 +1262,38 @@ def test_convert_datetime_time(self):

self.assertIsInstance(result, exp.TsOrDsToTime)
self.assertEqual(result.sql(), "CAST('12:00:00' AS TIME)")

def test_install_expression(self):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one seems noisy & redundant given that we have those in DuckDB. Let's remove it or move missing cases to test_duckdb.py

@georgesittas
Copy link
Collaborator

Hiya 👋
Any plans to take this to the finish line @betodealmeida?

@geooo109
Copy link
Collaborator

Thanks for the work @betodealmeida , I will take it to the finish line

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants