Skip to content

Commit 771b78f

Browse files
committed
vortex-tui: query tab should work for non-*.vortex files
Because of how ListingTable works, previously if we had a non-*.vortex file (for example, a file downloaded via a presigned URL from S3) it would open and otherwise be perfectly usable with the TUI, except the query tab would fail to list it, for two reasons 1. HEAD only works for canonical paths 2. There was a filter for *.vortex files being applied by our format By overriding the format file filter and canonicalizing the path, we can force ListingTable to work with the single file we pass as the argument to `vx browse` Signed-off-by: Andrew Duffy <andrew@a10y.dev>
1 parent f0b8fb9 commit 771b78f

1 file changed

Lines changed: 23 additions & 4 deletions

File tree

vortex-tui/src/datafusion_helper.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,32 @@ pub async fn create_vortex_context(
4949
let ctx = SessionContext::new();
5050
let format = Arc::new(VortexFormat::new(session.clone()));
5151

52+
// Resolve to an absolute, canonical path before handing it to `ListingTableUrl`.
53+
// `ListingTable` is collection-oriented: if the object `head` lookup for the URL
54+
// fails (which happens for relative or non-canonical paths), DataFusion silently
55+
// retries the path as a directory prefix and recursively lists it, crawling
56+
// sibling and child directories. Canonicalizing to the existing file keeps us on
57+
// the single-file fast path.
58+
let canonical = std::fs::canonicalize(file_path)
59+
.map_err(|e| format!("Failed to resolve file path '{file_path}': {e}"))?;
60+
let canonical = canonical
61+
.to_str()
62+
.ok_or_else(|| "Resolved path is not valid UTF-8".to_string())?;
63+
5264
let table_url =
53-
ListingTableUrl::parse(file_path).map_err(|e| format!("Failed to parse file path: {e}"))?;
65+
ListingTableUrl::parse(canonical).map_err(|e| format!("Failed to parse file path: {e}"))?;
66+
67+
// Clear the file extension filter (it defaults to `format.get_ext()`, i.e.
68+
// "vortex"). The CLI/TUI can open a Vortex file under any name, so registering
69+
// it for query must not require a `.vortex` extension. This is safe because the
70+
// canonical path above keeps us on the single-file path, so no directory listing
71+
// happens that an empty extension could over-match.
72+
let listing_options = ListingOptions::new(format)
73+
.with_file_extension("")
74+
.with_session_config_options(ctx.state().config());
5475

5576
let config = ListingTableConfig::new(table_url)
56-
.with_listing_options(
57-
ListingOptions::new(format).with_session_config_options(ctx.state().config()),
58-
)
77+
.with_listing_options(listing_options)
5978
.infer_schema(&ctx.state())
6079
.await
6180
.map_err(|e| format!("Failed to infer schema: {e}"))?;

0 commit comments

Comments
 (0)