Skip to content

fix: don't quote column names in list_indices - #7503

Merged
wjones127 merged 3 commits into
lance-format:mainfrom
dantasse:dantasse/quote-index-column-names
Jul 27, 2026
Merged

fix: don't quote column names in list_indices#7503
wjones127 merged 3 commits into
lance-format:mainfrom
dantasse:dantasse/quote-index-column-names

Conversation

@dantasse

@dantasse dantasse commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

The bug: have a column with a hyphen, like "col-3". Build an index on it. Call list_indices, get a value that's double-quoted, like:

{'name': 'col-3_idx', 'type': 'BTree', 'uuid': '5db8a52c-1398-437a-9d1f-9b2570dd1b19', 'fields': ['`col-3`'], 'version': 3, 'fragment_ids': {0}, 'base_id': None}

The fix: use field_path_minimal to only quote the value if it has a dot or a backtick in it (and therefore needs it - otherwise it's impossible to tell if my_loc.coords.lat is {my_loc: {coords: {lat: ...}}} or {my_loc: {"coords.lat": }}

I think this change is purely cosmetic, because calls like drop_column and update_field_metadata seem to work even when passed

"`col-3`"

So I am fine with either merging this or not (and prettifying it on the UI side e.g. if I display these results)

@github-actions github-actions Bot added A-python Python bindings A-namespace Namespace impls bug Something isn't working labels Jun 26, 2026
@wjones127
wjones127 self-requested a review July 6, 2026 23:39
@codecov

codecov Bot commented Jul 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.84615% with 4 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
rust/lance-core/src/datatypes/schema.rs 95.31% 2 Missing and 1 partial ⚠️
rust/lance-namespace-impls/src/dir.rs 0.00% 0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@wjones127 wjones127 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This looks thoughtfully done. If you get the remaining tests passing, I'd be open to merging this.

@dantasse
dantasse force-pushed the dantasse/quote-index-column-names branch from db34411 to 9ce957e Compare July 14, 2026 18:32
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: QUIET

Plan: Pro Plus

Run ID: 8d657e94-0183-47ac-9a4b-36ceeeac7471

📥 Commits

Reviewing files that changed from the base of the PR and between 0f79dae and ff1a242.

📒 Files selected for processing (5)
  • python/python/tests/test_column_names.py
  • python/src/indices.rs
  • rust/lance-core/src/datatypes.rs
  • rust/lance-core/src/datatypes/schema.rs
  • rust/lance-namespace-impls/src/dir.rs

📝 Walkthrough

Walkthrough

Schema field-path generation now supports minimal, round-trippable quoting. Python index descriptions and directory namespace index listings use the new format for indexed field names.

Changes

Field-path formatting and index integration

Layer / File(s) Summary
Schema minimal path formatting
rust/lance-core/src/datatypes/schema.rs, rust/lance-core/src/datatypes.rs
Adds minimal field-path formatting, documents its intended use, publicly re-exports the formatter, escapes embedded backticks, and tests hyphenated and dotted identifiers.
Index metadata path resolution
python/src/indices.rs, rust/lance-namespace-impls/src/dir.rs, python/python/tests/test_column_names.py
Uses minimal field paths for index metadata and updates special-character field-name expectations.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested labels: bug, A-python, A-namespace, A-index

Suggested reviewers: wjones127, xuanwo

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the main change: list_indices now avoids unnecessary quoting of column names.
Description check ✅ Passed The description is directly about the same bug and fix, including the field_path_minimal change.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@rust/lance-core/src/datatypes/schema.rs`:
- Around line 779-790: Add compilable doctest examples to the public APIs
Schema::field_path_minimal and format_field_path_minimal. Cover hyphenated
names, dotted segments, escaped backticks, and round-tripping the formatted
result through parse_field_path, using the existing public structs and methods
in the examples.
- Around line 2858-2915: Add coverage in test_field_path_minimal for a nested
field named child`x: assert field_path_minimal formats it with doubled-backtick
escaping as `child``x`, then assert parse_field_path round-trips the formatted
path to the original field components.
- Around line 1672-1680: Update the field-segment formatting logic in
format_field_path_minimal to treat empty strings like other segments requiring
quoting, producing a parseable quoted empty segment; alternatively, reject empty
field names during the existing schema validation path if empty segments are not
supported. Ensure formatted paths remain accepted by parse_field_path, including
["parent", ""].
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 541788a3-9038-4b15-9579-5d0693ec410d

📥 Commits

Reviewing files that changed from the base of the PR and between 0acc51e and 9ce957e.

📒 Files selected for processing (3)
  • python/src/indices.rs
  • rust/lance-core/src/datatypes/schema.rs
  • rust/lance-namespace-impls/src/dir.rs

Comment thread rust/lance-core/src/datatypes/schema.rs
Comment thread rust/lance-core/src/datatypes/schema.rs
Comment thread rust/lance-core/src/datatypes/schema.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
rust/lance-core/src/datatypes/schema.rs (1)

1669-1730: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract shared quoting/escaping helper for format_field_path and format_field_path_minimal.

The two functions are identical except for the needs_quoting predicate. Duplicated escape-and-join logic risks silently diverging (e.g., if backtick-escaping is fixed in one but not the other).

♻️ Proposed refactor
+fn format_field_path_with(fields: &[&str], needs_quoting: impl Fn(&str) -> bool) -> String {
+    fields
+        .iter()
+        .map(|field| {
+            if needs_quoting(field) {
+                let escaped = field.replace('`', "``");
+                format!("`{}`", escaped)
+            } else {
+                field.to_string()
+            }
+        })
+        .collect::<Vec<_>>()
+        .join(".")
+}
+
 pub fn format_field_path(fields: &[&str]) -> String {
-    fields
-        .iter()
-        .map(|field| {
-            // Quote if the field contains any non-identifier character
-            // (i.e., anything other than alphanumeric or underscore)
-            let needs_quoting = field.chars().any(|c| !c.is_alphanumeric() && c != '_');
-            if needs_quoting {
-                // Escape backticks by doubling them (PostgreSQL style)
-                let escaped = field.replace('`', "``");
-                format!("`{}`", escaped)
-            } else {
-                field.to_string()
-            }
-        })
-        .collect::<Vec<_>>()
-        .join(".")
+    format_field_path_with(fields, |field| {
+        field.chars().any(|c| !c.is_alphanumeric() && c != '_')
+    })
 }
...
 pub fn format_field_path_minimal(fields: &[&str]) -> String {
-    fields
-        .iter()
-        .map(|field| {
-            let needs_quoting = field.contains('.') || field.contains('`');
-            if needs_quoting {
-                let escaped = field.replace('`', "``");
-                format!("`{}`", escaped)
-            } else {
-                field.to_string()
-            }
-        })
-        .collect::<Vec<_>>()
-        .join(".")
+    format_field_path_with(fields, |field| field.contains('.') || field.contains('`'))
 }
As per coding guidelines, "Extract logic repeated in two or more places into a shared helper, but avoid helpers that only rename or forward existing calls."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rust/lance-core/src/datatypes/schema.rs` around lines 1669 - 1730, Extract
the shared segment escaping, quoting, and joining logic from format_field_path
and format_field_path_minimal into a helper that accepts the needs_quoting
predicate. Update both public functions to provide only their respective quoting
conditions and reuse the helper, preserving their existing output and backtick
escaping behavior.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@rust/lance-core/src/datatypes/schema.rs`:
- Around line 1669-1730: Extract the shared segment escaping, quoting, and
joining logic from format_field_path and format_field_path_minimal into a helper
that accepts the needs_quoting predicate. Update both public functions to
provide only their respective quoting conditions and reuse the helper,
preserving their existing output and backtick escaping behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 54ce8c0a-2b3b-41ba-b4e8-adc5ca9c9a0b

📥 Commits

Reviewing files that changed from the base of the PR and between 9ce957e and 0f79dae.

📒 Files selected for processing (2)
  • rust/lance-core/src/datatypes.rs
  • rust/lance-core/src/datatypes/schema.rs

@dantasse

Copy link
Copy Markdown
Contributor Author

@wjones127 ok, thanks! yeah I go back and forth on if it's even worth it but I guess so. so I added some coverage and ran the tests locally, seemed to pass; I guess you have to approve the rest of the tests?

@dantasse
dantasse force-pushed the dantasse/quote-index-column-names branch from 0f79dae to ff1a242 Compare July 24, 2026 16:43
@dantasse

Copy link
Copy Markdown
Contributor Author

@wjones127 ok, I think I fixed the test that was breaking; ready for another test run (do you already get notified for this? I'll stop @-ing you if so)

@wjones127
wjones127 merged commit c159a6d into lance-format:main Jul 27, 2026
37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-namespace Namespace impls A-python Python bindings bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants