--> written by AI, reviewed and approved by Greg -->

Problem

farm_multitenant_query_log_access_alter() in farm_multitenant.module joins three reference tables unconditionally:

$reference_fields = [
  'asset' => 'asset_target_id',
  'equipment' => 'equipment_target_id',
  'location' => 'location_target_id',
];
foreach ($reference_fields as $field => $field_column) {
  $query->leftJoin('log__' . $field, $log_field_alias, ...);
  ...
}

On farmOS installs that do not have the equipment-on-log field configured (e.g. installs without farm_equipment enabled — a legitimate configuration, since farmOS core modules are optional — or wherever the log__equipment table simply doesn't exist), any access-checked log query fails with:

SQLSTATE[42P01]: Undefined table: 7 ERROR:  relation "log__equipment" does not exist

This affects:

  • Views listings / dashboards issuing access-checked log queries for non-admin users
  • Log save flows that trigger access-tagged validation queries (e.g. quantity validation on log--activity save)

Steps to reproduce

farmOS 4.x-dev (without farm_equipment enabled) + farm_multitenant 2.0.0-beta1 + PostgreSQL 16 + Drupal core 11.3.3.

# As a non-admin user assigned to a farm group:
drush ev '\Drupal::entityQuery("log")->accessCheck(TRUE)->execute();'

Result: SQLSTATE[42P01]: relation "log__equipment" does not exist.

Proposed resolution

Before joining each reference table, check whether the field exists on the log entity type:

$field_manager = \Drupal::service('entity_field.manager');
$log_fields = $field_manager->getFieldStorageDefinitions('log');
foreach ($reference_fields as $field => $field_column) {
  if (!isset($log_fields[$field])) {
    continue;
  }
  // existing leftJoin + condition logic
}

The companion Views filter (AssetAccessFilter.php) already takes a defensive approach via $this->query->ensureTable('asset__farm') — query_log_access_alter should adopt the same style. query_quantity_access_alter likely needs the same treatment for any analogous joins (related: #3612253).

Workaround until fixed

Consumers can bypass by either:

  • accessCheck(FALSE) on log queries with an explicit user-uid filter (loses multitenant scoping — tradeoff)
  • Granting administer log to the user role (over-broad bypass)

Environment

  • Drupal core 11.3.3
  • farm_multitenant 2.0.0-beta1
  • PostgreSQL 16
  • farmOS 4.x-dev without farm_equipment module enabled

Disclosure: this issue text was prepared with AI assistance (Claude), directed and reviewed by me; the failure was hit and diagnosed on our own multitenant instances.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

gbathree created an issue. See original summary.

peacog made their first commit to this issue’s fork.

peacog’s picture

Thanks @gbathree, this looks good. I made a couple of small changes, removing a redundant load of the user entity and replacing where('1 = 0') with the more descriptive alwaysFalse() wrapper.

peacog’s picture

Title: `log_access query alter joins log__equipment unconditionally — fails on installs without the equipment field` » The log_access query alter joins log__equipment unconditionally, so fails on installs without the equipment field

  • peacog committed b6323ba3 on 2.0.x authored by gbathree
    Issue #3612338: only join log reference tables whose field storage...
peacog’s picture

Status: Active » Reviewed & tested by the community
gbathree’s picture

Thanks @peacog!

peacog’s picture

Status: Reviewed & tested by the community » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.