Add a new system table `user_query_log` by niyue · Pull Request #104462 · ClickHouse/ClickHouse · GitHub
Skip to content

Add a new system table user_query_log#104462

Open
niyue wants to merge 30 commits into
ClickHouse:masterfrom
niyue:feat/user-query-log
Open

Add a new system table user_query_log#104462
niyue wants to merge 30 commits into
ClickHouse:masterfrom
niyue:feat/user-query-log

Conversation

@niyue

@niyue niyue commented May 9, 2026

Copy link
Copy Markdown
Contributor

Changelog category (leave one):

  • New Feature

Changelog entry:

  • Added system.user_query_log system table that allows users to read only their own query log records without direct access to system.query_log.

Documentation entry for user-facing changes

  • Documentation is written

This PR will address #82539

@alexey-milovidov alexey-milovidov added the can be tested Allows running workflows for external contributors label May 9, 2026
@clickhouse-gh

clickhouse-gh Bot commented May 9, 2026

Copy link
Copy Markdown
Contributor

@clickhouse-gh clickhouse-gh Bot added the pr-feature Pull request with new product feature label May 9, 2026
Comment thread src/Storages/StorageView.cpp
Comment thread src/Storages/System/attachSystemTables.cpp Outdated
Comment thread src/Storages/System/attachSystemTables.cpp Outdated
@niyue niyue force-pushed the feat/user-query-log branch from ea9e2d4 to bca687e Compare May 10, 2026 13:58
Comment thread docs/en/operations/system-tables/user_query_log.md Outdated
Comment thread src/Storages/System/attachSystemTables.cpp Outdated
@niyue

niyue commented May 11, 2026

Copy link
Copy Markdown
Contributor Author

Hi @alexey-milovidov,

This PR is ready for review, could you please help? Thanks.

@alexey-milovidov

Copy link
Copy Markdown
Member

The FileCacheTest.SLRUFreeSpaceKeepingProtectedOnly failure on this PR is a known flaky test that was fixed in #104418. Could you please update the branch with the latest master to pick up the fix?

niyue added 10 commits May 13, 2026 09:40
Introduce a  security barrier mode that prevents view inlining and outer filter pushdown, and exposes barrier view columns without wrappers. Use it so user-supplied predicates cannot evaluate against filtered-out values.
Expose `attachSystemUserQueryLog` so `clickhouse-local` can create `system.user_query_log` after `initializeSystemLogs` creates `system.query_log`.
Add the required `current_database = currentDatabase()` predicate to `system.query_log` and `system.user_query_log` queries in the stateless test, so the query log style check accepts the test and concurrent test logs are ignored.

Issue: ClickHouse#82539
@niyue niyue force-pushed the feat/user-query-log branch from 01c8e4d to a6045a2 Compare May 13, 2026 01:45
Comment thread src/Storages/System/attachSystemTables.cpp Outdated
@niyue

niyue commented May 13, 2026

Copy link
Copy Markdown
Contributor Author

@alexey-milovidov Thanks for the guidance. I've updated the branch with the latest master.

Comment thread src/Storages/System/attachSystemTables.cpp Outdated
@niyue niyue force-pushed the feat/user-query-log branch from 460b718 to ffd3010 Compare May 13, 2026 15:06
Comment thread docs/en/operations/system-tables/user_query_log.md Outdated
# Conflicts:
#	src/Storages/System/attachSystemTables.cpp
#	src/Storages/System/attachSystemTables.h
@alexey-milovidov

Copy link
Copy Markdown
Member

Updated the branch with the latest master (resolved the conflicts in attachSystemTables.cpp/attachSystemTables.h against the new attachSystemTablesServer signature that gained the has_keeper_server parameter). CI is re-running.

For the record, the two red checks on the previous CI run were not caused by this PR:

  • 02180_group_by_lowcardinality failed on ~110 PRs (and on master itself) on 2026-05-17/18 — a transient master breakage during that window, clean since. The branch was simply stale.
  • The AST fuzzer does not have valid source node logical error is a recurring analyzer/JOIN fuzzer flake seen across many unrelated PRs (its stack is in PlannerJoins.cpp, unrelated to views).

The security_barrier view changes only affect the single system.user_query_log view (allowsViewInlining() is false only there), so ordinary views — and the 02180 test — are unaffected.

Comment thread src/Storages/System/attachSystemTables.cpp
niyue added 6 commits June 15, 2026 16:05
Replace debug-only `assert` checks in the system view attachment path with `chassert` so the code follows the ClickHouse assertion style.
Mark generated `StorageView` instances attached as system views as system storage, and rebuild `CREATE VIEW` metadata from in-memory view metadata for system view introspection.

Add coverage for `SHOW CREATE TABLE system.user_query_log` and `system.tables.as_select`.
Reject user-created or renamed objects at the reserved system table name even when the configured view is disabled or not attached.

Add coverage for `CREATE TABLE` and `RENAME TABLE` attempts that target the reserved name.
Reject non-system storage in the common `attachTable` path when it targets the reserved filtered user query log view name, so startup metadata loading also fails closed.

Add coverage for a legacy `metadata/system/user_query_log.sql` file loaded by `clickhouse-local`.

Related: ClickHouse#104462
Comment thread src/Storages/System/attachSystemTables.cpp Outdated
Run the filtered system view without a `default` definer so `StorageView` does not depend on a mutable user identity. Validate the view metadata as `SQL SECURITY NONE` and extend introspection coverage to check the missing definer.
Comment thread docs/en/operations/system-tables/user_query_log.md Outdated
Update the system table documentation to describe `SQL SECURITY NONE` instead of the removed `default` definer dependency.
Comment thread src/Storages/System/attachSystemTables.cpp Outdated
Use `initial_user` when it is present so distributed query-log rows remain visible to the original caller and are not exposed to the remote execution user. Keep `user` as the fallback for rows without an initiating user.
Comment thread src/Storages/System/attachSystemTables.cpp Outdated
Comment thread src/Storages/System/attachSystemTables.cpp Outdated
Avoid emitting `PREWHERE` in the view definition because the configured
`query_log.engine` can use storages such as `Null` that do not support
`PREWHERE`. A normal `WHERE` predicate keeps those engines usable while
still allowing `MergeTree` to optimize the filter.

Add a stateless regression test for `ENGINE = Null` query log storage.
Comment thread docs/en/operations/system-tables/user_query_log.md Outdated
niyue added 3 commits June 20, 2026 15:37
Build the view comment from the configured query log table so
`system.tables.comment` matches the actual `SELECT` source when
`query_log.table` is customized.

Extend the `ENGINE = Null` regression test to use a custom query log table
and check the generated comment.
Drop the documentation sentence that said the view filter uses `PREWHERE`.
The view now uses `WHERE`, and the exact clause is an implementation detail
already covered by `SHOW CREATE TABLE`.
Resolve the `DatabaseOnDisk` merge conflict by keeping the view-specific
metadata handling while preserving the upstream `metadata_ptr` comment path.
Comment thread src/Storages/StorageView.cpp
Prevent `additional_table_filters` from being applied through
`system.user_query_log`, where filters targeting the underlying
`system.query_log` table could observe rows hidden by the view predicate.

Add a regression test that verifies such filters are rejected explicitly
instead of being evaluated inside the security barrier.
Comment thread src/Storages/StorageView.cpp Outdated
niyue and others added 2 commits June 22, 2026 22:34
Block `additional_result_filter` before planner filter collection can apply it through security barrier views, and reject it again when reading the view body.

Extend `system.user_query_log` coverage for both analyzer paths.
The Style check `various_checks.sh` requires every test that mentions
`system.query_log`/`system.query_thread_log` to include a
`current_database = currentDatabase()` condition. Test
`04402_user_query_log_additional_filters.sh` referenced `system.query_log`
only as the `additional_table_filters` map key (the source table of the
`system.user_query_log` view), which tripped the heuristic.

Add the predicate to the three `system.user_query_log` queries. The queries
are still rejected by the security-barrier view before reading any data, so
the test outcome is unchanged, and the predicate now also isolates the view
read by the test database.

CI report: ClickHouse#104462
@alexey-milovidov alexey-milovidov mentioned this pull request Jul 2, 2026
21 tasks
if (security_barrier)
{
const auto & settings = context->getSettingsRef();
if (!settings[Setting::additional_table_filters].value.empty())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This blocks every non-empty additional_table_filters map, but the side channel only exists for entries that can resolve inside the barrier view (for system.user_query_log, keys like system.query_log or the configured source table). additional_table_filters is table-scoped in parseAdditionalFilterConditionForTable, so safe cases now regress too: for example, SELECT ... FROM system.user_query_log u JOIN system.one o ... SETTINGS additional_table_filters = {'system.one': 'dummy = 0'} or ... SETTINGS additional_table_filters = {'system.user_query_log': 'event_date = today()'} will fail here even though those predicates only apply outside the barrier. Please reject or strip only keys that target the inner source table instead of banning the whole query.


<SystemLogParameters/>

The `enable_user_query_log` parameter creates [`system.user_query_log`](/operations/system-tables/user_query_log), a view over the query log table filtered by `currentUser`. It is enabled by default.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This setting description is stale again. The final implementation does not always read from system.query_log, and it no longer filters with just user = currentUser(): it reads from the configured query_log.database / query_log.table and uses the initiating-user predicate if(initial_user != '', initial_user, user) = currentUser(). Please keep this page aligned with docs/en/operations/system-tables/user_query_log.md so operators do not get contradictory behavior docs.

@clickhouse-gh

clickhouse-gh Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

LLVM Coverage Report

Metric Baseline Current Δ
Lines 85.50% 85.50% +0.00%
Functions 92.60% 92.60% +0.00%
Branches 77.70% 77.70% +0.00%

Changed lines: Changed C/C++ lines covered: 208/251 (82.87%) · Uncovered code

Full report · Diff report

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

can be tested Allows running workflows for external contributors pr-feature Pull request with new product feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants