Skip to content

Reader URI: duckdb:///abs/path drops leading slash and falls through to a relative path #345

@shntnu

Description

@shntnu

Summary

--reader 'duckdb:///abs/path/to/file.duckdb' does not open the absolute path. The / after duckdb:// is consumed, so the connection string is interpreted as a relative path. The standard SQLAlchemy-style URI form (scheme:///abs/path) is the natural thing for a user to try, and there is no documented or working URI form that opens an absolute path.

Environment

  • ggsql 0.2.7 (binary extracted from ggsql_0.2.7_aarch64.pkg)
  • macOS 14.x, arm64

Reproducible example

$ cd "$HOME"   # cwd that does not contain a tmp/ child

$ ggsql run query.sql --reader 'duckdb:///tmp/somefile.duckdb'
Failed to create reader: Data source error: Failed to open DuckDB file 'tmp/somefile.duckdb': IO Error: Cannot open file "tmp/somefile.duckdb": No such file or directory

The path opened is tmp/somefile.duckdb (relative), not /tmp/somefile.duckdb (absolute).

Variations tested

Connection string Behavior
duckdb:///tmp/foo.duckdb Opens relative tmp/foo.duckdb (leading / dropped)
duckdb:////tmp/foo.duckdb Same — both leading slashes dropped
duckdb:/tmp/foo.duckdb Unsupported connection string
duckdb:tmp/foo.duckdb Unsupported connection string
duckdb://./tmp/foo.duckdb Opens relative ./tmp/foo.duckdb
duckdb://localhost/tmp/foo.duckdb Authority not stripped — opens localhost/tmp/foo.duckdb
file:///tmp/foo.duckdb Unsupported connection string
/tmp/foo.duckdb (no scheme) Unsupported connection string

Suggested behavior

One of:

  1. duckdb:///abs/path opens the absolute path (SQLAlchemy convention), or
  2. The connection-string parser rejects the form with a message that points at a working alternative (e.g. "use duckdb://relative/path for relative or duckdb:///abs/path for absolute, but not these other forms").

The current behavior of silently accepting the form and routing it to a relative path is the surprising part — there is no error from the URI parser itself, only from DuckDB downstream when the resolved relative path doesn't exist.

Workaround

cd into a parent directory of the target file and pass a relative path:

cd /tmp && ggsql run query.sql --reader 'duckdb://somefile.duckdb'

Edge case worth knowing about

DuckDB's default open mode is create-if-missing. If the resolved relative path happens to land in a writable existing directory, DuckDB will silently create an empty .duckdb file there and the user gets a downstream "Table not found" catalog error rather than a path-resolution error. This requires the unfortunate combination of (a) the URI bug above, (b) DuckDB's default create-on-missing, and (c) a writable directory matching the resolved relative path on the user's machine. Worth mentioning because the failure mode is quietly destructive (a stray empty .duckdb appears) but the URI parsing fix above would prevent it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions