From b23525c2b41263b82c9dc9f187600336ec451528 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Mon, 20 Jan 2025 14:19:54 +1300 Subject: [PATCH 1/3] Only query tenant is null against metadata --- src/Database/Adapter.php | 8 ++++ src/Database/Adapter/MariaDB.php | 65 +++++++++++++--------------- src/Database/Adapter/Mongo.php | 5 +++ src/Database/Adapter/Postgres.php | 71 ++++++++++++++++--------------- src/Database/Adapter/SQL.php | 33 +++++++++----- src/Database/Adapter/SQLite.php | 15 ++----- 6 files changed, 104 insertions(+), 93 deletions(-) diff --git a/src/Database/Adapter.php b/src/Database/Adapter.php index a21ce60be..e088b0b40 100644 --- a/src/Database/Adapter.php +++ b/src/Database/Adapter.php @@ -1045,4 +1045,12 @@ abstract public function getInternalIndexesKeys(): array; * @throws DatabaseException */ abstract public function getSchemaAttributes(string $collection): array; + + /** + * Get the query to check for tenant when in shared tables mode + * + * @param string $collection + * @return string + */ + abstract public function getTenantQuery(string $collection, string $alias = ''): string; } diff --git a/src/Database/Adapter/MariaDB.php b/src/Database/Adapter/MariaDB.php index 45d12e6fd..01704db19 100644 --- a/src/Database/Adapter/MariaDB.php +++ b/src/Database/Adapter/MariaDB.php @@ -1123,12 +1123,9 @@ public function updateDocument(string $collection, string $id, Document $documen SELECT _type, _permission FROM {$this->getSQLTable($name . '_perms')} WHERE _document = :_uid + {$this->getTenantQuery($collection)} "; - if ($this->sharedTables) { - $sql .= ' AND (_tenant = :_tenant OR _tenant IS NULL)'; - } - $sql = $this->trigger(Database::EVENT_PERMISSIONS_READ, $sql); /** @@ -1200,12 +1197,9 @@ public function updateDocument(string $collection, string $id, Document $documen DELETE FROM {$this->getSQLTable($name . '_perms')} WHERE _document = :_uid + {$this->getTenantQuery($collection)} "; - if ($this->sharedTables) { - $sql .= ' AND (_tenant = :_tenant OR _tenant IS NULL)'; - } - $removeQuery = $sql . $removeQuery; $removeQuery = $this->trigger(Database::EVENT_PERMISSIONS_DELETE, $removeQuery); @@ -1287,12 +1281,9 @@ public function updateDocument(string $collection, string $id, Document $documen UPDATE {$this->getSQLTable($name)} SET {$columns} _uid = :_newUid WHERE _uid = :_existingUid + {$this->getTenantQuery($collection)} "; - if ($this->sharedTables) { - $sql .= ' AND (_tenant = :_tenant OR _tenant IS NULL)'; - } - $sql = $this->trigger(Database::EVENT_DOCUMENT_UPDATE, $sql); $stmt = $this->getPDO()->prepare($sql); @@ -1436,12 +1427,9 @@ public function updateDocuments(string $collection, Document $updates, array $do SELECT _type, _permission FROM {$this->getSQLTable($name . '_perms')} WHERE _document = :_uid + {$this->getTenantQuery($collection)} "; - if ($this->sharedTables) { - $sql .= ' AND (_tenant = :_tenant OR _tenant IS NULL)'; - } - $sql = $this->trigger(Database::EVENT_PERMISSIONS_READ, $sql); $permissionsStmt = $this->getPDO()->prepare($sql); @@ -1481,14 +1469,9 @@ public function updateDocuments(string $collection, Document $updates, array $do $removeBindKeys[] = ':uid_' . $index; $removeBindValues[$bindKey] = $document->getId(); - $tenantQuery = ''; - if ($this->sharedTables) { - $tenantQuery = ' AND (_tenant = :_tenant OR _tenant IS NULL)'; - } - $removeQueries[] = "( _document = :uid_{$index} - {$tenantQuery} + {$this->getTenantQuery($collection)} AND _type = '{$type}' AND _permission IN (" . \implode(', ', \array_map(function (string $i) use ($permissionsToRemove, $index, $type, &$removeBindKeys, &$removeBindValues) { $bindKey = 'remove_' . $type . '_' . $index . '_' . $i; @@ -1616,11 +1599,9 @@ public function increaseDocumentAttribute(string $collection, string $id, string `{$attribute}` = `{$attribute}` + :val, `_updatedAt` = :updatedAt WHERE _uid = :_uid + {$this->getTenantQuery($collection)} "; - if ($this->sharedTables) { - $sql .= ' AND (_tenant = :_tenant OR _tenant IS NULL)'; - } $sql .= $sqlMax . $sqlMin; @@ -1656,12 +1637,9 @@ public function deleteDocument(string $collection, string $id): bool $sql = " DELETE FROM {$this->getSQLTable($name)} WHERE _uid = :_uid + {$this->getTenantQuery($collection)} "; - if ($this->sharedTables) { - $sql .= ' AND (_tenant = :_tenant OR _tenant IS NULL)'; - } - $sql = $this->trigger(Database::EVENT_DOCUMENT_DELETE, $sql); $stmt = $this->getPDO()->prepare($sql); @@ -1675,12 +1653,9 @@ public function deleteDocument(string $collection, string $id): bool $sql = " DELETE FROM {$this->getSQLTable($name . '_perms')} WHERE _document = :_uid + {$this->getTenantQuery($collection)} "; - if ($this->sharedTables) { - $sql .= ' AND (_tenant = :_tenant OR _tenant IS NULL)'; - } - $sql = $this->trigger(Database::EVENT_PERMISSIONS_DELETE, $sql); $stmtPermissions = $this->getPDO()->prepare($sql); @@ -1886,7 +1861,13 @@ public function find(string $collection, array $queries = [], ?int $limit = 25, } if ($this->sharedTables) { - $where[] = "(table_main._tenant = :_tenant OR table_main._tenant IS NULL)"; + $whereTenant = "(table_main._tenant = :_tenant"; + + if ($collection === Database::METADATA) { + $whereTenant .= " OR table_main._tenant IS NULL"; + } + + $where[] = $whereTenant . ')'; } $sqlWhere = !empty($where) ? 'WHERE ' . implode(' AND ', $where) : ''; @@ -2014,7 +1995,13 @@ public function count(string $collection, array $queries = [], ?int $max = null) } if ($this->sharedTables) { - $where[] = "(table_main._tenant = :_tenant OR table_main._tenant IS NULL)"; + $whereTenant = "(table_main._tenant = :_tenant"; + + if ($collection === Database::METADATA) { + $whereTenant .= " OR table_main._tenant IS NULL"; + } + + $where[] = $whereTenant . ')'; } $sqlWhere = !empty($where) @@ -2086,7 +2073,13 @@ public function sum(string $collection, string $attribute, array $queries = [], } if ($this->sharedTables) { - $where[] = "(table_main._tenant = :_tenant OR table_main._tenant IS NULL)"; + $whereTenant = "(table_main._tenant = :_tenant"; + + if ($collection === Database::METADATA) { + $whereTenant .= " OR table_main._tenant IS NULL"; + } + + $where[] = $whereTenant . ')'; } $sqlWhere = !empty($where) diff --git a/src/Database/Adapter/Mongo.php b/src/Database/Adapter/Mongo.php index 5df46e28e..f5d980ef7 100644 --- a/src/Database/Adapter/Mongo.php +++ b/src/Database/Adapter/Mongo.php @@ -798,6 +798,7 @@ private function insertDocument(string $name, array $document): array $filters = []; $filters['_uid'] = $document['_uid']; + if ($this->sharedTables) { $filters['_tenant'] = (string)$this->getTenant(); } @@ -1963,4 +1964,8 @@ public function getSchemaAttributes(string $collection): array return []; } + public function getTenantQuery(string $collection, string $alias = ''): string + { + return (string)$this->getTenant(); + } } diff --git a/src/Database/Adapter/Postgres.php b/src/Database/Adapter/Postgres.php index b55365961..8855c0b40 100644 --- a/src/Database/Adapter/Postgres.php +++ b/src/Database/Adapter/Postgres.php @@ -1161,12 +1161,9 @@ public function updateDocument(string $collection, string $id, Document $documen SELECT _type, _permission FROM {$this->getSQLTable($name . '_perms')} WHERE _document = :_uid + {$this->getTenantQuery($collection)} "; - if ($this->sharedTables) { - $sql .= ' AND (_tenant = :_tenant OR _tenant IS NULL)'; - } - $sql = $this->trigger(Database::EVENT_PERMISSIONS_READ, $sql); /** @@ -1239,12 +1236,9 @@ public function updateDocument(string $collection, string $id, Document $documen DELETE FROM {$this->getSQLTable($name . '_perms')} WHERE _document = :_uid + {$this->getTenantQuery($collection)} "; - if ($this->sharedTables) { - $sql .= ' AND (_tenant = :_tenant OR _tenant IS NULL)'; - } - $removeQuery = $sql . $removeQuery; $removeQuery = $this->trigger(Database::EVENT_PERMISSIONS_DELETE, $removeQuery); @@ -1311,12 +1305,9 @@ public function updateDocument(string $collection, string $id, Document $documen UPDATE {$this->getSQLTable($name)} SET {$columns} _uid = :_newUid WHERE _uid = :_existingUid + {$this->getTenantQuery($collection)} "; - if ($this->sharedTables) { - $sql .= ' AND (_tenant = :_tenant OR _tenant IS NULL)'; - } - $sql = $this->trigger(Database::EVENT_DOCUMENT_UPDATE, $sql); $stmt = $this->getPDO()->prepare($sql); @@ -1395,7 +1386,13 @@ public function updateDocuments(string $collection, Document $updates, array $do $where[] = "_uid IN (" . \implode(', ', \array_map(fn ($index) => ":_id_{$index}", \array_keys($ids))) . ")"; if ($this->sharedTables) { - $where[] = "(_tenant = :_tenant OR _tenant IS NULL)"; + $whereTenant = "(_tenant = :_tenant"; + + if ($collection === Database::METADATA) { + $whereTenant .= " OR _tenant IS NULL"; + } + + $where[] = $whereTenant . ')'; } $sqlWhere = 'WHERE ' . implode(' AND ', $where); @@ -1504,14 +1501,9 @@ public function updateDocuments(string $collection, Document $updates, array $do $removeBindKeys[] = ':uid_' . $index; $removeBindValues[$bindKey] = $document->getId(); - $tenantQuery = ''; - if ($this->sharedTables) { - $tenantQuery = ' AND (_tenant = :_tenant OR _tenant IS NULL)'; - } - $removeQueries[] = "( _document = :uid_{$index} - {$tenantQuery} + {$this->getTenantQuery($collection)} AND _type = '{$type}' AND _permission IN (" . \implode(', ', \array_map(function (string $i) use ($permissionsToRemove, $index, $type, &$removeBindKeys, &$removeBindValues) { $bindKey = 'remove_' . $type . '_' . $index . '_' . $i; @@ -1638,13 +1630,10 @@ public function increaseDocumentAttribute(string $collection, string $id, string SET \"{$attribute}\" = \"{$attribute}\" + :val, \"_updatedAt\" = :updatedAt - WHERE _uid = :_uid + WHERE _uid = :_uid + {$this->getTenantQuery($collection)} "; - if ($this->sharedTables) { - $sql .= ' AND (_tenant = :_tenant OR _tenant IS NULL)'; - } - $sql .= $sqlMax . $sqlMin; $sql = $this->trigger(Database::EVENT_DOCUMENT_UPDATE, $sql); @@ -1677,12 +1666,9 @@ public function deleteDocument(string $collection, string $id): bool $sql = " DELETE FROM {$this->getSQLTable($name)} WHERE _uid = :_uid + {$this->getTenantQuery($collection)} "; - if ($this->sharedTables) { - $sql .= ' AND (_tenant = :_tenant OR _tenant IS NULL)'; - } - $sql = $this->trigger(Database::EVENT_DOCUMENT_DELETE, $sql); $stmt = $this->getPDO()->prepare($sql); $stmt->bindValue(':_uid', $id, PDO::PARAM_STR); @@ -1694,12 +1680,9 @@ public function deleteDocument(string $collection, string $id): bool $sql = " DELETE FROM {$this->getSQLTable($name . '_perms')} WHERE _document = :_uid + {$this->getTenantQuery($collection)} "; - if ($this->sharedTables) { - $sql .= ' AND (_tenant = :_tenant OR _tenant IS NULL)'; - } - $sql = $this->trigger(Database::EVENT_PERMISSIONS_DELETE, $sql); $stmtPermissions = $this->getPDO()->prepare($sql); @@ -1903,7 +1886,13 @@ public function find(string $collection, array $queries = [], ?int $limit = 25, } if ($this->sharedTables) { - $where[] = "(table_main._tenant = :_tenant OR table_main._tenant IS NULL)"; + $whereTenant = "(table_main._tenant = :_tenant"; + + if ($collection === Database::METADATA) { + $whereTenant .= " OR table_main._tenant IS NULL"; + } + + $where[] = $whereTenant . ')'; } if (Authorization::$status) { @@ -2031,7 +2020,13 @@ public function count(string $collection, array $queries = [], ?int $max = null) } if ($this->sharedTables) { - $where[] = "(table_main._tenant = :_tenant OR table_main._tenant IS NULL)"; + $whereTenant = "(table_main._tenant = :_tenant"; + + if ($collection === Database::METADATA) { + $whereTenant .= " OR table_main._tenant IS NULL"; + } + + $where[] = $whereTenant . ')'; } if (Authorization::$status) { @@ -2096,7 +2091,13 @@ public function sum(string $collection, string $attribute, array $queries = [], } if ($this->sharedTables) { - $where[] = "(table_main._tenant = :_tenant OR table_main._tenant IS NULL)"; + $whereTenant = "(table_main._tenant = :_tenant"; + + if ($collection === Database::METADATA) { + $whereTenant .= " OR table_main._tenant IS NULL"; + } + + $where[] = $whereTenant . ')'; } if (Authorization::$status) { diff --git a/src/Database/Adapter/SQL.php b/src/Database/Adapter/SQL.php index e5bcda7c1..5b829c8e4 100644 --- a/src/Database/Adapter/SQL.php +++ b/src/Database/Adapter/SQL.php @@ -216,12 +216,9 @@ public function getDocument(string $collection, string $id, array $queries = [], SELECT {$this->getAttributeProjection($selections)} FROM {$this->getSQLTable($name)} WHERE _uid = :_uid + {$this->getTenantQuery($collection)} "; - if ($this->sharedTables) { - $sql .= "AND (_tenant = :_tenant OR _tenant IS NULL)"; - } - if ($this->getSupportForUpdateLock()) { $sql .= " {$forUpdate}"; } @@ -1045,17 +1042,12 @@ protected function getSQLPermissionsCondition(string $collection, array $roles, $roles = array_map(fn (string $role) => $this->getPDO()->quote($role), $roles); - $tenantQuery = ''; - if ($this->sharedTables) { - $tenantQuery = 'AND (_tenant = :_tenant OR _tenant IS NULL)'; - } - return "table_main._uid IN ( SELECT _document FROM {$this->getSQLTable($collection . '_perms')} WHERE _permission IN (" . implode(', ', $roles) . ") AND _type = '{$type}' - {$tenantQuery} + {$this->getTenantQuery($collection)} )"; } @@ -1180,4 +1172,25 @@ public function getSchemaAttributes(string $collection): array { return []; } + + public function getTenantQuery(string $collection, string $alias = ''): string + { + if (!$this->sharedTables) { + return ''; + } + + if (!empty($alias) || $alias === '0') { + $alias .= '.'; + } + + $query = "AND ({$alias}_tenant = :_tenant"; + + if ($collection === Database::METADATA) { + $query .= " OR {$alias}_tenant IS NULL"; + } + + $query .= ")"; + + return $query; + } } diff --git a/src/Database/Adapter/SQLite.php b/src/Database/Adapter/SQLite.php index 07cad6999..8603a6cbb 100644 --- a/src/Database/Adapter/SQLite.php +++ b/src/Database/Adapter/SQLite.php @@ -660,12 +660,9 @@ public function updateDocument(string $collection, string $id, Document $documen SELECT _type, _permission FROM `{$this->getNamespace()}_{$name}_perms` WHERE _document = :_uid + {$this->getTenantQuery($collection)} "; - if ($this->sharedTables) { - $sql .= " AND (_tenant = :_tenant OR _tenant IS NULL)"; - } - $sql = $this->trigger(Database::EVENT_PERMISSIONS_READ, $sql); /** @@ -737,12 +734,9 @@ public function updateDocument(string $collection, string $id, Document $documen DELETE FROM `{$this->getNamespace()}_{$name}_perms` WHERE _document = :_uid + {$this->getTenantQuery($collection)} "; - if ($this->sharedTables) { - $sql .= " AND (_tenant = :_tenant OR _tenant IS NULL)"; - } - $removeQuery = $sql . $removeQuery; $removeQuery = $this->trigger(Database::EVENT_PERMISSIONS_DELETE, $removeQuery); @@ -809,12 +803,9 @@ public function updateDocument(string $collection, string $id, Document $documen UPDATE `{$this->getNamespace()}_{$name}` SET {$columns} _uid = :_newUid WHERE _uid = :_existingUid + {$this->getTenantQuery($collection)} "; - if ($this->sharedTables) { - $sql .= " AND (_tenant = :_tenant OR _tenant IS NULL)"; - } - $sql = $this->trigger(Database::EVENT_DOCUMENT_UPDATE, $sql); $stmt = $this->getPDO()->prepare($sql); From e8132e2bf91a9bde6501d49660d4b4cd6039afda Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Mon, 20 Jan 2025 14:36:01 +1300 Subject: [PATCH 2/3] Rename param --- src/Database/Adapter.php | 5 +++-- src/Database/Adapter/Mongo.php | 2 +- src/Database/Adapter/SQL.php | 20 ++++++++++---------- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/Database/Adapter.php b/src/Database/Adapter.php index e088b0b40..6bb7b9ae3 100644 --- a/src/Database/Adapter.php +++ b/src/Database/Adapter.php @@ -1049,8 +1049,9 @@ abstract public function getSchemaAttributes(string $collection): array; /** * Get the query to check for tenant when in shared tables mode * - * @param string $collection + * @param string $collection The collection being queried + * @param string $parentAlias The alias of the parent collection if in a subquery * @return string */ - abstract public function getTenantQuery(string $collection, string $alias = ''): string; + abstract public function getTenantQuery(string $collection, string $parentAlias = ''): string; } diff --git a/src/Database/Adapter/Mongo.php b/src/Database/Adapter/Mongo.php index f5d980ef7..b67db87ec 100644 --- a/src/Database/Adapter/Mongo.php +++ b/src/Database/Adapter/Mongo.php @@ -1964,7 +1964,7 @@ public function getSchemaAttributes(string $collection): array return []; } - public function getTenantQuery(string $collection, string $alias = ''): string + public function getTenantQuery(string $collection, string $parentAlias = ''): string { return (string)$this->getTenant(); } diff --git a/src/Database/Adapter/SQL.php b/src/Database/Adapter/SQL.php index 5b829c8e4..f731d8bdd 100644 --- a/src/Database/Adapter/SQL.php +++ b/src/Database/Adapter/SQL.php @@ -1163,34 +1163,34 @@ public function getInternalIndexesKeys(): array return []; } - protected function processException(PDOException $e): \Exception - { - return $e; - } - public function getSchemaAttributes(string $collection): array { return []; } - public function getTenantQuery(string $collection, string $alias = ''): string + public function getTenantQuery(string $collection, string $parentAlias = ''): string { if (!$this->sharedTables) { return ''; } - if (!empty($alias) || $alias === '0') { - $alias .= '.'; + if (!empty($parentAlias) || $parentAlias === '0') { + $parentAlias .= '.'; } - $query = "AND ({$alias}_tenant = :_tenant"; + $query = "AND ({$parentAlias}_tenant = :_tenant"; if ($collection === Database::METADATA) { - $query .= " OR {$alias}_tenant IS NULL"; + $query .= " OR {$parentAlias}_tenant IS NULL"; } $query .= ")"; return $query; } + + protected function processException(PDOException $e): \Exception + { + return $e; + } } From 8d76babb04ba92a9ec9904471813899d41b4d675 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Mon, 20 Jan 2025 22:14:18 +1300 Subject: [PATCH 3/3] Compose instead of concat --- src/Database/Adapter.php | 2 +- src/Database/Adapter/MariaDB.php | 18 +++++++++--------- src/Database/Adapter/Postgres.php | 18 +++++++++--------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/Database/Adapter.php b/src/Database/Adapter.php index 6bb7b9ae3..73535ea11 100644 --- a/src/Database/Adapter.php +++ b/src/Database/Adapter.php @@ -446,7 +446,7 @@ abstract public function createCollection(string $name, array $attributes = [], abstract public function deleteCollection(string $id): bool; /** - * Analyze a collection updating it's metadata on the database engine + * Analyze a collection updating its metadata on the database engine * * @param string $collection * @return bool diff --git a/src/Database/Adapter/MariaDB.php b/src/Database/Adapter/MariaDB.php index 01704db19..d4c15d032 100644 --- a/src/Database/Adapter/MariaDB.php +++ b/src/Database/Adapter/MariaDB.php @@ -1861,13 +1861,13 @@ public function find(string $collection, array $queries = [], ?int $limit = 25, } if ($this->sharedTables) { - $whereTenant = "(table_main._tenant = :_tenant"; + $orIsNull = ''; if ($collection === Database::METADATA) { - $whereTenant .= " OR table_main._tenant IS NULL"; + $orIsNull = " OR table_main._tenant IS NULL"; } - $where[] = $whereTenant . ')'; + $where[] = "(table_main._tenant = :_tenant {$orIsNull})"; } $sqlWhere = !empty($where) ? 'WHERE ' . implode(' AND ', $where) : ''; @@ -1995,13 +1995,13 @@ public function count(string $collection, array $queries = [], ?int $max = null) } if ($this->sharedTables) { - $whereTenant = "(table_main._tenant = :_tenant"; + $orIsNull = ''; if ($collection === Database::METADATA) { - $whereTenant .= " OR table_main._tenant IS NULL"; + $orIsNull = " OR table_main._tenant IS NULL"; } - $where[] = $whereTenant . ')'; + $where[] = "(table_main._tenant = :_tenant {$orIsNull})"; } $sqlWhere = !empty($where) @@ -2073,13 +2073,13 @@ public function sum(string $collection, string $attribute, array $queries = [], } if ($this->sharedTables) { - $whereTenant = "(table_main._tenant = :_tenant"; + $orIsNull = ''; if ($collection === Database::METADATA) { - $whereTenant .= " OR table_main._tenant IS NULL"; + $orIsNull = " OR table_main._tenant IS NULL"; } - $where[] = $whereTenant . ')'; + $where[] = "(table_main._tenant = :_tenant {$orIsNull})"; } $sqlWhere = !empty($where) diff --git a/src/Database/Adapter/Postgres.php b/src/Database/Adapter/Postgres.php index 8855c0b40..d808a82dc 100644 --- a/src/Database/Adapter/Postgres.php +++ b/src/Database/Adapter/Postgres.php @@ -1886,13 +1886,13 @@ public function find(string $collection, array $queries = [], ?int $limit = 25, } if ($this->sharedTables) { - $whereTenant = "(table_main._tenant = :_tenant"; + $orIsNull = ''; if ($collection === Database::METADATA) { - $whereTenant .= " OR table_main._tenant IS NULL"; + $orIsNull = " OR table_main._tenant IS NULL"; } - $where[] = $whereTenant . ')'; + $where[] = "(table_main._tenant = :_tenant {$orIsNull})"; } if (Authorization::$status) { @@ -2020,13 +2020,13 @@ public function count(string $collection, array $queries = [], ?int $max = null) } if ($this->sharedTables) { - $whereTenant = "(table_main._tenant = :_tenant"; + $orIsNull = ''; if ($collection === Database::METADATA) { - $whereTenant .= " OR table_main._tenant IS NULL"; + $orIsNull = " OR table_main._tenant IS NULL"; } - $where[] = $whereTenant . ')'; + $where[] = "(table_main._tenant = :_tenant {$orIsNull})"; } if (Authorization::$status) { @@ -2091,13 +2091,13 @@ public function sum(string $collection, string $attribute, array $queries = [], } if ($this->sharedTables) { - $whereTenant = "(table_main._tenant = :_tenant"; + $orIsNull = ''; if ($collection === Database::METADATA) { - $whereTenant .= " OR table_main._tenant IS NULL"; + $orIsNull = " OR table_main._tenant IS NULL"; } - $where[] = $whereTenant . ')'; + $where[] = "(table_main._tenant = :_tenant {$orIsNull})"; } if (Authorization::$status) {