Skip to content

Conversation

@Bill-hbrhbr
Copy link
Contributor

@Bill-hbrhbr Bill-hbrhbr commented Jun 29, 2025

Description

This PR:

clp-package:

clp-package-utils

Add dataset arguments --dataset to various package scripts‘ command-line interface. If no dataset argument is provided, the default dataset name is default.

webui

Add dataset selector to new webui. Dataset selector has to query backend to get datasets, and then display them. I also now pass the dataset to the log viewer connector.

The cachedDataset is the dataset when query is submitted. We have to do this since the user could change the selector, then click a link, which would result in an error. Instead we cache the dataset when they submitted the query.
Screenshot 2025-06-23 at 12 23 39 PM

Checklist

  • The PR satisfies the contribution guidelines.
  • This is a breaking change and that has been indicated in the PR title, OR this isn't a
    breaking change.
  • Necessary docs have been updated, OR no docs need to be updated.

Validation performed

  • Verified correctness in the following use cases:
    • CLI
    • UI

Summary by CodeRabbit

  • New Features

    • Added dataset selection and filtering to the search interface for users with the CLP_S storage engine.
    • Introduced dataset support in compression, decompression, archive management, and search scripts via new command-line options.
    • Integrated React Query for enhanced data fetching and caching in the web UI.
    • Added new UI components and styles for dataset selection controls on the search page.
    • Enhanced query submission and timeline controls to include dataset context.
  • Bug Fixes

    • Improved validation and error handling for dataset selection and command usage across scripts and UI components.
  • Refactor

    • Removed default dataset logic; dataset must now be explicitly specified in relevant operations.
    • Updated internal APIs and state management to support dataset-aware workflows throughout the application.
    • Removed deprecated configuration constants from the server codebase.
  • Chores

    • Updated configuration files to remove obsolete storage engine settings and add dataset table naming.
    • Renamed and added dataset validation utilities for improved dataset name enforcement.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jun 29, 2025

## Walkthrough

This change introduces explicit dataset selection and handling throughout the CLP system, affecting the web UI client, server API, and CLI scripts. It removes hardcoded defaults and storage-engine-based dataset logic, replacing them with explicit dataset arguments, state, and validation. New UI components and API endpoints now support dataset filtering and selection.

## Changes

| File(s) / Group                                                                                         | Change Summary |
|---------------------------------------------------------------------------------------------------------|---------------|
| `components/webui/client/package.json`                                                                  | Added `@tanstack/react-query` and `@tanstack/react-query-devtools` as dependencies. |
| `components/webui/client/src/App.tsx`                                                                  | Integrated React Query context and devtools into the app. |
| `components/webui/client/src/api/query.ts`                                                             | Refactored `submitExtractStreamJob` to use a props object including new `dataset` parameter. |
| `components/webui/client/src/api/search.ts`, `components/webui/server/src/fastify-v2/schemas/search.ts`| Added optional `dataset` property to `QueryJobCreationSchema` type/schema. |
| `components/webui/client/src/api/sql.ts`                                                               | Added new `querySql` function for SQL queries via Axios. |
| `components/webui/client/src/pages/IngestPage/Details/index.tsx`,<br>`.../Jobs/index.tsx`,<br>`.../SpaceSavings/index.tsx` | Updated import path for `querySql` to new API module. |
| `components/webui/client/src/pages/IngestPage/sqlConfig.ts`                                            | Removed `querySql` function and its export. |
| `components/webui/client/src/pages/SearchPage/SearchControls/Dataset/DatasetLabel/index.module.css`     | Added new CSS module for dataset label styling. |
| `components/webui/client/src/pages/SearchPage/SearchControls/Dataset/DatasetLabel/index.tsx`            | Added new `DatasetLabel` React component. |
| `components/webui/client/src/pages/SearchPage/SearchControls/Dataset/index.module.css`                  | Added new CSS module for dataset selector styling. |
| `components/webui/client/src/pages/SearchPage/SearchControls/Dataset/index.tsx`                         | Added new `Dataset` React component for dataset selection UI. |
| `components/webui/client/src/pages/SearchPage/SearchControls/Dataset/sql.ts`                            | Added `fetchDatasetNames` function for retrieving datasets via SQL. |
| `components/webui/client/src/pages/SearchPage/SearchControls/SearchButton/SubmitButton/index.tsx`       | Enhanced submission logic to require dataset selection for `CLP_S` storage engine. |
| `components/webui/client/src/pages/SearchPage/SearchControls/index.tsx`                                 | Conditionally renders `Dataset` selector based on storage engine. |
| `components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/Message/LogViewerLink.tsx`| Appends `dataset` to log viewer links from search state. |
| `components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/index.tsx`            | Handles dataset in timeline zoom and query submission for `CLP_S`. |
| `components/webui/client/src/pages/SearchPage/SearchState/index.tsx`                                   | Extended search state with `cachedDataset` and `selectDataset` fields and update methods. |
| `components/webui/client/src/typings/query.ts`                                                         | Added `dataset` property to `ExtractJobSearchParams` type. |
| `components/webui/client/src/ui/QueryStatus.tsx`                                                       | Updated `submitExtractStreamJob` call to use new object parameter with `dataset`. |
| `components/webui/server/src/fastify-v2/routes/api/search/index.ts`                                    | `/query` route now directly assigns `dataset` from request body. |
| `components/webui/server/src/plugins/DbManager.ts`                                                     | `submitAndWaitForExtractStreamJob` now requires explicit `dataset` parameter. |
| `components/webui/server/src/routes/query.ts`                                                          | `/query/extract-stream` POST endpoint requires `dataset` in request body. |
| `components/clp-package-utils/clp_package_utils/scripts/archive_manager.py`,<br>`.../compress.py`,<br>`.../decompress.py`,<br>`.../search.py` | Added optional `--dataset` CLI argument and logic for validation and command construction. |
| `components/clp-package-utils/clp_package_utils/scripts/native/archive_manager.py`,<br>`.../compress.py`,<br>`.../decompress.py`,<br>`.../search.py` | Added optional `--dataset` CLI argument, removed storage-engine-based defaulting, and updated internal dataset handling. |
| `components/webui/server/src/configConstants.ts`                                                       | Deleted file, removing `CLP_STORAGE_ENGINE_CLP_S` and `CLP_DEFAULT_DATASET_NAME` constants. |
| `components/clp-package-utils/clp_package_utils/general.py`                                            | Renamed `validate_dataset` to `validate_dataset_exists`; added new `validate_dataset_name` function for dataset name validation. |
| `components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py`                                        | Added constants `MYSQL_TABLE_NAME_MAX_LEN` and `TABLE_SUFFIX_MAX_LEN` for dataset name validation. |
| `components/clp-package-utils/clp_package_utils/scripts/start_clp.py`                                  | Removed "ClpStorageEngine" key from server settings JSON update. |
| `components/webui/server/settings.json`                                                               | Removed "ClpStorageEngine" setting from JSON configuration. |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant User
    participant WebUI
    participant ServerAPI
    participant DbManager

    User->>WebUI: Selects dataset (if CLP_S)
    User->>WebUI: Submits search or extract job
    WebUI->>ServerAPI: POST /query or /query/extract-stream (includes dataset)
    ServerAPI->>DbManager: submitAndWaitForExtractStreamJob({dataset, ...})
    DbManager-->>ServerAPI: Job result
    ServerAPI-->>WebUI: Response
    WebUI-->>User: Displays results/status

Possibly related PRs

Suggested reviewers

  • davemarco
  • kirkrodrigues


<!-- walkthrough_end -->


---

<details>
<summary>📜 Recent review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: ASSERTIVE**
**Plan: Pro**


<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 3f1c3affcf246a248abd93e0a8899636213628b0 and 06695f3ad18f0a62f4b7c54008d18b4b9f29faf2.

</details>

<details>
<summary>📒 Files selected for processing (3)</summary>

* `components/webui/server/src/fastify-v2/routes/api/search/index.ts` (2 hunks)
* `components/webui/server/src/fastify-v2/schemas/search.ts` (1 hunks)
* `components/webui/server/src/routes/query.ts` (2 hunks)

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>📓 Path-based instructions (1)</summary>

<details>
<summary>`**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}`: - Prefer `false == <expression>` rather than `!<expression>`.</summary>


> `**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}`: - Prefer `false == <expression>` rather than `!<expression>`.

⚙️ Source: CodeRabbit Configuration File

List of files the instruction was applied to:
- `components/webui/server/src/routes/query.ts`
- `components/webui/server/src/fastify-v2/schemas/search.ts`
- `components/webui/server/src/fastify-v2/routes/api/search/index.ts`

</details>

</details><details>
<summary>🧠 Learnings (4)</summary>

<details>
<summary>📓 Common learnings</summary>

Learnt from: Bill-hbrhbr
PR: #1050
File: components/clp-package-utils/clp_package_utils/scripts/search.py:100-106
Timestamp: 2025-07-03T20:10:43.761Z
Learning: In the current CLP codebase implementation, dataset validation using validate_dataset() is performed within the native scripts (like clp_package_utils/scripts/native/search.py) rather than at the wrapper script level, where the native scripts handle their own parameter validation.


Learnt from: Bill-hbrhbr
PR: #1050
File: components/clp-package-utils/clp_package_utils/scripts/search.py:100-106
Timestamp: 2025-07-03T20:10:43.761Z
Learning: In the current CLP codebase implementation, dataset validation using validate_dataset() is performed within the native scripts (like clp_package_utils/scripts/native/search.py) rather than at the wrapper script level, where the native scripts handle their own parameter validation.


Learnt from: Bill-hbrhbr
PR: #1036
File: components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py:204-211
Timestamp: 2025-07-03T12:58:18.407Z
Learning: In the CLP codebase, the validate_and_cache_dataset function in components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py uses in-place updates of the existing_datasets set parameter rather than returning a new set, as preferred by the development team.


Learnt from: Bill-hbrhbr
PR: #1004
File: components/clp-package-utils/clp_package_utils/scripts/native/decompress.py:139-144
Timestamp: 2025-06-24T08:54:14.438Z
Learning: In the CLP codebase, the get_orig_file_id function signature was changed after a recent merge to no longer accept a dataset parameter, making previous suggestions that reference this parameter invalid.


Learnt from: Bill-hbrhbr
PR: #1036
File: components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py:188-212
Timestamp: 2025-07-03T12:59:46.638Z
Learning: In CLP schedulers (compression and query), runtime dataset validation is required; the helper validate_and_cache_dataset keeps a local cache and only queries the DB on cache misses because dataset additions are rare.


Learnt from: Bill-hbrhbr
PR: #868
File: components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py:141-144
Timestamp: 2025-05-05T16:32:55.163Z
Learning: The column metadata table (created by _create_column_metadata_table) is only needed for dataset-specific workflows in CLP_S and is obsolete for non-dataset workflows.


Learnt from: kirkrodrigues
PR: #881
File: components/core/tools/scripts/lib_install/ubuntu-jammy/install-prebuilt-packages.sh:35-41
Timestamp: 2025-05-06T09:48:55.408Z
Learning: For installation scripts in the CLP project, prefer explicit error handling over automatic dependency resolution (like apt-get install -f) when installing packages to give users more control over their system.


</details>
<details>
<summary>components/webui/server/src/routes/query.ts (2)</summary>

Learnt from: junhaoliao
PR: #596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In components/log-viewer-webui/client/src/api/query.js, the ExtractJsonResp type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.


Learnt from: junhaoliao
PR: #988
File: components/log-viewer-webui/client/src/components/QueryBox/InputWithCaseSensitive/CaseSenstiveToggle.tsx:34-37
Timestamp: 2025-06-09T17:48:56.024Z
Learning: In the y-scope/clp project, prefer false == <expression> rather than !<expression> for boolean expressions in TypeScript/JavaScript files, as specified in the coding guidelines.


</details>
<details>
<summary>components/webui/server/src/fastify-v2/schemas/search.ts (1)</summary>

Learnt from: junhaoliao
PR: #596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In components/log-viewer-webui/client/src/api/query.js, the ExtractJsonResp type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.


</details>
<details>
<summary>components/webui/server/src/fastify-v2/routes/api/search/index.ts (5)</summary>

Learnt from: Bill-hbrhbr
PR: #1004
File: components/clp-package-utils/clp_package_utils/scripts/native/decompress.py:139-144
Timestamp: 2025-06-24T08:54:14.438Z
Learning: In the CLP codebase, the get_orig_file_id function signature was changed after a recent merge to no longer accept a dataset parameter, making previous suggestions that reference this parameter invalid.


Learnt from: Bill-hbrhbr
PR: #1036
File: components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py:204-211
Timestamp: 2025-07-03T12:58:18.407Z
Learning: In the CLP codebase, the validate_and_cache_dataset function in components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py uses in-place updates of the existing_datasets set parameter rather than returning a new set, as preferred by the development team.


Learnt from: junhaoliao
PR: #596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In components/log-viewer-webui/client/src/api/query.js, the ExtractJsonResp type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.


Learnt from: junhaoliao
PR: #988
File: components/log-viewer-webui/client/src/components/QueryBox/InputWithCaseSensitive/CaseSenstiveToggle.tsx:34-37
Timestamp: 2025-06-09T17:48:56.024Z
Learning: In the y-scope/clp project, prefer false == <expression> rather than !<expression> for boolean expressions in TypeScript/JavaScript files, as specified in the coding guidelines.


Learnt from: LinZhihao-723
PR: #882
File: components/core/src/clp/ffi/ir_stream/search/QueryHandlerImpl.cpp:378-402
Timestamp: 2025-05-07T16:56:35.687Z
Learning: In the CLP search component, the evaluate_wildcard_filter function should return AstEvaluationResult::Pruned when node_id_value_pairs is empty, not AstEvaluationResult::False. Empty node sets should be treated as "undetermined" rather than definitive non-matches.


</details>

</details>

</details>

<details>
<summary>🔇 Additional comments (6)</summary><blockquote>

<details>
<summary>components/webui/server/src/fastify-v2/schemas/search.ts (1)</summary>

`13-16`: **Well-documented schema change with important technical note.**

The addition of the optional `dataset` field to the schema is correctly implemented. The comment about `Type.Null()` ordering is valuable technical documentation that explains why this specific order prevents unintended serialization conversion from `{dataset: null}` to `{dataset: ""}`.

</details>
<details>
<summary>components/webui/server/src/fastify-v2/routes/api/search/index.ts (2)</summary>

`63-63`: **Correct extraction of dataset parameter.**

The destructuring correctly extracts the `dataset` field from the request body, aligning with the updated schema.

---

`73-73`: **Clean direct parameter passing replaces conditional logic.**

The direct assignment of `dataset: dataset` is cleaner and more explicit than the previous conditional logic based on storage engine constants. This aligns with the broader refactor to remove implicit defaults.

</details>
<details>
<summary>components/webui/server/src/routes/query.ts (3)</summary>

`41-44`: **Consistent schema update with proper technical documentation.**

The dataset field addition follows the same pattern as the search schema, with the same important comment about `Type.Null()` ordering to prevent serialization issues. Good consistency across the codebase.

---

`51-51`: **Correct parameter extraction from request body.**

The destructuring properly extracts the `dataset` field alongside the other parameters, consistent with the updated schema.

---

`64-64`: **Proper dataset parameter passing to job submission.**

The `dataset` parameter is correctly passed to the `submitAndWaitForExtractStreamJob` method, completing the end-to-end dataset handling for extract stream jobs.

</details>

</blockquote></details>

</details>
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

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.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=y-scope/clp&utm_content=1050):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

@Bill-hbrhbr Bill-hbrhbr marked this pull request as ready for review June 29, 2025 12:09
@Bill-hbrhbr Bill-hbrhbr requested a review from a team as a code owner June 29, 2025 12:09
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bb8244c and 869b02d.

⛔ Files ignored due to path filters (1)
  • components/webui/client/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (26)
  • components/webui/client/package.json (1 hunks)
  • components/webui/client/src/App.tsx (2 hunks)
  • components/webui/client/src/api/query.ts (1 hunks)
  • components/webui/client/src/api/search.ts (1 hunks)
  • components/webui/client/src/api/sql.ts (1 hunks)
  • components/webui/client/src/pages/IngestPage/Details/index.tsx (1 hunks)
  • components/webui/client/src/pages/IngestPage/Jobs/index.tsx (1 hunks)
  • components/webui/client/src/pages/IngestPage/SpaceSavings/index.tsx (1 hunks)
  • components/webui/client/src/pages/IngestPage/sqlConfig.ts (0 hunks)
  • components/webui/client/src/pages/SearchPage/SearchControls/Dataset/DatasetLabel/index.module.css (1 hunks)
  • components/webui/client/src/pages/SearchPage/SearchControls/Dataset/DatasetLabel/index.tsx (1 hunks)
  • components/webui/client/src/pages/SearchPage/SearchControls/Dataset/index.module.css (1 hunks)
  • components/webui/client/src/pages/SearchPage/SearchControls/Dataset/index.tsx (1 hunks)
  • components/webui/client/src/pages/SearchPage/SearchControls/Dataset/sql.ts (1 hunks)
  • components/webui/client/src/pages/SearchPage/SearchControls/SearchButton/SubmitButton.tsx (0 hunks)
  • components/webui/client/src/pages/SearchPage/SearchControls/SearchButton/SubmitButton/index.tsx (1 hunks)
  • components/webui/client/src/pages/SearchPage/SearchControls/index.tsx (2 hunks)
  • components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/Message/LogViewerLink.tsx (3 hunks)
  • components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/index.tsx (3 hunks)
  • components/webui/client/src/pages/SearchPage/SearchState/index.tsx (6 hunks)
  • components/webui/client/src/typings/query.ts (1 hunks)
  • components/webui/client/src/ui/QueryStatus.tsx (2 hunks)
  • components/webui/server/src/fastify-v2/routes/api/search/index.ts (2 hunks)
  • components/webui/server/src/fastify-v2/schemas/search.ts (1 hunks)
  • components/webui/server/src/plugins/DbManager.ts (2 hunks)
  • components/webui/server/src/routes/query.ts (2 hunks)
💤 Files with no reviewable changes (2)
  • components/webui/client/src/pages/IngestPage/sqlConfig.ts
  • components/webui/client/src/pages/SearchPage/SearchControls/SearchButton/SubmitButton.tsx
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}`: - Prefer `false == ` rather than `!`.

**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}: - Prefer false == <expression> rather than !<expression>.

⚙️ Source: CodeRabbit Configuration File

List of files the instruction was applied to:

  • components/webui/client/src/pages/IngestPage/SpaceSavings/index.tsx
  • components/webui/client/src/pages/IngestPage/Details/index.tsx
  • components/webui/client/src/api/search.ts
  • components/webui/server/src/fastify-v2/schemas/search.ts
  • components/webui/client/src/App.tsx
  • components/webui/server/src/routes/query.ts
  • components/webui/client/src/typings/query.ts
  • components/webui/client/src/pages/SearchPage/SearchControls/Dataset/DatasetLabel/index.tsx
  • components/webui/server/src/fastify-v2/routes/api/search/index.ts
  • components/webui/client/src/ui/QueryStatus.tsx
  • components/webui/client/src/api/sql.ts
  • components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/index.tsx
  • components/webui/client/src/pages/SearchPage/SearchControls/Dataset/sql.ts
  • components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/Message/LogViewerLink.tsx
  • components/webui/client/src/pages/SearchPage/SearchControls/Dataset/index.tsx
  • components/webui/client/src/pages/IngestPage/Jobs/index.tsx
  • components/webui/client/src/pages/SearchPage/SearchControls/index.tsx
  • components/webui/server/src/plugins/DbManager.ts
  • components/webui/client/src/pages/SearchPage/SearchControls/SearchButton/SubmitButton/index.tsx
  • components/webui/client/src/api/query.ts
  • components/webui/client/src/pages/SearchPage/SearchState/index.tsx
🧠 Learnings (19)
components/webui/client/src/pages/IngestPage/SpaceSavings/index.tsx (1)
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In `components/log-viewer-webui/client/src/api/query.js`, the `ExtractJsonResp` type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.
components/webui/client/src/pages/IngestPage/Details/index.tsx (2)
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In `components/log-viewer-webui/client/src/api/query.js`, the `ExtractJsonResp` type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:35-41
Timestamp: 2024-11-19T19:52:43.429Z
Learning: For internal APIs in `components/log-viewer-webui/client/src/api/query.js`, runtime validation of parameters may not be necessary since the APIs are not exposed to end users, and JsDoc type annotations may be sufficient.
components/webui/client/src/api/search.ts (1)
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In `components/log-viewer-webui/client/src/api/query.js`, the `ExtractJsonResp` type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.
components/webui/server/src/fastify-v2/schemas/search.ts (1)
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In `components/log-viewer-webui/client/src/api/query.js`, the `ExtractJsonResp` type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.
components/webui/client/package.json (3)
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In `components/log-viewer-webui/client/src/api/query.js`, the `ExtractJsonResp` type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.
Learnt from: junhaoliao
PR: y-scope/clp#939
File: components/package-template/src/etc/clp-config.yml:64-64
Timestamp: 2025-06-22T04:01:43.409Z
Learning: The new webui architecture uses Fastify with Pino logging instead of the previous Winston-based logging system that was removed during the webui refactoring.
Learnt from: davemarco
PR: y-scope/clp#797
File: components/log-viewer-webui/client/src/components/Layout/MainLayout.tsx:2-5
Timestamp: 2025-04-08T22:32:05.366Z
Learning: In this codebase using React Router v7.4.1, components should be imported directly from "react-router" (e.g., `import { Link, Outlet } from "react-router";`) rather than from "react-router-dom" as was common in previous versions of React Router.
components/webui/client/src/App.tsx (5)
Learnt from: davemarco
PR: y-scope/clp#797
File: components/log-viewer-webui/client/src/components/Layout/MainLayout.tsx:2-5
Timestamp: 2025-04-08T22:32:05.366Z
Learning: In this codebase using React Router v7.4.1, components should be imported directly from "react-router" (e.g., `import { Link, Outlet } from "react-router";`) rather than from "react-router-dom" as was common in previous versions of React Router.
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In `components/log-viewer-webui/client/src/api/query.js`, the `ExtractJsonResp` type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.
Learnt from: davemarco
PR: y-scope/clp#797
File: components/log-viewer-webui/client/src/routes/routes.tsx:1-1
Timestamp: 2025-04-04T15:15:59.432Z
Learning: In React Router v7, `createBrowserRouter` and other router primitives should be imported from `react-router` package, not from `react-router-dom` as in previous versions. This represents a significant change in the library's structure where router primitives are now in the core package.
Learnt from: davemarco
PR: y-scope/clp#797
File: components/log-viewer-webui/client/src/components/Layout/MainLayout.tsx:2-5
Timestamp: 2025-04-08T22:32:05.367Z
Learning: React Router v7.4.1 uses a different package structure than previous versions. Components can be imported directly from "react-router" (e.g., `import { Link, Outlet } from "react-router";`) rather than from "react-router-dom" as was common in previous versions. Alternatively, DOM-specific components can also be imported using deep imports like `import { Link } from "react-router/dom";`.
Learnt from: junhaoliao
PR: y-scope/clp#937
File: components/log-viewer-webui/client/src/AntdApp.tsx:16-24
Timestamp: 2025-05-29T20:33:40.653Z
Learning: In components/log-viewer-webui React codebase: Return type annotations (like `: JSX.Element`) are unnecessary and not preferred for React components in JSX/TSX files.
components/webui/server/src/routes/query.ts (1)
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In `components/log-viewer-webui/client/src/api/query.js`, the `ExtractJsonResp` type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.
components/webui/client/src/typings/query.ts (1)
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In `components/log-viewer-webui/client/src/api/query.js`, the `ExtractJsonResp` type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.
components/webui/client/src/pages/SearchPage/SearchControls/Dataset/DatasetLabel/index.tsx (1)
Learnt from: junhaoliao
PR: y-scope/clp#937
File: components/log-viewer-webui/client/src/AntdApp.tsx:16-24
Timestamp: 2025-05-29T20:33:40.653Z
Learning: In components/log-viewer-webui React codebase: Return type annotations (like `: JSX.Element`) are unnecessary and not preferred for React components in JSX/TSX files.
components/webui/server/src/fastify-v2/routes/api/search/index.ts (1)
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1004
File: components/clp-package-utils/clp_package_utils/scripts/native/decompress.py:139-144
Timestamp: 2025-06-24T08:54:14.438Z
Learning: In the CLP codebase, the get_orig_file_id function signature was changed after a recent merge to no longer accept a dataset parameter, making previous suggestions that reference this parameter invalid.
components/webui/client/src/ui/QueryStatus.tsx (1)
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In `components/log-viewer-webui/client/src/api/query.js`, the `ExtractJsonResp` type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.
components/webui/client/src/api/sql.ts (1)
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In `components/log-viewer-webui/client/src/api/query.js`, the `ExtractJsonResp` type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.
components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/index.tsx (4)
Learnt from: junhaoliao
PR: y-scope/clp#962
File: components/log-viewer-webui/client/src/pages/SearchPage/SearchQueryStatus/Results.tsx:22-26
Timestamp: 2025-06-09T17:15:30.309Z
Learning: When using Zustand stores in React components, always use specific selectors (e.g., `useStore(state => state.property)`) instead of destructuring the entire state object to prevent unnecessary re-renders. This is especially important as state stores grow in complexity.
Learnt from: junhaoliao
PR: y-scope/clp#962
File: components/log-viewer-webui/client/src/pages/SearchPage/SearchQueryStatus/Results.tsx:22-26
Timestamp: 2025-06-09T17:15:30.309Z
Learning: When using Zustand stores in React components, always use specific selectors (e.g., `useStore(state => state.property)`) instead of destructuring the entire state object to prevent unnecessary re-renders. This is especially important as state stores grow in complexity.
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In `components/log-viewer-webui/client/src/api/query.js`, the `ExtractJsonResp` type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.
Learnt from: junhaoliao
PR: y-scope/clp#937
File: components/log-viewer-webui/client/src/AntdApp.tsx:16-24
Timestamp: 2025-05-29T20:33:40.653Z
Learning: In components/log-viewer-webui React codebase: Return type annotations (like `: JSX.Element`) are unnecessary and not preferred for React components in JSX/TSX files.
components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/Message/LogViewerLink.tsx (6)
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In `components/log-viewer-webui/client/src/api/query.js`, the `ExtractJsonResp` type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.
Learnt from: davemarco
PR: y-scope/clp#797
File: components/log-viewer-webui/client/src/components/Layout/MainLayout.tsx:2-5
Timestamp: 2025-04-08T22:32:05.366Z
Learning: In this codebase using React Router v7.4.1, components should be imported directly from "react-router" (e.g., `import { Link, Outlet } from "react-router";`) rather than from "react-router-dom" as was common in previous versions of React Router.
Learnt from: junhaoliao
PR: y-scope/clp#937
File: components/log-viewer-webui/client/src/AntdApp.tsx:16-24
Timestamp: 2025-05-29T20:33:40.653Z
Learning: In components/log-viewer-webui React codebase: Return type annotations (like `: JSX.Element`) are unnecessary and not preferred for React components in JSX/TSX files.
Learnt from: davemarco
PR: y-scope/clp#797
File: components/log-viewer-webui/client/src/components/Layout/MainLayout.tsx:2-5
Timestamp: 2025-04-08T22:32:05.367Z
Learning: React Router v7.4.1 uses a different package structure than previous versions. Components can be imported directly from "react-router" (e.g., `import { Link, Outlet } from "react-router";`) rather than from "react-router-dom" as was common in previous versions. Alternatively, DOM-specific components can also be imported using deep imports like `import { Link } from "react-router/dom";`.
Learnt from: junhaoliao
PR: y-scope/clp#962
File: components/log-viewer-webui/client/src/pages/SearchPage/SearchQueryStatus/Results.tsx:22-26
Timestamp: 2025-06-09T17:15:30.309Z
Learning: When using Zustand stores in React components, always use specific selectors (e.g., `useStore(state => state.property)`) instead of destructuring the entire state object to prevent unnecessary re-renders. This is especially important as state stores grow in complexity.
Learnt from: junhaoliao
PR: y-scope/clp#962
File: components/log-viewer-webui/client/src/pages/SearchPage/SearchQueryStatus/Results.tsx:22-26
Timestamp: 2025-06-09T17:15:30.309Z
Learning: When using Zustand stores in React components, always use specific selectors (e.g., `useStore(state => state.property)`) instead of destructuring the entire state object to prevent unnecessary re-renders. This is especially important as state stores grow in complexity.
components/webui/client/src/pages/SearchPage/SearchControls/Dataset/index.tsx (3)
Learnt from: junhaoliao
PR: y-scope/clp#937
File: components/log-viewer-webui/client/src/AntdApp.tsx:16-24
Timestamp: 2025-05-29T20:33:40.653Z
Learning: In components/log-viewer-webui React codebase: Return type annotations (like `: JSX.Element`) are unnecessary and not preferred for React components in JSX/TSX files.
Learnt from: junhaoliao
PR: y-scope/clp#962
File: components/log-viewer-webui/client/src/pages/SearchPage/SearchQueryStatus/Results.tsx:22-26
Timestamp: 2025-06-09T17:15:30.309Z
Learning: When using Zustand stores in React components, always use specific selectors (e.g., `useStore(state => state.property)`) instead of destructuring the entire state object to prevent unnecessary re-renders. This is especially important as state stores grow in complexity.
Learnt from: junhaoliao
PR: y-scope/clp#962
File: components/log-viewer-webui/client/src/pages/SearchPage/SearchQueryStatus/Results.tsx:22-26
Timestamp: 2025-06-09T17:15:30.309Z
Learning: When using Zustand stores in React components, always use specific selectors (e.g., `useStore(state => state.property)`) instead of destructuring the entire state object to prevent unnecessary re-renders. This is especially important as state stores grow in complexity.
components/webui/client/src/pages/IngestPage/Jobs/index.tsx (1)
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In `components/log-viewer-webui/client/src/api/query.js`, the `ExtractJsonResp` type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.
components/webui/server/src/plugins/DbManager.ts (1)
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In `components/log-viewer-webui/client/src/api/query.js`, the `ExtractJsonResp` type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.
components/webui/client/src/pages/SearchPage/SearchControls/SearchButton/SubmitButton/index.tsx (1)
Learnt from: junhaoliao
PR: y-scope/clp#937
File: components/log-viewer-webui/client/src/AntdApp.tsx:16-24
Timestamp: 2025-05-29T20:33:40.653Z
Learning: In components/log-viewer-webui React codebase: Return type annotations (like `: JSX.Element`) are unnecessary and not preferred for React components in JSX/TSX files.
components/webui/client/src/api/query.ts (2)
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In `components/log-viewer-webui/client/src/api/query.js`, the `ExtractJsonResp` type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:35-41
Timestamp: 2024-11-19T19:52:43.429Z
Learning: For internal APIs in `components/log-viewer-webui/client/src/api/query.js`, runtime validation of parameters may not be necessary since the APIs are not exposed to end users, and JsDoc type annotations may be sufficient.
🧬 Code Graph Analysis (5)
components/webui/client/src/ui/QueryStatus.tsx (2)
components/webui/client/src/api/query.ts (1)
  • submitExtractStreamJob (51-51)
components/webui/client/src/typings/query.ts (2)
  • EXTRACT_JOB_TYPE (92-92)
  • QUERY_LOADING_STATE (95-95)
components/webui/client/src/pages/SearchPage/SearchControls/Dataset/sql.ts (1)
components/webui/client/src/api/sql.ts (1)
  • querySql (14-14)
components/webui/client/src/pages/SearchPage/SearchControls/Dataset/index.tsx (1)
components/webui/client/src/pages/SearchPage/SearchControls/Dataset/sql.ts (1)
  • fetchDatasetNames (41-41)
components/webui/client/src/pages/SearchPage/SearchControls/SearchButton/SubmitButton/index.tsx (1)
components/webui/client/src/pages/SearchPage/SearchState/index.tsx (1)
  • SEARCH_STATE_DEFAULT (152-152)
components/webui/client/src/api/query.ts (1)
components/webui/client/src/typings/query.ts (2)
  • QUERY_JOB_TYPE (94-94)
  • ExtractStreamResp (90-90)
🔇 Additional comments (38)
components/webui/client/src/pages/IngestPage/SpaceSavings/index.tsx (1)

9-9: LGTM! Import path correctly updated.

The import path change aligns with the centralization of SQL query logic into the shared API module.

components/webui/client/src/pages/IngestPage/Jobs/index.tsx (1)

9-9: LGTM! Import path correctly updated.

The import path change is consistent with the centralization of SQL query logic and follows the same pattern as other IngestPage components.

components/webui/client/src/pages/IngestPage/Details/index.tsx (1)

10-10: LGTM! Import path correctly updated.

The import path change completes the consistent refactor across IngestPage components to use the centralized SQL query API.

components/webui/client/src/pages/SearchPage/SearchControls/Dataset/DatasetLabel/index.module.css (1)

1-9: LGTM! Clean CSS styling for dataset label component.

The flexbox layout with centre alignment and border radius adjustments is appropriate for a label that visually connects to an adjacent selector element.

components/webui/server/src/fastify-v2/schemas/search.ts (1)

13-13: LGTM! Clean addition of required dataset parameter.

The schema extension is consistent with the PR objectives and properly typed using TypeBox's string validation.

components/webui/client/src/api/search.ts (1)

18-18: LGTM! Consistent type definition aligns with server schema.

The addition of the required dataset string property maintains type consistency between client and server schemas.

components/webui/client/src/pages/SearchPage/SearchControls/Dataset/index.module.css (1)

1-13: LGTM! Appropriate styling for dataset selector component.

The flexbox layout and width constraints provide consistent UI sizing. The use of !important for Ant Design component overrides is justified when customising third-party component libraries.

components/webui/client/src/typings/query.ts (1)

52-52: LGTM! Consistent schema extension for extract job parameters.

The addition of the required dataset parameter using TypeBox's Type.String() maintains consistency with existing schema patterns and ensures type safety for extract operations.

components/webui/server/src/routes/query.ts (3)

41-41: LGTM! Dataset parameter correctly added to schema.

The dataset parameter is properly defined as a required string in the request body schema.


48-48: LGTM! Dataset parameter correctly extracted from request body.

The destructuring follows the established pattern and correctly extracts the dataset field.


61-61: LGTM! Dataset parameter correctly passed to job submission.

The dataset is properly included in the parameters passed to submitAndWaitForExtractStreamJob.

components/webui/client/src/App.tsx (3)

3-7: LGTM! React Query imports are correct.

The imports from @tanstack/react-query and @tanstack/react-query-devtools are properly structured.


16-16: LGTM! QueryClient instance created correctly.

The QueryClient is instantiated with default configuration, which is appropriate for most use cases.


25-32: LGTM! React Query provider integration is correct.

The QueryClientProvider properly wraps the existing providers and the ReactQueryDevtools is appropriately configured with initialIsOpen={false}.

components/webui/client/src/pages/SearchPage/SearchControls/Dataset/DatasetLabel/index.tsx (1)

1-35: LGTM! Component implementation follows established patterns.

The DatasetLabel component correctly uses Ant Design theming and Typography. The combination of CSS modules and inline styles allows for both static styling and dynamic theming based on design tokens, which is appropriate for this use case.

components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTable/Message/LogViewerLink.tsx (3)

11-11: LGTM! Correct import of search store.

The useSearchStore import is properly added for accessing the cached dataset state.


36-36: LGTM! Proper use of specific selector.

Using useSearchStore((state) => state.cachedDataset) follows the learned pattern of using specific selectors to prevent unnecessary re-renders.


50-51: LGTM! Dataset parameter correctly added to URL.

The dataset parameter is properly encoded and appended to the query string, maintaining consistency with existing URL parameters.

components/webui/server/src/fastify-v2/routes/api/search/index.ts (2)

63-63: LGTM! Dataset parameter correctly destructured from request body.

The dataset field is properly extracted alongside other search parameters following the established pattern.


73-73: LGTM! Dataset parameter correctly included in job arguments.

The dataset is properly added to the args object that will be passed to the search and aggregation job submission functions.

components/webui/client/src/ui/QueryStatus.tsx (1)

68-79: LGTM! Improved API usage with named parameters.

The refactoring from positional arguments to a single object with named properties improves code readability and maintainability. The addition of the dataset parameter correctly integrates with the broader dataset awareness functionality introduced in this PR.

components/webui/client/src/pages/SearchPage/SearchControls/index.tsx (2)

1-5: LGTM! Well-structured imports and component integration.

The new imports for storage engine configuration and the Dataset component are properly organized and support the conditional rendering logic.


30-30: LGTM! Appropriate conditional rendering.

The conditional rendering of the Dataset component based on the storage engine type ensures the dataset selector is only shown when using CLP_S, which aligns with the PR objectives for exposing dataset functionality.

components/webui/client/src/pages/SearchPage/SearchControls/Dataset/sql.ts (4)

7-7: LGTM! Good use of constants for table names.

Using a constant for the table name prevents typos and makes the code more maintainable.


13-15: LGTM! Proper enum usage for column names.

The enum provides type safety and prevents magic strings while maintaining clarity about the table structure.


20-25: LGTM! Clean and well-structured SQL query.

The query is properly formatted, uses the defined constants, and includes sensible ordering by name for better user experience.


36-39: LGTM! Robust async function implementation.

The function properly uses the typed querySql API and correctly extracts the dataset names from the response. The return type is appropriately defined as Promise<string[]>.

components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/index.tsx (2)

26-36: LGTM! Excellent refactoring to use specific selectors.

The change from destructuring the entire state to using individual selectors follows the established learning from previous PRs and will prevent unnecessary re-renders as the state store grows in complexity.


76-76: LGTM! Correct dataset parameter integration.

The dataset parameter is properly included in the query submission, with appropriate fallback to an empty string when no dataset is selected.

components/webui/server/src/plugins/DbManager.ts (2)

101-101: LGTM! Proper method signature and documentation updates.

The addition of the dataset parameter to the method signature and documentation correctly reflects the new functionality for dataset-aware extract stream jobs.

Also applies to: 109-109, 115-115


131-131: LGTM! Correct conditional dataset integration.

The dataset is appropriately added to the jobConfig only for EXTRACT_JSON job types, which aligns with the conditional logic and maintains backwards compatibility for other job types.

components/webui/client/src/pages/SearchPage/SearchControls/Dataset/index.tsx (1)

21-96: Component implementation looks good overall.

The component follows React best practices with proper use of React Query, Zustand state management, and Ant Design components. The error handling, loading states, and side effects are well managed.

components/webui/client/src/pages/SearchPage/SearchControls/SearchButton/SubmitButton/index.tsx (3)

25-94: Component follows good React patterns and state management practices.

The component correctly uses specific Zustand selectors as recommended in the learnings, implements proper validation logic for dataset selection, and handles disabled states appropriately. The useCallback optimization is well applied.


69-70: Apply coding guidelines for boolean conditions.

The null check and boolean expression should follow the coding guidelines format.

-    const isNoDatasetsAndClpS = (null === selectDataset) &&
-                          (CLP_STORAGE_ENGINES.CLP_S === SETTINGS_STORAGE_ENGINE);
+    const isNoDatasetsAndClpS = (false == (null !== selectDataset)) &&
+                          (CLP_STORAGE_ENGINES.CLP_S === SETTINGS_STORAGE_ENGINE);
⛔ Skipped due to learnings
Learnt from: junhaoliao
PR: y-scope/clp#988
File: components/log-viewer-webui/client/src/components/QueryBox/InputWithCaseSensitive/CaseSenstiveToggle.tsx:34-37
Timestamp: 2025-06-09T17:48:56.024Z
Learning: In the y-scope/clp project, prefer `false == <expression>` rather than `!<expression>` for boolean expressions in TypeScript/JavaScript files, as specified in the coding guidelines.
Learnt from: LinZhihao-723
PR: y-scope/clp#882
File: components/core/src/clp/ffi/ir_stream/search/QueryHandlerImpl.cpp:378-402
Timestamp: 2025-05-07T16:56:35.687Z
Learning: In the CLP search component, the `evaluate_wildcard_filter` function should return `AstEvaluationResult::Pruned` when `node_id_value_pairs` is empty, not `AstEvaluationResult::False`. Empty node sets should be treated as "undetermined" rather than definitive non-matches.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#868
File: components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py:141-144
Timestamp: 2025-05-05T16:32:55.163Z
Learning: The column metadata table (created by `_create_column_metadata_table`) is only needed for dataset-specific workflows in `CLP_S` and is obsolete for non-dataset workflows.

41-49: Apply coding guidelines for boolean comparisons.

According to the coding guidelines, prefer false == <expression> rather than !<expression>. The null check should be written more explicitly.

-        if (CLP_STORAGE_ENGINES.CLP_S === SETTINGS_STORAGE_ENGINE) {
-            if (null !== selectDataset) {
-                updateCachedDataset(selectDataset);
-            } else {
-                console.error("Cannot submit a clp-s query without a dataset selection.");
-
-                return;
-            }
-        }
+        if (CLP_STORAGE_ENGINES.CLP_S === SETTINGS_STORAGE_ENGINE) {
+            if (false == (null === selectDataset)) {
+                updateCachedDataset(selectDataset);
+            } else {
+                console.error("Cannot submit a clp-s query without a dataset selection.");
+
+                return;
+            }
+        }
⛔ Skipped due to learnings
Learnt from: junhaoliao
PR: y-scope/clp#988
File: components/log-viewer-webui/client/src/components/QueryBox/InputWithCaseSensitive/CaseSenstiveToggle.tsx:34-37
Timestamp: 2025-06-09T17:48:56.024Z
Learning: In the y-scope/clp project, prefer `false == <expression>` rather than `!<expression>` for boolean expressions in TypeScript/JavaScript files, as specified in the coding guidelines.
Learnt from: junhaoliao
PR: y-scope/clp#962
File: components/log-viewer-webui/client/src/pages/SearchPage/SearchQueryStatus/Results.tsx:22-26
Timestamp: 2025-06-09T17:15:30.309Z
Learning: When using Zustand stores in React components, always use specific selectors (e.g., `useStore(state => state.property)`) instead of destructuring the entire state object to prevent unnecessary re-renders. This is especially important as state stores grow in complexity.
Learnt from: junhaoliao
PR: y-scope/clp#962
File: components/log-viewer-webui/client/src/pages/SearchPage/SearchQueryStatus/Results.tsx:22-26
Timestamp: 2025-06-09T17:15:30.309Z
Learning: When using Zustand stores in React components, always use specific selectors (e.g., `useStore(state => state.property)`) instead of destructuring the entire state object to prevent unnecessary re-renders. This is especially important as state stores grow in complexity.
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In `components/log-viewer-webui/client/src/api/query.js`, the `ExtractJsonResp` type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.
Learnt from: junhaoliao
PR: y-scope/clp#937
File: components/log-viewer-webui/client/src/AntdApp.tsx:16-24
Timestamp: 2025-05-29T20:33:40.653Z
Learning: In components/log-viewer-webui React codebase: Return type annotations (like `: JSX.Element`) are unnecessary and not preferred for React components in JSX/TSX files.
Learnt from: LinZhihao-723
PR: y-scope/clp#882
File: components/core/src/clp/ffi/ir_stream/search/QueryHandlerImpl.cpp:378-402
Timestamp: 2025-05-07T16:56:35.687Z
Learning: In the CLP search component, the `evaluate_wildcard_filter` function should return `AstEvaluationResult::Pruned` when `node_id_value_pairs` is empty, not `AstEvaluationResult::False`. Empty node sets should be treated as "undetermined" rather than definitive non-matches.
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:35-41
Timestamp: 2024-11-19T19:52:43.429Z
Learning: For internal APIs in `components/log-viewer-webui/client/src/api/query.js`, runtime validation of parameters may not be necessary since the APIs are not exposed to end users, and JsDoc type annotations may be sufficient.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1036
File: components/clp-package-utils/clp_package_utils/general.py:564-579
Timestamp: 2025-06-28T07:10:47.237Z
Learning: The validate_dataset function in components/clp-package-utils/clp_package_utils/general.py is designed to be called once upon function startup for dataset validation, not repeatedly during execution, making caching optimizations unnecessary.
components/webui/client/src/api/query.ts (1)

32-49: Function refactoring to object parameter is well implemented.

The change from multiple parameters to a single object parameter improves readability and maintainability. The destructuring in the function signature and the inclusion of the dataset parameter in the request payload are correctly implemented.

components/webui/client/src/pages/SearchPage/SearchState/index.tsx (2)

38-44: Good separation of dataset state concerns.

The distinction between cachedDataset (for submitted queries/extract jobs) and selectDataset (for UI selector) is a well-designed pattern that prevents UI state changes from affecting ongoing operations.


111-149: Zustand store implementation follows best practices.

The state management implementation correctly spreads the default state, provides consistent update function naming, and maintains proper immutability patterns. The TypeScript typing ensures type safety throughout the store usage.

"zustand": "^5.0.3"
},
"devDependencies": {
"@tanstack/react-query": "^5.81.5",
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Move @tanstack/react-query to dependencies.

React Query is used in production code for state management and data fetching, so it should be in dependencies rather than devDependencies. The devtools package correctly belongs in devDependencies.

Apply this diff to fix the dependency placement:

  "dependencies": {
    "@ant-design/v5-patch-for-react-19": "^1.0.3",
    "@emotion/react": "^11.14.0",
    "@emotion/styled": "^11.14.0",
    "@mui/joy": "^5.0.0-beta.51",
    "@sinclair/typebox": "^0.34.25",
+   "@tanstack/react-query": "^5.81.5",
    "antd": "^5.24.5",
    "axios": "^1.7.9",
    "chart.js": "^4.4.9",
    "chartjs-adapter-dayjs-4": "^1.0.4",
    "chartjs-plugin-zoom": "^2.2.0",
    "dayjs": "^1.11.13",
    "react": "^19.0.0",
    "react-chartjs-2": "^5.3.0",
    "react-dom": "^19.0.0",
    "react-router": "^7.4.1",
    "react-syntax-highlighter": "^15.6.1",
    "socket.io-client": "^4.8.1",
    "zustand": "^5.0.3"
  },
  "devDependencies": {
-   "@tanstack/react-query": "^5.81.5",
    "@tanstack/react-query-devtools": "^5.81.5",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"@tanstack/react-query": "^5.81.5",
"dependencies": {
"@ant-design/v5-patch-for-react-19": "^1.0.3",
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.0",
"@mui/joy": "^5.0.0-beta.51",
"@sinclair/typebox": "^0.34.25",
+ "@tanstack/react-query": "^5.81.5",
"antd": "^5.24.5",
"axios": "^1.7.9",
"chart.js": "^4.4.9",
"chartjs-adapter-dayjs-4": "^1.0.4",
"chartjs-plugin-zoom": "^2.2.0",
"dayjs": "^1.11.13",
"react": "^19.0.0",
"react-chartjs-2": "^5.3.0",
"react-dom": "^19.0.0",
"react-router": "^7.4.1",
"react-syntax-highlighter": "^15.6.1",
"socket.io-client": "^4.8.1",
"zustand": "^5.0.3"
},
"devDependencies": {
- "@tanstack/react-query": "^5.81.5",
"@tanstack/react-query-devtools": "^5.81.5"
}
🤖 Prompt for AI Agents
In components/webui/client/package.json at line 36, move the
"@tanstack/react-query" package from devDependencies to dependencies because it
is used in production code for state management and data fetching. Keep the
devtools package in devDependencies as it is only for development use.

Comment on lines +4 to +12
/**
* Query the SQL server with the queryString.
*
* @param queryString
* @return
*/
const querySql = async <T>(queryString: string) => {
return axios.post<T>("/query/sql", {queryString});
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Improve JSDoc documentation.

The function implementation is solid, but the JSDoc documentation could be more descriptive about the return type and error handling.

Apply this diff to enhance the documentation:

 /**
  * Query the SQL server with the queryString.
  *
- * @param queryString
- * @return
+ * @param queryString The SQL query string to execute
+ * @return Promise that resolves to an Axios response with typed data
+ * @throws Network errors, server errors, or invalid SQL queries
  */
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/**
* Query the SQL server with the queryString.
*
* @param queryString
* @return
*/
const querySql = async <T>(queryString: string) => {
return axios.post<T>("/query/sql", {queryString});
};
/**
* Query the SQL server with the queryString.
*
* @param queryString The SQL query string to execute
* @return Promise that resolves to an Axios response with typed data
* @throws Network errors, server errors, or invalid SQL queries
*/
const querySql = async <T>(queryString: string) => {
return axios.post<T>("/query/sql", {queryString});
};
🤖 Prompt for AI Agents
In components/webui/client/src/api/sql.ts around lines 4 to 12, the JSDoc for
the querySql function lacks detail on the return type and error handling. Update
the JSDoc to specify that the function returns a Promise resolving to the
response data of type T and mention that it may throw an error if the request
fails. This will improve clarity for users of the function.

Comment on lines +65 to +73
if (CLP_STORAGE_ENGINES.CLP_S === SETTINGS_STORAGE_ENGINE) {
if (null !== selectDataset) {
updateCachedDataset(selectDataset);
} else {
console.error("Cannot submit a clp-s query without a dataset selection.");

return;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

LGTM! Proper dataset validation for CLP_S storage engine.

The conditional validation ensures that queries cannot be submitted without a dataset selection when using the CLP_S storage engine. The error logging provides clear feedback for debugging purposes.

Consider following the coding guideline by using false === <expression> instead of !<expression>:

-            if (null !== selectDataset) {
+            if (false === (null === selectDataset)) {

However, the current form is more readable, so this is a minor stylistic preference.

🤖 Prompt for AI Agents
In
components/webui/client/src/pages/SearchPage/SearchResults/SearchResultsTimeline/index.tsx
around lines 65 to 73, the condition checking if selectDataset is not null
currently uses "null !== selectDataset". To align with the coding guideline,
change this to "false === (selectDataset === null)" or an equivalent explicit
comparison instead of using negation. This is a stylistic change to improve
consistency with the codebase's preferred style.

Comment on lines +38 to +42
if (isSuccess) {
if ("undefined" !== typeof data[0] && null === dataset) {
updateDataset(data[0]);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Consider using standard undefined check instead of typeof comparison.

The condition "undefined" !== typeof data[0] is unnecessarily verbose. Use the more conventional data[0] !== undefined for better readability.

-        if (isSuccess) {
-            if ("undefined" !== typeof data[0] && null === dataset) {
-                updateDataset(data[0]);
-            }
-        }
+        if (isSuccess) {
+            if (data[0] !== undefined && null === dataset) {
+                updateDataset(data[0]);
+            }
+        }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (isSuccess) {
if ("undefined" !== typeof data[0] && null === dataset) {
updateDataset(data[0]);
}
}
if (isSuccess) {
if (data[0] !== undefined && null === dataset) {
updateDataset(data[0]);
}
}
🤖 Prompt for AI Agents
In components/webui/client/src/pages/SearchPage/SearchControls/Dataset/index.tsx
around lines 38 to 42, replace the condition checking if data[0] is defined from
using the verbose typeof comparison ("undefined" !== typeof data[0]) to the
simpler and more readable standard undefined check (data[0] !== undefined).

{contextHolder}
<DatasetLabel/>
<Select
className={styles["select"] || ""}
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Remove redundant fallback in className assignment.

The || "" fallback is unnecessary since styles["select"] will be undefined if the CSS module doesn't have the class, and React handles undefined className gracefully.

-                className={styles["select"] || ""}
+                className={styles["select"]}
🤖 Prompt for AI Agents
In components/webui/client/src/pages/SearchPage/SearchControls/Dataset/index.tsx
at line 86, remove the redundant fallback `|| ""` from the className assignment.
Change `className={styles["select"] || ""}` to just
`className={styles["select"]}` since React handles undefined className values
without issues.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🔭 Outside diff range comments (1)
components/clp-package-utils/clp_package_utils/scripts/native/archive_manager.py (1)

268-268: Potential SQL injection risk with unvalidated dataset parameter.

The dataset parameter is directly concatenated into the table prefix without validation, which could pose a security risk if the dataset contains malicious characters.

While the dataset should be validated before reaching this point (see previous comment), add an additional safety check:

        if StorageEngine.CLP_S == storage_engine:
+            if dataset is None:
+                logger.error("Dataset is required for CLP_S storage engine.")
+                return -1
            table_prefix = f"{table_prefix}{dataset}_"

Also applies to: 339-339

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 869b02d and 74c2cd2.

📒 Files selected for processing (12)
  • components/clp-package-utils/clp_package_utils/general.py (2 hunks)
  • components/clp-package-utils/clp_package_utils/scripts/archive_manager.py (3 hunks)
  • components/clp-package-utils/clp_package_utils/scripts/compress.py (6 hunks)
  • components/clp-package-utils/clp_package_utils/scripts/decompress.py (4 hunks)
  • components/clp-package-utils/clp_package_utils/scripts/native/archive_manager.py (8 hunks)
  • components/clp-package-utils/clp_package_utils/scripts/native/compress.py (3 hunks)
  • components/clp-package-utils/clp_package_utils/scripts/native/decompress.py (2 hunks)
  • components/clp-package-utils/clp_package_utils/scripts/native/search.py (9 hunks)
  • components/clp-package-utils/clp_package_utils/scripts/search.py (4 hunks)
  • components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py (2 hunks)
  • components/job-orchestration/job_orchestration/scheduler/job_config.py (3 hunks)
  • components/job-orchestration/job_orchestration/scheduler/query/query_scheduler.py (2 hunks)
🧰 Additional context used
🧠 Learnings (12)
components/clp-package-utils/clp_package_utils/scripts/archive_manager.py (3)
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1036
File: components/clp-package-utils/clp_package_utils/general.py:564-579
Timestamp: 2025-06-28T07:10:47.237Z
Learning: The validate_dataset function in components/clp-package-utils/clp_package_utils/general.py is designed to be called once upon function startup for dataset validation, not repeatedly during execution, making caching optimizations unnecessary.
Learnt from: haiqi96
PR: y-scope/clp#594
File: components/clp-package-utils/clp_package_utils/scripts/native/del_archives.py:104-110
Timestamp: 2024-11-15T16:21:52.122Z
Learning: In `clp_package_utils/scripts/native/del_archives.py`, when deleting archives, the `archive` variable retrieved from the database is controlled and is always a single string without path components. Therefore, it's acceptable to skip additional validation checks for directory traversal in this context.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1004
File: components/clp-package-utils/clp_package_utils/scripts/native/decompress.py:139-144
Timestamp: 2025-06-24T08:54:14.438Z
Learning: In the CLP codebase, the get_orig_file_id function signature was changed after a recent merge to no longer accept a dataset parameter, making previous suggestions that reference this parameter invalid.
components/clp-package-utils/clp_package_utils/scripts/search.py (2)
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1036
File: components/clp-package-utils/clp_package_utils/general.py:564-579
Timestamp: 2025-06-28T07:10:47.237Z
Learning: The validate_dataset function in components/clp-package-utils/clp_package_utils/general.py is designed to be called once upon function startup for dataset validation, not repeatedly during execution, making caching optimizations unnecessary.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1004
File: components/clp-package-utils/clp_package_utils/scripts/native/decompress.py:139-144
Timestamp: 2025-06-24T08:54:14.438Z
Learning: In the CLP codebase, the get_orig_file_id function signature was changed after a recent merge to no longer accept a dataset parameter, making previous suggestions that reference this parameter invalid.
components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py (2)
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1036
File: components/clp-package-utils/clp_package_utils/general.py:564-579
Timestamp: 2025-06-28T07:10:47.237Z
Learning: The validate_dataset function in components/clp-package-utils/clp_package_utils/general.py is designed to be called once upon function startup for dataset validation, not repeatedly during execution, making caching optimizations unnecessary.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#868
File: components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py:141-144
Timestamp: 2025-05-05T16:32:55.163Z
Learning: The column metadata table (created by `_create_column_metadata_table`) is only needed for dataset-specific workflows in `CLP_S` and is obsolete for non-dataset workflows.
components/clp-package-utils/clp_package_utils/scripts/native/compress.py (2)
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1004
File: components/clp-package-utils/clp_package_utils/scripts/native/decompress.py:139-144
Timestamp: 2025-06-24T08:54:14.438Z
Learning: In the CLP codebase, the get_orig_file_id function signature was changed after a recent merge to no longer accept a dataset parameter, making previous suggestions that reference this parameter invalid.
Learnt from: haiqi96
PR: y-scope/clp#651
File: components/clp-package-utils/clp_package_utils/scripts/compress.py:0-0
Timestamp: 2025-01-16T16:58:43.190Z
Learning: In the clp-package compression flow, path validation and error handling is performed at the scheduler level rather than in the compress.py script to maintain simplicity and avoid code duplication.
components/clp-package-utils/clp_package_utils/general.py (3)
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1036
File: components/clp-package-utils/clp_package_utils/general.py:564-579
Timestamp: 2025-06-28T07:10:47.237Z
Learning: The validate_dataset function in components/clp-package-utils/clp_package_utils/general.py is designed to be called once upon function startup for dataset validation, not repeatedly during execution, making caching optimizations unnecessary.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1004
File: components/clp-package-utils/clp_package_utils/scripts/native/decompress.py:139-144
Timestamp: 2025-06-24T08:54:14.438Z
Learning: In the CLP codebase, the get_orig_file_id function signature was changed after a recent merge to no longer accept a dataset parameter, making previous suggestions that reference this parameter invalid.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#868
File: components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py:141-144
Timestamp: 2025-05-05T16:32:55.163Z
Learning: The column metadata table (created by `_create_column_metadata_table`) is only needed for dataset-specific workflows in `CLP_S` and is obsolete for non-dataset workflows.
components/job-orchestration/job_orchestration/scheduler/job_config.py (2)
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1004
File: components/clp-package-utils/clp_package_utils/scripts/native/decompress.py:139-144
Timestamp: 2025-06-24T08:54:14.438Z
Learning: In the CLP codebase, the get_orig_file_id function signature was changed after a recent merge to no longer accept a dataset parameter, making previous suggestions that reference this parameter invalid.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#868
File: components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py:141-144
Timestamp: 2025-05-05T16:32:55.163Z
Learning: The column metadata table (created by `_create_column_metadata_table`) is only needed for dataset-specific workflows in `CLP_S` and is obsolete for non-dataset workflows.
components/job-orchestration/job_orchestration/scheduler/query/query_scheduler.py (3)
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1036
File: components/clp-package-utils/clp_package_utils/general.py:564-579
Timestamp: 2025-06-28T07:10:47.237Z
Learning: The validate_dataset function in components/clp-package-utils/clp_package_utils/general.py is designed to be called once upon function startup for dataset validation, not repeatedly during execution, making caching optimizations unnecessary.
Learnt from: haiqi96
PR: y-scope/clp#569
File: components/job-orchestration/job_orchestration/scheduler/query/query_scheduler.py:380-392
Timestamp: 2024-11-15T20:07:22.256Z
Learning: The current implementation assumes single-threaded execution, so race conditions in functions like `is_target_extracted` in `components/job-orchestration/job_orchestration/scheduler/query/query_scheduler.py` are not currently a concern.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#868
File: components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py:141-144
Timestamp: 2025-05-05T16:32:55.163Z
Learning: The column metadata table (created by `_create_column_metadata_table`) is only needed for dataset-specific workflows in `CLP_S` and is obsolete for non-dataset workflows.
components/clp-package-utils/clp_package_utils/scripts/decompress.py (5)
Learnt from: haiqi96
PR: y-scope/clp#651
File: components/clp-package-utils/clp_package_utils/scripts/compress.py:0-0
Timestamp: 2025-01-16T16:58:43.190Z
Learning: In the clp-package compression flow, path validation and error handling is performed at the scheduler level rather than in the compress.py script to maintain simplicity and avoid code duplication.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1004
File: components/clp-package-utils/clp_package_utils/scripts/native/decompress.py:139-144
Timestamp: 2025-06-24T08:54:14.438Z
Learning: In the CLP codebase, the get_orig_file_id function signature was changed after a recent merge to no longer accept a dataset parameter, making previous suggestions that reference this parameter invalid.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1036
File: components/clp-package-utils/clp_package_utils/general.py:564-579
Timestamp: 2025-06-28T07:10:47.237Z
Learning: The validate_dataset function in components/clp-package-utils/clp_package_utils/general.py is designed to be called once upon function startup for dataset validation, not repeatedly during execution, making caching optimizations unnecessary.
Learnt from: haiqi96
PR: y-scope/clp#594
File: components/clp-package-utils/clp_package_utils/scripts/native/del_archives.py:104-110
Timestamp: 2024-11-15T16:21:52.122Z
Learning: In `clp_package_utils/scripts/native/del_archives.py`, when deleting archives, the `archive` variable retrieved from the database is controlled and is always a single string without path components. Therefore, it's acceptable to skip additional validation checks for directory traversal in this context.
Learnt from: haiqi96
PR: y-scope/clp#594
File: components/clp-package-utils/clp_package_utils/scripts/del_archives.py:56-65
Timestamp: 2024-11-18T16:49:20.248Z
Learning: When reviewing wrapper scripts in `components/clp-package-utils/clp_package_utils/scripts/`, note that it's preferred to keep error handling simple without adding extra complexity.
components/clp-package-utils/clp_package_utils/scripts/native/decompress.py (1)
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1004
File: components/clp-package-utils/clp_package_utils/scripts/native/decompress.py:139-144
Timestamp: 2025-06-24T08:54:14.438Z
Learning: In the CLP codebase, the get_orig_file_id function signature was changed after a recent merge to no longer accept a dataset parameter, making previous suggestions that reference this parameter invalid.
components/clp-package-utils/clp_package_utils/scripts/compress.py (3)
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1004
File: components/clp-package-utils/clp_package_utils/scripts/native/decompress.py:139-144
Timestamp: 2025-06-24T08:54:14.438Z
Learning: In the CLP codebase, the get_orig_file_id function signature was changed after a recent merge to no longer accept a dataset parameter, making previous suggestions that reference this parameter invalid.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1036
File: components/clp-package-utils/clp_package_utils/general.py:564-579
Timestamp: 2025-06-28T07:10:47.237Z
Learning: The validate_dataset function in components/clp-package-utils/clp_package_utils/general.py is designed to be called once upon function startup for dataset validation, not repeatedly during execution, making caching optimizations unnecessary.
Learnt from: haiqi96
PR: y-scope/clp#651
File: components/clp-package-utils/clp_package_utils/scripts/compress.py:0-0
Timestamp: 2025-01-16T16:58:43.190Z
Learning: In the clp-package compression flow, path validation and error handling is performed at the scheduler level rather than in the compress.py script to maintain simplicity and avoid code duplication.
components/clp-package-utils/clp_package_utils/scripts/native/archive_manager.py (5)
Learnt from: haiqi96
PR: y-scope/clp#594
File: components/clp-package-utils/clp_package_utils/scripts/native/del_archives.py:104-110
Timestamp: 2024-11-15T16:21:52.122Z
Learning: In `clp_package_utils/scripts/native/del_archives.py`, when deleting archives, the `archive` variable retrieved from the database is controlled and is always a single string without path components. Therefore, it's acceptable to skip additional validation checks for directory traversal in this context.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1004
File: components/clp-package-utils/clp_package_utils/scripts/native/decompress.py:139-144
Timestamp: 2025-06-24T08:54:14.438Z
Learning: In the CLP codebase, the get_orig_file_id function signature was changed after a recent merge to no longer accept a dataset parameter, making previous suggestions that reference this parameter invalid.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1036
File: components/clp-package-utils/clp_package_utils/general.py:564-579
Timestamp: 2025-06-28T07:10:47.237Z
Learning: The validate_dataset function in components/clp-package-utils/clp_package_utils/general.py is designed to be called once upon function startup for dataset validation, not repeatedly during execution, making caching optimizations unnecessary.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#868
File: components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py:141-144
Timestamp: 2025-05-05T16:32:55.163Z
Learning: The column metadata table (created by `_create_column_metadata_table`) is only needed for dataset-specific workflows in `CLP_S` and is obsolete for non-dataset workflows.
Learnt from: haiqi96
PR: y-scope/clp#594
File: components/clp-package-utils/clp_package_utils/scripts/native/del_archives.py:90-96
Timestamp: 2024-11-15T16:22:33.635Z
Learning: In the CLP codebase, `table_prefix` is a trusted configuration value and can be safely embedded into SQL queries.
components/clp-package-utils/clp_package_utils/scripts/native/search.py (1)
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1004
File: components/clp-package-utils/clp_package_utils/scripts/native/decompress.py:139-144
Timestamp: 2025-06-24T08:54:14.438Z
Learning: In the CLP codebase, the get_orig_file_id function signature was changed after a recent merge to no longer accept a dataset parameter, making previous suggestions that reference this parameter invalid.
🧬 Code Graph Analysis (4)
components/clp-package-utils/clp_package_utils/scripts/archive_manager.py (1)
components/clp-package-utils/clp_package_utils/general.py (1)
  • validate_dataset (567-592)
components/clp-package-utils/clp_package_utils/scripts/search.py (1)
components/clp-package-utils/clp_package_utils/general.py (1)
  • validate_dataset (567-592)
components/job-orchestration/job_orchestration/scheduler/query/query_scheduler.py (3)
components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py (1)
  • validate_and_cache_dataset (160-179)
components/job-orchestration/job_orchestration/scheduler/job_config.py (1)
  • QueryJobConfig (59-60)
components/clp-py-utils/clp_py_utils/clp_config.py (1)
  • StorageEngine (54-56)
components/clp-package-utils/clp_package_utils/scripts/compress.py (1)
components/clp-package-utils/clp_package_utils/general.py (1)
  • validate_dataset (567-592)
🪛 Flake8 (7.2.0)
components/clp-package-utils/clp_package_utils/scripts/archive_manager.py

[error] 168-168: local variable 'dataset' is assigned to but never used

(F841)

components/clp-package-utils/clp_package_utils/scripts/decompress.py

[error] 220-220: undefined name 'validate_dataset'

(F821)

components/clp-package-utils/clp_package_utils/scripts/compress.py

[error] 67-67: undefined name 'Optional'

(F821)

🪛 Pylint (3.3.7)
components/clp-package-utils/clp_package_utils/scripts/archive_manager.py

[warning] 168-168: Unused variable 'dataset'

(W0612)

components/clp-package-utils/clp_package_utils/general.py

[error] 15-29: Unable to import 'clp_py_utils.clp_config'

(E0401)


[error] 30-30: Unable to import 'clp_py_utils.clp_metadata_db_utils'

(E0401)


[error] 31-36: Unable to import 'clp_py_utils.core'

(E0401)


[error] 37-37: Unable to import 'clp_py_utils.sql_adapter'

(E0401)

components/job-orchestration/job_orchestration/scheduler/job_config.py

[error] 6-6: Unable to import 'clp_py_utils.clp_config'

(E0401)


[convention] 31-31: Missing class docstring

(C0115)


[refactor] 31-31: Too few public methods (0/2)

(R0903)

components/job-orchestration/job_orchestration/scheduler/query/query_scheduler.py

[error] 44-44: Unable to import 'clp_py_utils.clp_metadata_db_utils'

(E0401)

components/clp-package-utils/clp_package_utils/scripts/decompress.py

[error] 8-13: Unable to import 'clp_py_utils.clp_config'

(E0401)


[warning] 178-181: Use lazy % formatting in logging functions

(W1203)


[warning] 185-185: Use lazy % formatting in logging functions

(W1203)


[error] 220-220: Undefined variable 'validate_dataset'

(E0602)

components/clp-package-utils/clp_package_utils/scripts/compress.py

[error] 67-67: Undefined variable 'Optional'

(E0602)

🔇 Additional comments (27)
components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py (2)

4-4: LGTM: Enhanced typing imports

Good addition of Set and Tuple for the new caching function.


160-180: Excellent caching optimization for dataset validation

This function provides an efficient approach to dataset validation by implementing caching to avoid redundant database queries. The implementation correctly:

  • Checks the cache first before hitting the database
  • Returns both validation status and updated cache for subsequent calls
  • Follows consistent error handling patterns
  • Uses proper type hints

This optimization will improve performance when multiple dataset validations are needed.

components/clp-package-utils/clp_package_utils/scripts/archive_manager.py (1)

65-70: LGTM: Dataset argument addition

The dataset argument is properly defined with appropriate help text.

components/clp-package-utils/clp_package_utils/scripts/search.py (3)

39-44: LGTM: Dataset argument properly defined

The dataset argument follows the established pattern with appropriate type and help text.


88-88: LGTM: Proper dataset validation

The dataset validation correctly uses the imported validate_dataset function to ensure dataset existence.


119-121: LGTM: Conditional dataset passing

The dataset is correctly passed to the command only when not None, maintaining backwards compatibility.

components/clp-package-utils/clp_package_utils/general.py (2)

10-10: LGTM: Required imports for dataset validation

All necessary imports are correctly added to support the new dataset validation functionality.

Also applies to: 17-17, 19-19, 25-25, 30-30, 37-37


567-592: Well-implemented dataset validation function

This function provides comprehensive dataset validation with excellent design:

  • Storage engine compatibility: Correctly restricts dataset selection to CLP_S engine only
  • Default handling: Uses CLP_DEFAULT_DATASET_NAME when no dataset is specified
  • Resource management: Proper use of closing() context managers for database connections
  • Error handling: Clear error messages for non-existent datasets and incompatible storage engines
  • Integration: Leverages the new validate_and_cache_dataset function for optimized validation

The function centralizes dataset validation logic and will be used consistently across CLI scripts.

components/clp-package-utils/clp_package_utils/scripts/native/compress.py (2)

195-200: LGTM: Dataset argument addition

The dataset argument is properly defined following the established pattern.


143-143: LGTM: Dataset integration in input configs

The dataset is correctly added to both FsInputConfig and S3InputConfig objects, enabling dataset-aware compression jobs.

Note: This script doesn't perform dataset validation, which is appropriate since validation likely occurs at the job orchestration level to avoid duplication.

Also applies to: 158-158

components/clp-package-utils/clp_package_utils/scripts/native/decompress.py (1)

142-142: LGTM! Dataset parameter correctly passed from CLI.

The change properly uses the dataset from command line arguments instead of a hardcoded default, aligning with the broader dataset awareness implementation.

components/job-orchestration/job_orchestration/scheduler/job_config.py (1)

6-6: LGTM! Dataset fields properly converted to optional.

The changes correctly remove the default dataset import and make dataset fields explicitly optional. This forces explicit dataset specification rather than relying on implicit defaults, which aligns with the PR objectives.

Also applies to: 25-25, 33-33, 60-60

components/job-orchestration/job_orchestration/scheduler/query/query_scheduler.py (2)

44-44: LGTM! Import updated to use caching validation function.

The change from fetch_existing_datasets to validate_and_cache_dataset improves efficiency by caching dataset validation results.


645-663: LGTM! Dataset validation logic correctly implemented.

The validation logic properly:

  • Checks if dataset is not None before validation
  • Uses the new caching validation function
  • Updates the table prefix with dataset name
  • Handles validation failures by marking jobs as failed

The implementation is consistent with the dataset awareness objectives.

components/clp-package-utils/clp_package_utils/scripts/decompress.py (3)

184-186: LGTM! Proper validation for JSON extraction storage engine.

The validation correctly ensures JSON extraction is only allowed with CLP_S storage engine, which aligns with the system requirements.


220-222: Dataset validation logic is correct but missing import.

The validation logic is correct, but validate_dataset is not imported (see import comment above).


283-288: LGTM! Dataset argument properly added to JSON extraction parser.

The argument definition correctly provides dataset specification for JSON extraction with an appropriate default value and help text.

components/clp-package-utils/clp_package_utils/scripts/compress.py (4)

23-23: LGTM! validate_dataset import properly added.

The import correctly includes the validation function needed for dataset validation.


79-81: LGTM! Dataset argument correctly added to compression command.

The conditional logic properly appends the dataset argument only when a dataset is provided.


139-144: LGTM! Dataset CLI argument properly defined.

The argument definition provides appropriate dataset specification with correct type and help text.


176-176: LGTM! Dataset validation and usage correctly implemented.

The dataset validation and passing to the compression command generator are properly implemented according to the new dataset awareness pattern.

Also applies to: 214-214

components/clp-package-utils/clp_package_utils/scripts/native/archive_manager.py (3)

99-104: LGTM! Dataset CLI argument properly configured.

The --dataset argument is correctly added with appropriate type and help text.


293-295: Path construction logic is correct and consistent.

The conditional path construction properly handles both dataset-specific and default scenarios.

Also applies to: 398-398


204-204: Incorrect suggestion: dataset is already validated in archive_manager.py

The validate_dataset call is present in archive_manager.py:

    dataset = validate_dataset(clp_config, parsed_args.dataset)

Subsequent logic uses the validated dataset, so adding another validation on parsed_args.dataset isn’t needed.

Likely an incorrect or invalid review comment.

components/clp-package-utils/clp_package_utils/scripts/native/search.py (3)

35-35: Dataset parameter integration looks correct.

The dataset parameter is properly added to the function signature and correctly passed to SearchJobConfig.

Also applies to: 47-47


118-118: Consistent dataset parameter propagation throughout the call chain.

The dataset parameter is correctly passed through all function calls in the search pipeline.

Also applies to: 153-153, 191-191, 206-206, 220-220


302-302: Dataset parameter correctly passed to search function.

The parsed dataset argument is properly passed to the do_search function.

hoophalab
hoophalab previously approved these changes Jun 30, 2025
Copy link
Contributor

@hoophalab hoophalab left a comment

Choose a reason for hiding this comment

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

webui looks good to me. There are some nitpicks. Someone needs to take a look at the package tools.

} from "../typings/query";


interface submitExtractStreamJobProps {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
interface submitExtractStreamJobProps {
interface SubmitExtractStreamJobProps {

<Text
className={styles["datasetLabel"] || ""}
style={{
backgroundColor: token.colorFillAlter,
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
backgroundColor: token.colorFillAlter,
backgroundColor: token.colorFillTertiary,

how about making the bg darker

Copy link
Contributor

Choose a reason for hiding this comment

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

I think you're right, that matches the selector better. So i made darker

{contextHolder}
<DatasetLabel/>
<Select
className={styles["select"] || ""}
Copy link
Contributor

Choose a reason for hiding this comment

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

Correct me if wrong: do we need || "" when importing from an index.module.css in our project?

Copy link
Contributor

Choose a reason for hiding this comment

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

for now we need it for antd components since it wont take undefined for className. Junhao mentioned that there may be a change to our typescript settings that can avoid this, but for now we need it

Copy link
Contributor

Choose a reason for hiding this comment

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

sounds reasonable to me

if (null !== selectDataset) {
updateCachedDataset(selectDataset);
} else {
console.error("Cannot submit a clp-s query without a dataset selection.");
Copy link
Contributor

Choose a reason for hiding this comment

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

how about using message api to show an error message?

(feel free to push back since this branch cannot happen in normal cases)

Copy link
Contributor

Choose a reason for hiding this comment

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

per your statement this branch cannot happen in normal cases, I don't think we need message api since this branch should be impossible, so user should never see it. I just put the log there for completeness or if a developer breaks something in the future.

Copy link
Contributor

@davemarco davemarco left a comment

Choose a reason for hiding this comment

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

addressed feedback

{contextHolder}
<DatasetLabel/>
<Select
className={styles["select"] || ""}
Copy link
Contributor

Choose a reason for hiding this comment

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

for now we need it for antd components since it wont take undefined for className. Junhao mentioned that there may be a change to our typescript settings that can avoid this, but for now we need it

if (null !== selectDataset) {
updateCachedDataset(selectDataset);
} else {
console.error("Cannot submit a clp-s query without a dataset selection.");
Copy link
Contributor

Choose a reason for hiding this comment

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

per your statement this branch cannot happen in normal cases, I don't think we need message api since this branch should be impossible, so user should never see it. I just put the log there for completeness or if a developer breaks something in the future.

<Text
className={styles["datasetLabel"] || ""}
style={{
backgroundColor: token.colorFillAlter,
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you're right, that matches the selector better. So i made darker

@davemarco davemarco requested a review from hoophalab June 30, 2025 21:20
hoophalab
hoophalab previously approved these changes Jul 1, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
components/webui/server/src/fastify-v2/routes/api/search/index.ts (1)

73-73: Fix ternary expression formatting to comply with ESLint rules.

The ternary expression violates the ESLint multiline formatting rule. The logic is correct (converting empty strings to null), but the formatting needs adjustment.

-                dataset: ("" === dataset ? null : dataset),
+                dataset: ("" === dataset
+                    ? null
+                    : dataset),
📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5b48c8d and dde5d54.

📒 Files selected for processing (6)
  • components/clp-package-utils/clp_package_utils/general.py (4 hunks)
  • components/webui/client/src/pages/SearchPage/SearchControls/Dataset/sql.ts (1 hunks)
  • components/webui/client/src/settings.ts (1 hunks)
  • components/webui/server/src/fastify-v2/routes/api/search/index.ts (2 hunks)
  • components/webui/server/src/plugins/DbManager.ts (2 hunks)
  • components/webui/server/src/routes/query.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}`: - Prefer `false == ` rather than `!`.

**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}: - Prefer false == <expression> rather than !<expression>.

⚙️ Source: CodeRabbit Configuration File

List of files the instruction was applied to:

  • components/webui/client/src/settings.ts
  • components/webui/server/src/routes/query.ts
  • components/webui/client/src/pages/SearchPage/SearchControls/Dataset/sql.ts
  • components/webui/server/src/fastify-v2/routes/api/search/index.ts
  • components/webui/server/src/plugins/DbManager.ts
🧠 Learnings (6)
📓 Common learnings
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1050
File: components/clp-package-utils/clp_package_utils/scripts/search.py:100-106
Timestamp: 2025-07-03T20:10:43.761Z
Learning: In the current CLP codebase implementation, dataset validation using validate_dataset() is performed within the native scripts (like clp_package_utils/scripts/native/search.py) rather than at the wrapper script level, where the native scripts handle their own parameter validation.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1050
File: components/clp-package-utils/clp_package_utils/scripts/search.py:100-106
Timestamp: 2025-07-03T20:10:43.761Z
Learning: In the current CLP codebase implementation, dataset validation using validate_dataset() is performed within the native scripts (like clp_package_utils/scripts/native/search.py) rather than at the wrapper script level, where the native scripts handle their own parameter validation.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1036
File: components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py:204-211
Timestamp: 2025-07-03T12:58:18.407Z
Learning: In the CLP codebase, the validate_and_cache_dataset function in components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py uses in-place updates of the existing_datasets set parameter rather than returning a new set, as preferred by the development team.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1004
File: components/clp-package-utils/clp_package_utils/scripts/native/decompress.py:139-144
Timestamp: 2025-06-24T08:54:14.438Z
Learning: In the CLP codebase, the get_orig_file_id function signature was changed after a recent merge to no longer accept a dataset parameter, making previous suggestions that reference this parameter invalid.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1036
File: components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py:188-212
Timestamp: 2025-07-03T12:59:46.638Z
Learning: In CLP schedulers (compression and query), runtime dataset validation is required; the helper validate_and_cache_dataset keeps a local cache and only queries the DB on cache misses because dataset additions are rare.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#868
File: components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py:141-144
Timestamp: 2025-05-05T16:32:55.163Z
Learning: The column metadata table (created by `_create_column_metadata_table`) is only needed for dataset-specific workflows in `CLP_S` and is obsolete for non-dataset workflows.
Learnt from: kirkrodrigues
PR: y-scope/clp#881
File: components/core/tools/scripts/lib_install/ubuntu-jammy/install-prebuilt-packages.sh:35-41
Timestamp: 2025-05-06T09:48:55.408Z
Learning: For installation scripts in the CLP project, prefer explicit error handling over automatic dependency resolution (like `apt-get install -f`) when installing packages to give users more control over their system.
components/webui/server/src/routes/query.ts (1)
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In `components/log-viewer-webui/client/src/api/query.js`, the `ExtractJsonResp` type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.
components/webui/client/src/pages/SearchPage/SearchControls/Dataset/sql.ts (1)
Learnt from: Bill-hbrhbr
PR: y-scope/clp#868
File: components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py:141-144
Timestamp: 2025-05-05T16:32:55.163Z
Learning: The column metadata table (created by `_create_column_metadata_table`) is only needed for dataset-specific workflows in `CLP_S` and is obsolete for non-dataset workflows.
components/webui/server/src/fastify-v2/routes/api/search/index.ts (5)
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1004
File: components/clp-package-utils/clp_package_utils/scripts/native/decompress.py:139-144
Timestamp: 2025-06-24T08:54:14.438Z
Learning: In the CLP codebase, the get_orig_file_id function signature was changed after a recent merge to no longer accept a dataset parameter, making previous suggestions that reference this parameter invalid.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1036
File: components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py:204-211
Timestamp: 2025-07-03T12:58:18.407Z
Learning: In the CLP codebase, the validate_and_cache_dataset function in components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py uses in-place updates of the existing_datasets set parameter rather than returning a new set, as preferred by the development team.
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In `components/log-viewer-webui/client/src/api/query.js`, the `ExtractJsonResp` type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.
Learnt from: junhaoliao
PR: y-scope/clp#988
File: components/log-viewer-webui/client/src/components/QueryBox/InputWithCaseSensitive/CaseSenstiveToggle.tsx:34-37
Timestamp: 2025-06-09T17:48:56.024Z
Learning: In the y-scope/clp project, prefer `false == <expression>` rather than `!<expression>` for boolean expressions in TypeScript/JavaScript files, as specified in the coding guidelines.
Learnt from: LinZhihao-723
PR: y-scope/clp#882
File: components/core/src/clp/ffi/ir_stream/search/QueryHandlerImpl.cpp:378-402
Timestamp: 2025-05-07T16:56:35.687Z
Learning: In the CLP search component, the `evaluate_wildcard_filter` function should return `AstEvaluationResult::Pruned` when `node_id_value_pairs` is empty, not `AstEvaluationResult::False`. Empty node sets should be treated as "undetermined" rather than definitive non-matches.
components/clp-package-utils/clp_package_utils/general.py (14)
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1036
File: components/clp-package-utils/clp_package_utils/general.py:564-579
Timestamp: 2025-06-28T07:10:47.295Z
Learning: The validate_dataset function in components/clp-package-utils/clp_package_utils/general.py is designed to be called once upon function startup for dataset validation, not repeatedly during execution, making caching optimizations unnecessary.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1036
File: components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py:204-211
Timestamp: 2025-07-03T12:58:18.407Z
Learning: In the CLP codebase, the validate_and_cache_dataset function in components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py uses in-place updates of the existing_datasets set parameter rather than returning a new set, as preferred by the development team.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1050
File: components/clp-package-utils/clp_package_utils/scripts/search.py:100-106
Timestamp: 2025-07-03T20:10:43.761Z
Learning: In the current CLP codebase implementation, dataset validation using validate_dataset() is performed within the native scripts (like clp_package_utils/scripts/native/search.py) rather than at the wrapper script level, where the native scripts handle their own parameter validation.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1050
File: components/clp-package-utils/clp_package_utils/scripts/search.py:100-106
Timestamp: 2025-07-03T20:10:43.761Z
Learning: In the current CLP codebase implementation, dataset validation using validate_dataset() is performed within the native scripts (like clp_package_utils/scripts/native/search.py) rather than at the wrapper script level, where the native scripts handle their own parameter validation.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1004
File: components/clp-package-utils/clp_package_utils/scripts/native/decompress.py:139-144
Timestamp: 2025-06-24T08:54:14.438Z
Learning: In the CLP codebase, the get_orig_file_id function signature was changed after a recent merge to no longer accept a dataset parameter, making previous suggestions that reference this parameter invalid.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1036
File: components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py:188-212
Timestamp: 2025-07-03T12:59:46.638Z
Learning: In CLP schedulers (compression and query), runtime dataset validation is required; the helper validate_and_cache_dataset keeps a local cache and only queries the DB on cache misses because dataset additions are rare.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#868
File: components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py:141-144
Timestamp: 2025-05-05T16:32:55.163Z
Learning: The column metadata table (created by `_create_column_metadata_table`) is only needed for dataset-specific workflows in `CLP_S` and is obsolete for non-dataset workflows.
Learnt from: haiqi96
PR: y-scope/clp#594
File: components/clp-package-utils/clp_package_utils/scripts/native/del_archives.py:90-96
Timestamp: 2024-11-15T16:22:33.635Z
Learning: In the CLP codebase, `table_prefix` is a trusted configuration value and can be safely embedded into SQL queries.
Learnt from: gibber9809
PR: y-scope/clp#672
File: components/core/src/clp_s/indexer/MySQLIndexStorage.cpp:30-38
Timestamp: 2025-01-23T17:08:55.566Z
Learning: SQL identifiers (table names, column names) in the codebase are currently from trusted sources and directly interpolated into queries. However, the team prefers to implement sanitization for robustness, even for trusted inputs.
Learnt from: LinZhihao-723
PR: y-scope/clp#873
File: components/core/src/clp/ffi/ir_stream/search/QueryHandlerImpl.hpp:320-324
Timestamp: 2025-05-05T01:12:18.561Z
Learning: In the CLP codebase, the `m_case_sensitive_search` flag is used only for actual string value comparisons during query evaluation, not for schema key name matching. Schema keys are always compared case-sensitively regardless of this flag's setting.
Learnt from: haiqi96
PR: y-scope/clp#620
File: components/core/src/clp/clo/clo.cpp:198-198
Timestamp: 2024-12-02T22:36:17.847Z
Learning: The existing references to `file_split_id` in the codebase are acceptable and do not need to be changed.
Learnt from: quinntaylormitchell
PR: y-scope/clp#961
File: docs/src/dev-guide/design-clp-structured/single-file-archive-format.md:216-219
Timestamp: 2025-06-18T14:35:20.485Z
Learning: In clp-s documentation, technical abbreviations like "MPT" (Merged Parse Tree) should be defined at first use to improve reader clarity and comprehension.
Learnt from: jackluo923
PR: y-scope/clp#1054
File: components/core/src/glt/SQLitePreparedStatement.hpp:4-4
Timestamp: 2025-07-01T14:49:07.333Z
Learning: In the CLP codebase, standard headers like `<cstdint>` and `<string>` in alphabetical order (as seen in components/core/src/glt/SQLitePreparedStatement.hpp) are correctly ordered and do not need adjustment.
Learnt from: junhaoliao
PR: y-scope/clp#939
File: components/package-template/src/etc/clp-config.yml:64-64
Timestamp: 2025-06-24T20:13:46.758Z
Learning: When users ask CodeRabbit to create an issue after providing suggestions, they want a GitHub issue created with the high-level requirements and context, not specific code implementations.
components/webui/server/src/plugins/DbManager.ts (2)
Learnt from: junhaoliao
PR: y-scope/clp#596
File: components/log-viewer-webui/client/src/api/query.js:16-23
Timestamp: 2024-11-21T15:51:33.203Z
Learning: In `components/log-viewer-webui/client/src/api/query.js`, the `ExtractJsonResp` type definition is accurate as-is and does not require modification. When suggesting changes to type definitions, ensure they align with the server-side definitions, referencing the source code if necessary.
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1004
File: components/clp-package-utils/clp_package_utils/scripts/native/decompress.py:139-144
Timestamp: 2025-06-24T08:54:14.438Z
Learning: In the CLP codebase, the get_orig_file_id function signature was changed after a recent merge to no longer accept a dataset parameter, making previous suggestions that reference this parameter invalid.
🧬 Code Graph Analysis (2)
components/webui/client/src/pages/SearchPage/SearchControls/Dataset/sql.ts (2)
components/webui/client/src/settings.ts (1)
  • settings (34-34)
components/webui/client/src/api/sql.ts (1)
  • querySql (14-14)
components/clp-package-utils/clp_package_utils/general.py (2)
components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py (1)
  • fetch_existing_datasets (184-196)
components/clp-py-utils/clp_py_utils/clp_config.py (1)
  • Database (80-159)
🪛 GitHub Actions: clp-lint
components/webui/server/src/routes/query.ts

[error] 61-61: ESLint: Expected newline between test and consequent of ternary expression (@stylistic/multiline-ternary)


[error] 61-61: ESLint: Expected newline between consequent and alternate of ternary expression (@stylistic/multiline-ternary)

components/webui/server/src/fastify-v2/routes/api/search/index.ts

[error] 73-73: ESLint: Expected newline between test and consequent of ternary expression (@stylistic/multiline-ternary)


[error] 73-73: ESLint: Expected newline between consequent and alternate of ternary expression (@stylistic/multiline-ternary)

🔇 Additional comments (15)
components/clp-package-utils/clp_package_utils/general.py (4)

5-5: LGTM: Import added for regex validation.

The re module import is appropriately added to support the regex pattern matching in the new validate_dataset_name function.


29-33: LGTM: Required constants imported for dataset validation.

The imports from clp_metadata_db_utils provide the necessary constants for MySQL table name length validation and the function to fetch existing datasets.


570-570: LGTM: Function renamed for clarity.

Renaming validate_dataset to validate_dataset_exists better describes the function's purpose of validating dataset existence in the metadata database.


588-614: Separator logic validated: no changes needed.

The table-naming helper _get_table_name expects clp_table_prefix to include its own trailing underscore and appends exactly one underscore between the dataset name and the suffix. Subtracting 1 for that separator is correct—no adjustments required.

components/webui/client/src/settings.ts (1)

8-8: LGTM: Dataset table name property added to settings.

The addition of SqlDbClpDatasetsTableName property to the Settings type is correct and aligns with the dataset selection functionality being introduced throughout the codebase.

components/webui/server/src/routes/query.ts (2)

41-41: LGTM: Dataset parameter added to request schema.

The addition of the dataset string parameter to the request body schema correctly extends the API to support dataset selection.


48-48: LGTM: Dataset extracted from request body.

The destructuring correctly extracts the dataset parameter from the request body for use in the handler.

components/webui/client/src/pages/SearchPage/SearchControls/Dataset/sql.ts (6)

1-2: LGTM: Appropriate imports for SQL queries and settings.

The imports correctly bring in the SQL query function and settings configuration needed for dataset queries.


5-10: LGTM: Well-defined column names enum.

The enum provides a clean way to reference dataset table column names and improves maintainability.


12-20: LGTM: Proper SQL query construction using settings.

The SQL query correctly uses the configurable table name from settings and implements proper ordering. This addresses previous feedback about using settings.json for table names.


22-24: LGTM: Appropriate interface definition for query results.

The DatasetItem interface correctly models the expected shape of the query result rows.


26-34: LGTM: Clean implementation of dataset fetching function.

The function correctly executes the SQL query and extracts dataset names from the response. The error handling is delegated to the underlying querySql function, which is appropriate.


36-36: LGTM: Appropriate export of public API.

Only the fetchDatasetNames function is exported, maintaining a clean public interface.

components/webui/server/src/fastify-v2/routes/api/search/index.ts (1)

63-63: LGTM: Dataset parameter extracted from request body.

The destructuring correctly adds the dataset parameter to the extracted request body properties for use in the search query.

components/webui/server/src/plugins/DbManager.ts (1)

101-135: LGTM! Clean implementation of explicit dataset parameter handling.

The addition of the dataset parameter is well-implemented with proper typing, documentation, and usage. The parameter is correctly used only for EXTRACT_JSON jobs, which aligns with the different requirements of the job types. The explicit parameter approach replaces the previous hardcoded defaults, providing better control and flexibility for dataset selection.

Comment on lines 73 to 75
dataset: ("" === dataset ?
null :
dataset),
Copy link
Member

Choose a reason for hiding this comment

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

This is really a hack. On the client, if we change cachedDataset to default to null, when dataset: null is sent from the client, it gets changed into dataset: "" on the server. I tried a few different things but couldn't find a solution that worked. If we can't find a solution soon, I suggest we open an issue to investigate this properly.

Copy link
Contributor

@hoophalab hoophalab Jul 7, 2025

Choose a reason for hiding this comment

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

fixed in the new commit. Sorry, but can you run the package again to make sure the change is correct? @kirkrodrigues

Copy link
Contributor

Choose a reason for hiding this comment

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

I thought we cannot submit "" as a dataset?
Like this new condition added in this commit ("" === dataset ?null) should never be reached ?

Copy link
Contributor

@hoophalab hoophalab left a comment

Choose a reason for hiding this comment

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

The code works, but there are other style changes required. Let's make a release first.

* @return
*/
const Dataset = () => {
const {refreshInterval} = useIngestStatsStore();
Copy link
Contributor

@hoophalab hoophalab Jul 7, 2025

Choose a reason for hiding this comment

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

We shouldn't use a store from another page. Let's merge the code for now.

Copy link
Contributor

Choose a reason for hiding this comment

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

@coderabbitai create an issue

Copy link
Contributor

Choose a reason for hiding this comment

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

🧩 Analysis chain

@hoophalab I've created a GitHub issue to track the architectural concern about the Dataset component using a store from another page. The issue has been assigned to you and includes the relevant context and references to this PR and comment thread.


🏁 Script executed:

#!/bin/bash
# Create GitHub issue for architectural concern about cross-page store usage
gh issue create \
  --title "Refactor Dataset component to avoid cross-page store dependency" \
  --body "## Description

The Dataset component in the SearchPage is currently using \`useIngestStatsStore\` from the IngestPage, which creates inappropriate coupling between different pages/components.

## Context

This architectural concern was identified during code review where the Dataset component imports and uses a store from another page, violating good separation of concerns.

## Expected Outcome

The Dataset component should be refactored to either:
- Use a shared/global store for common data like refresh intervals
- Have its own local state management
- Receive necessary data through props

## References

- Original PR: https://github.com/y-scope/clp/pull/1050
- Comment thread: https://github.com/y-scope/clp/pull/1050#discussion_r2189045908
- Reported by: @hoophalab" \
  --assignee hoophalab

Length of output: 940


@hoophalab Perfect! I've successfully created GitHub issue #1073 to track the architectural concern about the Dataset component using a cross-page store dependency.

Issue created: #1073

The issue has been assigned to you and includes all the relevant context, expected outcomes, and references to this PR and comment thread.

🐰✨
Thoughtfully documenting architectural improvements for future work


🧬 Code Graph Analysis Results

Relevant snippet from components/webui/client/src/pages/SearchPage/SearchControls/Dataset/sql.ts (line 36):

fetchDatasetNames

This is the function imported and used as the queryFn in the useQuery hook within index.tsx to fetch the list of dataset names. Understanding its implementation is important to know how datasets are retrieved.


No relevant content from components/core/src/clp_s/ArchiveWriter.hpp (line 146):

The open(ArchiveWriterOption const& option) method in ArchiveWriter.hpp is unrelated to the React component or dataset fetching logic in the provided file. It appears to be part of a C++ backend or core library and does not impact the frontend dataset selector component.


Summary: The only relevant snippet is the fetchDatasetNames function from sql.ts since it directly relates to the dataset fetching logic used in the Dataset React component. The other snippet is unrelated.


🧠 Learnings used
Learnt from: junhaoliao
PR: y-scope/clp#962
File: components/log-viewer-webui/client/src/pages/SearchPage/SearchQueryStatus/Results.tsx:22-26
Timestamp: 2025-06-09T17:15:30.309Z
Learning: When using Zustand stores in React components, always use specific selectors (e.g., `useStore(state => state.property)`) instead of destructuring the entire state object to prevent unnecessary re-renders. This is especially important as state stores grow in complexity.

Learnt from: junhaoliao
PR: y-scope/clp#962
File: components/log-viewer-webui/client/src/pages/SearchPage/SearchQueryStatus/Results.tsx:22-26
Timestamp: 2025-06-09T17:15:30.309Z
Learning: When using Zustand stores in React components, always use specific selectors (e.g., `useStore(state => state.property)`) instead of destructuring the entire state object to prevent unnecessary re-renders. This is especially important as state stores grow in complexity.

Learnt from: junhaoliao
PR: y-scope/clp#937
File: components/log-viewer-webui/client/src/AntdApp.tsx:16-24
Timestamp: 2025-05-29T20:33:40.653Z
Learning: In components/log-viewer-webui React codebase: Return type annotations (like `: JSX.Element`) are unnecessary and not preferred for React components in JSX/TSX files.

Learnt from: junhaoliao
PR: y-scope/clp#939
File: components/package-template/src/etc/clp-config.yml:64-64
Timestamp: 2025-06-24T20:13:46.758Z
Learning: When users ask CodeRabbit to create an issue after providing suggestions, they want a GitHub issue created with the high-level requirements and context, not specific code implementations.

Learnt from: Bill-hbrhbr
PR: y-scope/clp#1050
File: components/clp-package-utils/clp_package_utils/scripts/search.py:100-106
Timestamp: 2025-07-03T20:10:43.761Z
Learning: In the current CLP codebase implementation, dataset validation using validate_dataset() is performed within the native scripts (like clp_package_utils/scripts/native/search.py) rather than at the wrapper script level, where the native scripts handle their own parameter validation.

Learnt from: Bill-hbrhbr
PR: y-scope/clp#1050
File: components/clp-package-utils/clp_package_utils/scripts/search.py:100-106
Timestamp: 2025-07-03T20:10:43.761Z
Learning: In the current CLP codebase implementation, dataset validation using validate_dataset() is performed within the native scripts (like clp_package_utils/scripts/native/search.py) rather than at the wrapper script level, where the native scripts handle their own parameter validation.

Learnt from: Bill-hbrhbr
PR: y-scope/clp#1036
File: components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py:204-211
Timestamp: 2025-07-03T12:58:18.407Z
Learning: In the CLP codebase, the validate_and_cache_dataset function in components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py uses in-place updates of the existing_datasets set parameter rather than returning a new set, as preferred by the development team.

Comment on lines 73 to 75
dataset: ("" === dataset ?
null :
dataset),
Copy link
Contributor

@hoophalab hoophalab Jul 7, 2025

Choose a reason for hiding this comment

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

fixed in the new commit. Sorry, but can you run the package again to make sure the change is correct? @kirkrodrigues

Copy link
Contributor

Choose a reason for hiding this comment

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

I dont fully understand all these changes, if they are required let me know

Copy link
Member

Choose a reason for hiding this comment

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

I think Chaoyue already got rid of them in favour of the correct way of doing things.

@hoophalab
Copy link
Contributor

One issue that manifests in webui but is caused by the package.

  1. Compress structured logs without --timestamp-key
    compress.sh --dataset dataset1 postgresql.log
  2. Search with * returns nothing
    search.sh --begin-time -100000 --end-time 2000000000000 --dataset ds2 \*
    @coderabbitai can you create an issue on this

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 7, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

@hoophalab, I'll create a GitHub issue to track this bug.


🏁 Script executed:

#!/bin/bash
# Create a GitHub issue for the reported bug
gh issue create \
  --title "Search with wildcard returns no results after compressing structured logs without --timestamp-key" \
  --body "## Description

A bug has been identified where searching with wildcard \`*\` returns no results when the logs were compressed without specifying the \`--timestamp-key\` argument for structured logs.

## Steps to Reproduce

1. Compress structured logs without \`--timestamp-key\`:
   \`\`\`bash
   compress.sh --dataset dataset1 postgresql.log
   \`\`\`

2. Search with wildcard:
   \`\`\`bash
   search.sh --begin-time -100000 --end-time 2000000000000 --dataset ds2 \\*
   \`\`\`

## Expected Behavior
Search should return matching results from the compressed logs.

## Actual Behavior
Search returns no results.

## Additional Context
- This issue manifests in the webui but is caused by the package
- Reported in PR #1050: https://github.com/y-scope/clp/pull/1050
- Original comment: https://github.com/y-scope/clp/pull/1050#issuecomment-$(gh api repos/y-scope/clp/pulls/1050/comments --jq '.[-1].id')

## Environment
- Component: clp-package
- Affects: WebUI search functionality" \
  --assignee hoophalab

Length of output: 1174


Perfect! I've successfully created GitHub issue #1075 to track this bug: #1075

The issue includes:

  • Clear reproduction steps with the commands you provided
  • Expected vs actual behavior
  • Context that it manifests in WebUI but is caused by the package
  • Reference back to this PR and your comment
  • Assigned to you as requested

This will help ensure the bug gets proper attention and tracking for resolution.


🧠 Learnings used
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1050
File: components/clp-package-utils/clp_package_utils/scripts/search.py:100-106
Timestamp: 2025-07-03T20:10:43.789Z
Learning: In the current CLP codebase implementation, dataset validation using validate_dataset() is performed within the native scripts (like clp_package_utils/scripts/native/search.py) rather than at the wrapper script level, where the native scripts handle their own parameter validation.

Learnt from: Bill-hbrhbr
PR: y-scope/clp#1050
File: components/clp-package-utils/clp_package_utils/scripts/search.py:100-106
Timestamp: 2025-07-03T20:10:43.789Z
Learning: In the current CLP codebase implementation, dataset validation using validate_dataset() is performed within the native scripts (like clp_package_utils/scripts/native/search.py) rather than at the wrapper script level, where the native scripts handle their own parameter validation.

Learnt from: Bill-hbrhbr
PR: y-scope/clp#1036
File: components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py:204-211
Timestamp: 2025-07-03T12:58:18.407Z
Learning: In the CLP codebase, the validate_and_cache_dataset function in components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py uses in-place updates of the existing_datasets set parameter rather than returning a new set, as preferred by the development team.

fastify.post("/query/extract-stream", {
schema: {
body: Type.Object({
// Type.Null must come before Type.String;
Copy link
Contributor

@davemarco davemarco Jul 7, 2025

Choose a reason for hiding this comment

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

This isnt explicity required since the cached dataset cannot be null. But I guess it isnt hurtful to include it

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess the dataset needs to be null for clp-text flavor, as kirk has already fixed in his commits.

Copy link
Member

Choose a reason for hiding this comment

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

I think we can change cachedDataset to default to null now, after your fix, @hoophalab.

@hoophalab
Copy link
Contributor

Another user-friendliness issue (not caused by the web UI itself):

When submitting a query through the web UI, it actually sends two separate requests to the CLP package — one for the timeline and another for the search results.
As a result, the search job count increases by 2 for each query.
We could explore ways to handle this more nicely.

image

@coderabbitai can you create an issue on this?

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 7, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

@hoophalab, I'll create a GitHub issue to track this user-friendliness concern about dual search requests.

Perfect! I've created GitHub issue #1076 to track this user-friendliness concern: #1076

The issue documents:

  • The dual request problem (timeline + search results)
  • The impact on job count accuracy
  • Potential solutions to explore (request consolidation, better UX feedback, etc.)
  • Reference back to this PR and your comment
  • Assigned to you as requested

This will help ensure the team can investigate optimizations to improve the user experience around search job management.


🏁 Script executed:

#!/bin/bash
# Create a GitHub issue for the dual search request problem
gh issue create \
  --title "Web UI sends duplicate search requests causing job count to increase by 2 per query" \
  --body "## Description

The web UI currently sends two separate requests to the CLP package for each user query:
1. One request for the timeline data
2. Another request for the search results

This causes the search job count to increase by 2 for each query submitted through the web UI, which creates a confusing user experience and unnecessary overhead.

## Steps to Reproduce

1. Open the web UI
2. Submit a search query
3. Observe the search job count increases by 2 instead of 1

## Expected Behavior
Each user query should ideally result in a single job count increment, or the dual requests should be handled in a way that provides better user feedback.

## Actual Behavior
Search job count increases by 2 for each query, making it appear as if twice as many searches are being performed.

## Potential Solutions to Explore
- Combine timeline and search results into a single request
- Provide clearer indication to users about why multiple jobs are created
- Optimize the backend to handle both timeline and results more efficiently
- Consider caching strategies to reduce redundant requests

## Additional Context
- This is not caused by the web UI itself but appears to be an architectural consideration
- Issue affects user perception of system load and job management
- Reported in PR #1050: https://github.com/y-scope/clp/pull/1050
- Original comment: https://github.com/y-scope/clp/pull/1050#issuecomment-\$(gh api repos/y-scope/clp/pulls/1050/comments --jq '.[-1].id')

## Environment
- Component: Web UI + CLP Package interaction
- Affects: User experience and job count accuracy" \
  --assignee hoophalab

Length of output: 1777


Perfect! I've successfully created GitHub issue #1077 to track this user-friendliness concern: #1077

The issue comprehensively documents:

  • Problem: Web UI sends two separate requests (timeline + search results) per query
  • Impact: Job count increases by 2 instead of 1, creating user confusion
  • Reproduction steps: Clear steps to observe the behavior
  • Potential solutions: Multiple approaches to explore (request consolidation, better UX feedback, backend optimization, caching)
  • Context: Notes that it's an architectural consideration rather than a web UI bug
  • References: Links back to this PR and your comment
  • Assignment: Assigned to you as requested

This will help the team investigate and implement improvements to provide a better user experience around search job management and system load perception.


🧠 Learnings used
Learnt from: Bill-hbrhbr
PR: y-scope/clp#1050
File: components/clp-package-utils/clp_package_utils/scripts/search.py:100-106
Timestamp: 2025-07-03T20:10:43.789Z
Learning: In the current CLP codebase implementation, dataset validation using validate_dataset() is performed within the native scripts (like clp_package_utils/scripts/native/search.py) rather than at the wrapper script level, where the native scripts handle their own parameter validation.

Learnt from: Bill-hbrhbr
PR: y-scope/clp#1050
File: components/clp-package-utils/clp_package_utils/scripts/search.py:100-106
Timestamp: 2025-07-03T20:10:43.789Z
Learning: In the current CLP codebase implementation, dataset validation using validate_dataset() is performed within the native scripts (like clp_package_utils/scripts/native/search.py) rather than at the wrapper script level, where the native scripts handle their own parameter validation.

Learnt from: Bill-hbrhbr
PR: y-scope/clp#1036
File: components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py:204-211
Timestamp: 2025-07-03T12:58:18.407Z
Learning: In the CLP codebase, the validate_and_cache_dataset function in components/clp-py-utils/clp_py_utils/clp_metadata_db_utils.py uses in-place updates of the existing_datasets set parameter rather than returning a new set, as preferred by the development team.

Copy link
Member

@junhaoliao junhaoliao left a comment

Choose a reason for hiding this comment

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

approving to provide write access since @hoophalab has reviewed the code

return -1

storage_engine: StorageEngine = clp_config.package.storage_engine
dataset = parsed_args.dataset
Copy link
Member

Choose a reason for hiding this comment

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

if the parser used is ir_extraction_parser instead of json_extraction_parser, below error is raised:

junhao@ASUS-X870E:~/workspace/clp/build/clp-package/sbin$ ./decompress.sh i --orig-file-id=4577ad28-f615-4d37-8e7f-cd35dbb2324c 1
Traceback (most recent call last):
  File "/usr/lib/python3.10/runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib/python3.10/runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "/home/junhao/workspace/clp/build/clp-package/lib/python3/site-packages/clp_package_utils/scripts/decompress.py", line 321, in <module>
    sys.exit(main(sys.argv))
  File "/home/junhao/workspace/clp/build/clp-package/lib/python3/site-packages/clp_package_utils/scripts/decompress.py", line 314, in main
    return handle_extract_stream_cmd(parsed_args, clp_home, default_config_file_path)
  File "/home/junhao/workspace/clp/build/clp-package/lib/python3/site-packages/clp_package_utils/scripts/decompress.py", line 188, in handle_extract_stream_cmd
    dataset = parsed_args.dataset
AttributeError: 'Namespace' object has no attribute 'dataset'

@coderabbitai create an issue to track this

Copy link
Contributor

Choose a reason for hiding this comment

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

🧩 Analysis chain

I can see the issue - the --dataset argument was only added to the json_extraction_parser but not to the ir_extraction_parser, yet the handle_extract_stream_cmd function tries to access parsed_args.dataset regardless of which parser was used.

Let me create an issue to track this bug:

@junhaoliao I've created an issue to track this bug. The problem is that the --dataset argument was only added to the json_extraction_parser but not to the ir_extraction_parser, yet the code tries to access parsed_args.dataset in both cases. This needs to be fixed by either adding the --dataset argument to the IR extraction parser or handling the missing attribute gracefully.


🏁 Script executed:

#!/bin/bash
gh issue create \
  --title "IR extraction parser missing --dataset argument causes AttributeError" \
  --body "## Description

When using the IR extraction parser in the decompress script, an AttributeError is raised because the \`--dataset\` argument was not added to the \`ir_extraction_parser\`, only to the \`json_extraction_parser\`.

## Error

\`\`\`
AttributeError: 'Namespace' object has no attribute 'dataset'
\`\`\`

## Steps to Reproduce

1. Run the decompress script with IR extraction: \`./decompress.sh i --orig-file-id=4577ad28-f615-4d37-8e7f-cd35dbb2324c 1\`
2. The script fails at line 188 in \`handle_extract_stream_cmd\` when trying to access \`parsed_args.dataset\`

## Root Cause

In PR #1050, the \`--dataset\` argument was only added to the \`json_extraction_parser\` but not to the \`ir_extraction_parser\`. However, the \`handle_extract_stream_cmd\` function tries to access \`parsed_args.dataset\` regardless of which parser was used.

## Expected Behavior

The \`ir_extraction_parser\` should also have the \`--dataset\` argument added, or the code should handle cases where the dataset argument is not available.

## Related

- PR: https://github.com/y-scope/clp/pull/1050
- Comment: https://github.com/y-scope/clp/pull/1050#discussion_r2275420916
- Reported by: @junhaoliao" \
  --assignee junhaoliao

Length of output: 1343


Perfect! I've successfully created issue #1200 to track this bug. The issue documents:

  • Root cause: The --dataset argument was only added to the json_extraction_parser but not to the ir_extraction_parser
  • Error details: AttributeError: 'Namespace' object has no attribute 'dataset' when using IR extraction
  • Steps to reproduce: Using the decompress script with IR extraction command
  • Expected fix: Either add the --dataset argument to the IR extraction parser or handle the missing attribute gracefully

The issue has been assigned to you as requested and includes backlinks to this PR and comment for proper tracking.


🧬 Code Graph Analysis Results
  • File: components/clp-package-utils/clp_package_utils/scripts/decompress.py, lines 257-317
def main(argv):
    clp_home = get_clp_home()
    default_config_file_path = clp_home / CLP_DEFAULT_CONFIG_FILE_RELATIVE_PATH

    args_parser = argparse.ArgumentParser(description="Decompresses logs")
    args_parser.add_argument(
        "--config",
        "-c",
        default=str(default_config_file_path),
        help="CLP configuration file.",
    )
    command_args_parser = args_parser.add_subparsers(dest="command", required=True)

    # File extraction command parser
    file_extraction_parser = command_args_parser.add_parser(EXTRACT_FILE_CMD)
    file_extraction_parser.add_argument(
        "paths", metavar="PATH", nargs="*", help="Files to extract."
    )
    file_extraction_parser.add_argument(
        "-f", "--files-from", help="A file listing all files to extract."
    )
    file_extraction_parser.add_argument(
        "-d", "--extraction-dir", metavar="DIR", default=".", help="Extract files into DIR."
    )

    # IR extraction command parser
    ir_extraction_parser = command_args_parser.add_parser(EXTRACT_IR_CMD)
    ir_extraction_parser.add_argument("msg_ix", type=int, help="Message index.")
    ir_extraction_parser.add_argument(
        "--target-uncompressed-size", type=int, help="Target uncompressed IR size."
    )

    group = ir_extraction_parser.add_mutually_exclusive_group(required=True)
    group.add_argument("--orig-file-id", type=str, help="Original file's ID.")
    group.add_argument("--orig-file-path", type=str, help="Original file's path.")

    # JSON extraction command parser
    json_extraction_parser = command_args_parser.add_parser(EXTRACT_JSON_CMD)
    json_extraction_parser.add_argument("archive_id", type=str, help="Archive ID")
    json_extraction_parser.add_argument(
        "--dataset",
        type=str,
        default=None,
        help="The dataset that the archives belong to.",
    )
    json_extraction_parser.add_argument(
        "--target-chunk-size",
        type=int,
        help="Target chunk size (B).",
    )

    parsed_args = args_parser.parse_args(argv[1:])

    command = parsed_args.command
    if EXTRACT_FILE_CMD == command:
        return handle_extract_file_cmd(parsed_args, clp_home, default_config_file_path)
    elif command in (EXTRACT_IR_CMD, EXTRACT_JSON_CMD):
        return handle_extract_stream_cmd(parsed_args, clp_home, default_config_file_path)
    else:
        logger.exception(f"Unexpected command: {command}")
        return -1
  • File: components/clp-package-utils/clp_package_utils/scripts/native/decompress.py, lines 273-332
def main(argv):
    clp_home = get_clp_home()
    default_config_file_path = clp_home / CLP_DEFAULT_CONFIG_FILE_RELATIVE_PATH

    args_parser = argparse.ArgumentParser(description="Decompresses logs.")
    args_parser.add_argument(
        "--config",
        "-c",
        default=str(default_config_file_path),
        help="CLP configuration file.",
    )
    command_args_parser = args_parser.add_subparsers(dest="command", required=True)

    # File extraction command parser
    file_extraction_parser = command_args_parser.add_parser(EXTRACT_FILE_CMD)
    file_extraction_parser.add_argument(
        "paths", metavar="PATH", nargs="*", help="Files to extract."
    )
    file_extraction_parser.add_argument(
        "-f", "--files-from", help="A file listing all files to extract."
    )
    file_extraction_parser.add_argument(
        "-d", "--extraction-dir", metavar="DIR", default=".", help="Extract files into DIR."
    )

    # IR extraction command parser
    ir_extraction_parser = command_args_parser.add_parser(EXTRACT_IR_CMD)
    ir_extraction_parser.add_argument("msg_ix", type=int, help="Message index.")
    ir_extraction_parser.add_argument(
        "--target-uncompressed-size", type=int, help="Target uncompressed IR size."
    )

    group = ir_extraction_parser.add_mutually_exclusive_group(required=True)
    group.add_argument("--orig-file-id", type=str, help="Original file's ID.")
    group.add_argument("--orig-file-path", type=str, help="Original file's path.")

    # JSON extraction command parser
    json_extraction_parser = command_args_parser.add_parser(EXTRACT_JSON_CMD)
    json_extraction_parser.add_argument("archive_id", type=str, help="Archive ID")
    json_extraction_parser.add_argument(
        "--dataset",
        type=str,
        default=None,
        help="The dataset that the archives belong to.",
    )
    json_extraction_parser.add_argument(
        "--target-chunk-size", type=int, help="Target chunk size (B)."
    )

    parsed_args = args_parser.parse_args(argv[1:])

    command = parsed_args.command
    if EXTRACT_FILE_CMD == command:
        return handle_extract_file_cmd(parsed_args, clp_home, default_config_file_path)
    elif command in (EXTRACT_IR_CMD, EXTRACT_JSON_CMD):
        return handle_extract_stream_cmd(parsed_args, clp_home, default_config_file_path)
    else:
        logger.exception(f"Unexpected command: {command}")
        return -1
  • File: components/clp-package-utils/clp_package_utils/scripts/native/archive_manager.py, lines 85-241
def main(argv: typing.List[str]) -> int:
    clp_home: Path = get_clp_home()
    default_config_file_path: Path = clp_home / CLP_DEFAULT_CONFIG_FILE_RELATIVE_PATH

    # Top-level parser and options
    args_parser: argparse.ArgumentParser = argparse.ArgumentParser(
        description="View list of archive IDs or delete compressed archives."
    )
    args_parser.add_argument(
        "--config",
        "-c",
        default=str(default_config_file_path),
        help="CLP configuration file.",
    )
    args_parser.add_argument(
        "--dataset",
        type=str,
        default=None,
        help="The dataset that the archives belong to.",
    )

    # Top-level commands
    subparsers: argparse._SubParsersAction[argparse.ArgumentParser] = args_parser.add_subparsers(
        dest="subcommand",
        required=True,
    )
    find_parser: argparse.ArgumentParser = subparsers.add_parser(
        FIND_COMMAND,
        help="List IDs of archives.",
    )
    del_parser: argparse.ArgumentParser = subparsers.add_parser(
        DEL_COMMAND,
        help="Delete archives from the database and file system.",
    )

    # Options for find subcommand
    find_parser.add_argument(
        BEGIN_TS_ARG,
        dest="begin_ts",
        type=int,
        help="Time-range lower-bound (inclusive) as milliseconds from the UNIX epoch.",
    )
    find_parser.add_argument(
        END_TS_ARG,
        dest="end_ts",
        type=int,
        help="Time-range upper-bound (inclusive) as milliseconds from the UNIX epoch.",
    )

    # Options for delete subcommand
    del_parser.add_argument(
        DRY_RUN_ARG,
        dest="dry_run",
        action="store_true",
        help="Preview delete without making changes. Lists errors and files to be deleted.",
    )

    # Subcommands for delete subcommands
    del_subparsers: argparse._SubParsersAction[argparse.ArgumentParser] = del_parser.add_subparsers(
        dest="del_subcommand",
        required=True,
    )

    # Delete by ID subcomand
    del_id_parser: argparse.ArgumentParser = del_subparsers.add_parser(
        DEL_BY_IDS_SUBCOMMAND,
        help="Delete archives by ID.",
    )

    # Delete by ID arguments
    del_id_parser.add_argument(
        "ids",
        nargs="+",
        help="List of archive IDs to delete",
    )

    # Delete by filter subcommand
    del_filter_parser: argparse.ArgumentParser = del_subparsers.add_parser(
        DEL_BY_FILTER_SUBCOMMAND,
        help="Deletes archives that fall within the specified time range.",
    )

    # Delete by filter arguments
    del_filter_parser.add_argument(
        "begin_ts",
        type=int,
        help="Time-range lower-bound (inclusive) as milliseconds from the UNIX epoch.",
    )
    del_filter_parser.add_argument(
        "end_ts",
        type=int,
        help="Time-range upper-bound (inclusive) as milliseconds from the UNIX epoch.",
    )

    parsed_args: argparse.Namespace = args_parser.parse_args(argv[1:])

    # Validate and load config file
    config_file_path: Path = Path(parsed_args.config)
    try:
        clp_config: CLPConfig = load_config_file(
            config_file_path, default_config_file_path, clp_home
        )
        clp_config.validate_logs_dir()
    except:
        logger.exception("Failed to load config.")
        return -1

    database_config: Database = clp_config.database
    dataset = parsed_args.dataset
    if dataset is not None:
        try:
            validate_dataset_exists(database_config, dataset)
        except Exception as e:
            logger.error(e)
            return -1

    archives_dir: Path = clp_config.archive_output.get_directory()
    if not archives_dir.exists():
        logger.error("`archive_output.directory` doesn't exist.")
        return -1

    if FIND_COMMAND == parsed_args.subcommand:
        return _find_archives(
            archives_dir,
            database_config,
            dataset,
            parsed_args.begin_ts,
            parsed_args.end_ts,
        )
    elif DEL_COMMAND == parsed_args.subcommand:
        delete_handler: DeleteHandler
        if DEL_BY_IDS_SUBCOMMAND == parsed_args.del_subcommand:
            delete_handler: IdDeleteHandler = IdDeleteHandler(parsed_args.ids)
            return _delete_archives(
                archives_dir,
                database_config,
                dataset,
                delete_handler,
                parsed_args.dry_run,
            )
        elif DEL_BY_FILTER_SUBCOMMAND == parsed_args.del_subcommand:
            delete_handler: FilterDeleteHandler = FilterDeleteHandler(
                [parsed_args.begin_ts, parsed_args.end_ts]
            )
            return _delete_archives(
                archives_dir,
                database_config,
                dataset,
                delete_handler,
                parsed_args.dry_run,
            )
        else:
            logger.error(f"Unsupported subcommand: `{parsed_args.del_subcommand}`.")
            return -1
    else:
        logger.error(f"Unsupported subcommand: `{parsed_args.subcommand}`.")
        return -1

✏️ Learnings added
Learnt from: junhaoliao
PR: y-scope/clp#1050
File: components/clp-package-utils/clp_package_utils/scripts/archive_manager.py:178-178
Timestamp: 2025-08-14T05:06:58.977Z
Learning: In the decompress.py script, the --dataset argument was only added to the json_extraction_parser but not to the ir_extraction_parser, causing AttributeError when handle_extract_stream_cmd tries to access parsed_args.dataset for IR extraction commands.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

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.

6 participants