Skip to content

fix(query): the related-row subquery names the prefixed magic table - #4684

Merged
rubenvdlinde merged 1 commit into
developmentfrom
fix/related-row-table-prefix
Oct 18, 2026
Merged

rubenvdlinde merged 1 commit into
developmentfrom
fix/related-row-table-prefix

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

What

_related and _referenced filters now work on an instance with a table prefix. Before this fix they failed on every real instance (oc_ is the default prefix).

RelatedRowExistsClause writes its subquery as raw SQL: EXISTS (SELECT 1 FROM <table> ...). The applier passed the name from MagicTableHandler::getTableNameForRegisterSchema(), which is the bare openregister_table_<register>_<schema>. Raw SQL in createFunction() gets no automatic prefix, so Postgres answered SQLSTATE[42P01] relation "openregister_table_23_281" does not exist. That was the 500 on dossiq's DqSubsidie tabs, found by BLD-Dq-D. #4682's empty-match guard wasn't the cause: the table exists as oc_openregister_table_23_281, so the guard passed and the query then failed. This PR keeps that guard.

How

The applier passes *PREFIX*openregister_table_<r>_<s>. Nextcloud's connection replaces *PREFIX* in every statement it runs (OC\DB\Connection::replaceTablePrefix()). I checked the other raw SQL the related-row path builds: the access predicate from MagicRbacHandler::buildRbacPredicateForAlias() names columns only, never a table, so this was the only bare table name.

Why the tests missed it

The test doubles for getTableNameForRegisterSchema() returned oc_openregister_table_…, a prefixed name the real method never returns. The clause tests then checked the SQL text. The doubles now return the bare name.

The test against a real database

RelatedRowPrefixedDatabaseTest (in tests/Unit) runs the applier's SQL on an in-memory SQLite database whose tables carry oc_, after the same *PREFIX* replacement Nextcloud's connection does:

  • a _referenced filter finds the matching row;
  • a filter with no matching referenced row returns nothing.

Without the fix it fails with no such table: openregister_table_1_2, the SQLite form of the 500. The unit suite has no Postgres or Nextcloud connection; the existing DB-backed tests (AuditTrail*) need the full Nextcloud server and error in a standalone run. So this test uses DBAL plus SQLite directly, and it copies the prefix replacement rather than calling OC\DB\Connection.

Possible issue, not fixed here

RelatedRowExistsClause::quoteIdentifier() quotes columns with double quotes on both engines. On MariaDB without ANSI_QUOTES that is not an identifier quote. I haven't verified this on MariaDB; it needs a check before anyone relies on these filters there.

Verified locally

  • All of tests/Unit/Service/Query/ (42 tests) and MagicSearchHandlerTest pass. The new test fails on development.
  • phpcs and phpmd report nothing on the changed lines.
  • One composer check:strict run: lint, phpcs, phpmd, psalm and phpstan pass. test:all ran 26,314 tests with 15 errors. The sorted error list is identical to development's: the AuditTrail and DraftRemovalAuditRow database tests that need the full Nextcloud server.

AI-assisted: written with Claude Code.

RelatedRowExistsClause wrote the bare openregister_table_<r>_<s> into raw
SQL, which gets no automatic prefix, so every _related and _referenced
filter failed with 42P01 on an instance with a table prefix (oc_ by
default). The applier now passes *PREFIX*openregister_table_<r>_<s>, which
Nextcloud's connection replaces. The test doubles that returned an
already-prefixed name now return the bare name the handler really answers,
and a new test runs the filter on SQLite with oc_ tables.

Assisted-by: ClaudeCode:claude-opus-5-5
@rubenvdlinde
rubenvdlinde merged commit 171043e into development Oct 18, 2026
43 of 44 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/openregister @ 834206d

Check PHP Vue Security License Tests
lint ✅
phpcs ✅
phpmd ❌
psalm ✅
phpstan ✅
phpmetrics ✅
eslint ✅
stylelint ✅
build ✅
check-specs ✅
test-l10n ✅
test-l10n-parity ✅
format ✅
check-schema-l10n ✅
composer ✅ ✅ 173/173
npm ✅ ✅ 648/648
app:check-code ⏭️
info.xml ✅
REUSE ✅
lockfile sync ✅
PHPUnit ✅ 26289/26289 · 25 skipped
Newman ✅ 714/714
Playwright ⏭️ deferred: E2E runs locally and on the promotion path only. This pull request targets development, so the suite is asked once per promotion into beta and main rather than once per push per open pull request. Run it locally with npx playwright test, or from the Actions tab on a branch with no open pull request into development.
Hydra gates ✅

Quality workflow — 2026-10-18 10:45 UTC

Download the full PDF report from the workflow artifacts.

WilcoLouwerse added a commit that referenced this pull request Oct 19, 2026
…-fixes-r2

Conflicts:
- OrganisationController: development's OrganisationUsageService (#4683
  usage report) and this branch's optional GrantChangeAuditor both join the
  constructor; the required service comes before the optional auditor.
- RelatedRowQueryApplier: development's missing-table guard and `*PREFIX*`
  table (#4682, #4684) kept; the bare table name still feeds the RBAC
  predicate's tableName (data-f3).
- OrganisationGrantManageGuardTest: both new constructor arguments.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant