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:
duckdb:///abs/path opens the absolute path (SQLAlchemy convention), or
- 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.
Summary
--reader 'duckdb:///abs/path/to/file.duckdb'does not open the absolute path. The/afterduckdb://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_aarch64.pkg)Reproducible example
The path opened is
tmp/somefile.duckdb(relative), not/tmp/somefile.duckdb(absolute).Variations tested
duckdb:///tmp/foo.duckdbtmp/foo.duckdb(leading/dropped)duckdb:////tmp/foo.duckdbduckdb:/tmp/foo.duckdbUnsupported connection stringduckdb:tmp/foo.duckdbUnsupported connection stringduckdb://./tmp/foo.duckdb./tmp/foo.duckdbduckdb://localhost/tmp/foo.duckdblocalhost/tmp/foo.duckdbfile:///tmp/foo.duckdbUnsupported connection string/tmp/foo.duckdb(no scheme)Unsupported connection stringSuggested behavior
One of:
duckdb:///abs/pathopens the absolute path (SQLAlchemy convention), orduckdb://relative/pathfor relative orduckdb:///abs/pathfor 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
cdinto a parent directory of the target file and pass a relative path: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
.duckdbfile 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.