Skip to content

Sync upstream with gradual SQL view conversion and compatible error tools - #42

Merged
VibeSWE merged 13 commits into
mainfrom
sync/upstream-oct16-compatible
Oct 16, 2026
Merged

VibeSWE merged 13 commits into
mainfrom
sync/upstream-oct16-compatible

Conversation

@VibeSWE

@VibeSWE VibeSWE commented Oct 16, 2026 •

Copy link
Copy Markdown

Sync upstream through a5976d2e while keeping native saved log views usable. An unchanged upstream merge would rewrite their dataset association to sql, leave old persisted copies behind, and change the existing schema tool response type.

Changes

  • Support both legacy dataset-scoped SQL filters and canonical stream_name: "sql". New native views stay dataset scoped until their owner selects Convert to SQL view. Converted views remain attached to their original explorer dataset, and subsequent edits preserve their format.
  • Add an authenticated, idempotent POST /api/v1/filters/{id}/convert-to-sql. Preserve owner, ID, query, time filter and extra metadata, including on admin updates and stale-client edits.
  • Write the canonical copy before removing aliases; remove aliases before the final copy on deletion. Startup reconciliation deterministically repairs duplicate legacy/SQL copies, preserves untouched legacy records and keeps owner/tenant boundaries. Cleanup failures remain retryable.
  • Classify log errors by explicit severity across supported aliases, with safe exact numeric comparisons and per-row fallback. Remove message-substring false positives. Keep full JSON as the schema tool default and offer compact output explicitly through format.
  • Include the six upstream commits (installer, OTEL/compact schema, pmeta startup cleanup, error tools, compose telemetry and SQL filters), retaining the fork's release URLs and additional OTEL/installer regression coverage.

Validation

  • Native frontend production build, TypeScript and formatting passed; 55 focused unit tests and 23 Chromium browser tests passed, including conversion, reopen/update, ownership, failures, stale responses and existing Logs regressions.
  • 20 filter-focused Rust tests and 19 tool tests passed, including real LocalFS persistence/failure/retry/tenant cases and generated SQL executed by DataFusion.
  • Native server build and isolated HTTP smoke passed: legacy create, authorization, admin ownership, conversion/retry, stale update, restart reconciliation of a seeded duplicate, and delete followed by restart.
  • Nine mocked installer tests, Rust formatting, and strict library Clippy passed.
  • Sol 6.1 and Opus 5.5 reviewed the implementation; their actionable findings were addressed.

The additional cargo clippy --lib --tests -- -D warnings check reports existing test-only lints in unchanged known_schema.rs, handlers/http/mod.rs, staging/reader.rs, and streams.rs. Strict cargo clippy --lib -- -D warnings passes.

Operational notes

Reconciliation runs at startup and after mutations; there is no one-time flag that can conceal partial cleanup. Mutations are serialized within one query-server process, not across multiple independent query servers sharing storage. An older native UI cannot display converted views; retain this compatible UI during rollback. See conversion and recovery notes. Existing deployments were not modified during testing.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

nikhilsinhaparseable and others added 11 commits October 12, 2026 22:37
* fix: install script

make installer platform aware, shell profile safe

* coderabbit comments fix

* coderabbit comments fix

* add separator newline when missing
* Misc updates

- added query param `?format=compact` to get a compact schema (defaults to JSON)
- if severity text/number is missing then the value is derived using the other field if present

* remove nullable from compact schema
* add log, trace errors as tools

* deesource error fix

* get_dataset_schema tool to return compact TSV response
currently failing because UI sends `stream_name=sql` in create/update filters
when called from sql editor

the stream name validation was added in the PR
parseablehq#1727

for a security fix
GHSA-q8xx-r33r-6mwv

with this change, the security fix still works
also, UI will be able to save the filter as-is

@comment-clanker comment-clanker Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Independent Sol 6.1 and Opus 5.5 review cycle: the first confirmed issue below needs a regression test and fix before merge.

Comment thread src/tool_executor.rs Outdated
Comment on lines +580 to +581
start_time: required_string(arguments, "startTime")?.to_owned(),
end_time: required_string(arguments, "endTime")?.to_owned(),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[P2] Preserve the requested time window when aggregating log errors.

query_internal parses these bounds with TimeRange::parse_human_time, which truncates both endpoints to the minute. The new aggregate query contains no exact timestamp predicate. A request for 12:00:30Z–12:01:30Z therefore includes errors from the preceding 30 seconds and drops errors in the final 30 seconds; a range entirely inside one minute becomes empty. This also affects ranges produced by resolve_time_range, whose end includes seconds.

Parse and validate the exact bounds, apply an explicit half-open timestamp predicate before aggregation (using the dataset's configured timestamp column), and expand the transport bounds to cover that exact interval. Add a regression fixture with rows before, inside, and at/after the requested boundaries, including a subminute range.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fixed in commit 85358dff (pushed). The log-error tool now uses exact half-open SQL bounds and a covering minute-aligned transport range. Filtering and lastSeen use the configured timestamp column; relative endpoints share one clock value.

TDD: the new DataFusion regression first failed because an error before the requested start was included. After the fix, all 21 tool tests pass, including six cases covering default/custom timestamps, cross-minute/subminute/fractional ranges, both boundaries, and the final partial minute. Formatting and strict library Clippy also pass. Fresh Sol 6.1 and Opus 5.5 reviews of the pushed fix are underway.

@comment-clanker comment-clanker Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Opus 5.5 identified three additional saved-view edge cases. Regression tests and fixes are underway; the earlier log time-window fix has passed independent Sol and Opus review.

Comment thread src/users/filters.rs Outdated
Comment on lines +160 to +163
// IDs are normally globally unique. Fail closed for an administrator
// if imported records make this owner-less URL ambiguous.
if matches.next().is_some() {
return None;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[P2] Preserve access to an administrator's own copy when legacy IDs collide.

The previous admin-update implementation could leave two records with the same filter ID under different owners. This PR now preserves both records in the cache, but an admin matching either owner is denied all operations because both match this predicate. Prefer an exact owner match before the admin fallback; keep rejecting an ambiguous fallback for unrelated admins. Also distinguish (owner, ID) in the native Saved views selector: it currently uses only filter_id for option keys/values and selects the first match, making the second owner's view inaccessible. Keep both owners' data intact and add upgrade/collision regression coverage.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fixed in e57d1ed7 (pushed). Cache lookup prefers the requester's own record before requiring a unique administrator fallback. The UI uses owner + ID for selection and preserves the original ID in API requests; no owners' records are deleted or combined.

RED: the administrator's own copy returned None, and the browser selected the other owner's view. GREEN: 21 filter tests and all 27 Logs browser tests pass, including independent selection/apply/update/conversion/deletion of colliding views.

Comment thread src/handlers/http/users/filters.rs Outdated
Comment on lines +100 to +103
PARSEABLE
.metastore
.reconcile_filter(&filter, &tenant_id)
.await?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[P2] Do not fail a new-view creation on unrelated alias cleanup.

The server has already durably written and cached a newly generated ULID here. Reconciliation then probes that new ID in every existing dataset directory for the owner. An unreadable unrelated directory or transient storage error returns a failure after the view was created. The UI does not refresh on error, and retrying creates another view with a new ID. New IDs have no old aliases to reconcile; reserve alias cleanup for updates/conversion/deletion. A failing-storage regression should assert that an unrelated lookup cannot turn a successful new write into a failed POST.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fixed in e57d1ed7 (pushed). New-filter POST no longer performs alias reconciliation for its freshly generated ID; update/conversion/deletion retain reconciliation.

RED: the live HTTP regression created an unreadable sibling directory and observed HTTP 500 after exactly one new JSON record was persisted. GREEN: the same test against the rebuilt binary succeeds, together with the complete authorization, conversion, stale-update, reconciliation and delete/restart smoke test.

Comment on lines +184 to +187
onOpenChange={(nextOpen) => {
if (!nextOpen) {
generation.current += 1;
setBusy(false);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[P2] Keep the mutation lock while a save is still pending.

Start a slow Save new view, close the dialog, and reopen before POST completes. This resets busy even though the request is still running, enabling another Save and a second POST. The first response then fails the generation check and skips the list refresh. Preserve the in-flight mutation state across close/reopen, refresh the current dataset after completion, and keep suppressing stale selection/notice updates. Add a browser regression that holds POST pending across close/reopen and verifies only one create request occurs.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fixed in e57d1ed7 (pushed). A mutation token keeps writes locked across close/reopen, refreshes after a successful current-context write, and prevents old dataset responses from unlocking a newer save. Dialog generations still protect selection and draft text. Failed conversion cleanup keeps Retry available.

RED: the browser regression observed Save enabled while the first POST was pending. GREEN: all 27 Logs browser tests and 74 focused unit tests pass, including close/reopen, dataset-switch races and cleanup-after-write retry. TypeScript, production build, formatting and strict Rust library Clippy pass. Fresh Sol 6.1 and Opus 5.5 reviews are checking this pushed commit.

@comment-clanker comment-clanker Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Repeated Sol 6.1 and Opus 5.5 reviews are clean on e57d1ed70ea870da0a1cf971076f8b9e16d0db83: no remaining actionable PR findings in the latest independent passes.

Four confirmed findings were posted as resolvable threads, reproduced with failing tests, fixed in 85358dff / e57d1ed7, and followed up with RED/GREEN evidence: precise log-error windows, legacy cross-owner ID collisions, new-filter failure after persistence, and duplicate saves during dialog close/reopen. Review of the UI fix also added coverage for conversion cleanup retry and dataset changes during pending writes.

Validation: 21 tool tests, 21 filter tests, 27 Logs Chromium tests, 74 focused frontend unit tests, nine installer tests, rebuilt-server HTTP/restart regression, TypeScript/production build, formatting and strict library Clippy pass. The latest CI checks are still running; this review does not claim they have passed.

The reviewed operational constraints remain documented: filter mutation locking is within one query-server process, and older native UIs cannot display converted views. No deployment or merge was performed.

@VibeSWE
VibeSWE merged commit b9ec5eb into main Oct 16, 2026
7 checks passed
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