Skip to content

Commit

Permalink
Merge pull request neos#4792 from kitsunet/task/less-dependent-restri…
Browse files Browse the repository at this point in the history
…ction-query

TASK: Make restrictionrelation less dependent subquery
  • Loading branch information
ahaeslich authored Dec 21, 2023
2 parents ad8f1cb + 953cc20 commit 3a1a77a
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ public function findNodeAggregateById(
->select('n.*, h.name, h.contentstreamid, h.dimensionspacepoint AS covereddimensionspacepoint, r.dimensionspacepointhash AS disableddimensionspacepointhash')
->from($this->tableNamePrefix . '_hierarchyrelation', 'h')
->innerJoin('h', $this->tableNamePrefix . '_node', 'n', 'n.relationanchorpoint = h.childnodeanchor')
->leftJoin('h', $this->tableNamePrefix . '_restrictionrelation', 'r', 'r.originnodeaggregateid = n.nodeaggregateid AND r.contentstreamid = h.contentstreamid AND r.affectednodeaggregateid = n.nodeaggregateid AND r.dimensionspacepointhash = h.dimensionspacepointhash')
->leftJoin('h', $this->tableNamePrefix . '_restrictionrelation', 'r', 'r.originnodeaggregateid = n.nodeaggregateid AND r.contentstreamid = :contentStreamId AND r.affectednodeaggregateid = n.nodeaggregateid AND r.dimensionspacepointhash = h.dimensionspacepointhash')
->where('n.nodeaggregateid = :nodeAggregateId')
->andWhere('h.contentstreamid = :contentStreamId')
->setParameters([
Expand All @@ -207,7 +207,7 @@ public function findParentNodeAggregates(
->innerJoin('pn', $this->tableNamePrefix . '_hierarchyrelation', 'ph', 'ph.childnodeanchor = pn.relationanchorpoint')
->innerJoin('pn', $this->tableNamePrefix . '_hierarchyrelation', 'ch', 'ch.parentnodeanchor = pn.relationanchorpoint')
->innerJoin('ch', $this->tableNamePrefix . '_node', 'cn', 'cn.relationanchorpoint = ch.childnodeanchor')
->leftJoin('ph', $this->tableNamePrefix . '_restrictionrelation', 'r', 'r.originnodeaggregateid = pn.nodeaggregateid AND r.contentstreamid = ph.contentstreamid AND r.affectednodeaggregateid = pn.nodeaggregateid AND r.dimensionspacepointhash = ph.dimensionspacepointhash')
->leftJoin('ph', $this->tableNamePrefix . '_restrictionrelation', 'r', 'r.originnodeaggregateid = pn.nodeaggregateid AND r.contentstreamid = :contentStreamId AND r.affectednodeaggregateid = pn.nodeaggregateid AND r.dimensionspacepointhash = ph.dimensionspacepointhash')
->where('cn.nodeaggregateid = :nodeAggregateId')
->andWhere('ph.contentstreamid = :contentStreamId')
->andWhere('ch.contentstreamid = :contentStreamId')
Expand Down Expand Up @@ -238,7 +238,7 @@ public function findParentNodeAggregateByChildOriginDimensionSpacePoint(
->select('n.*, h.name, h.contentstreamid, h.dimensionspacepoint AS covereddimensionspacepoint, r.dimensionspacepointhash AS disableddimensionspacepointhash')
->from($this->tableNamePrefix . '_node', 'n')
->innerJoin('n', $this->tableNamePrefix . '_hierarchyrelation', 'h', 'h.childnodeanchor = n.relationanchorpoint')
->leftJoin('h', $this->tableNamePrefix . '_restrictionrelation', 'r', 'r.originnodeaggregateid = n.nodeaggregateid AND r.contentstreamid = h.contentstreamid AND r.affectednodeaggregateid = n.nodeaggregateid AND r.dimensionspacepointhash = h.dimensionspacepointhash')
->leftJoin('h', $this->tableNamePrefix . '_restrictionrelation', 'r', 'r.originnodeaggregateid = n.nodeaggregateid AND r.contentstreamid = :contentStreamId AND r.affectednodeaggregateid = n.nodeaggregateid AND r.dimensionspacepointhash = h.dimensionspacepointhash')
->where('n.nodeaggregateid = (' . $subQueryBuilder->getSQL() . ')')
->andWhere('h.contentstreamid = :contentStreamId')
->setParameters([
Expand Down Expand Up @@ -374,7 +374,7 @@ private function buildChildNodeAggregateQuery(NodeAggregateId $parentNodeAggrega
->innerJoin('pn', $this->tableNamePrefix . '_hierarchyrelation', 'ph', 'ph.childnodeanchor = pn.relationanchorpoint')
->innerJoin('pn', $this->tableNamePrefix . '_hierarchyrelation', 'ch', 'ch.parentnodeanchor = pn.relationanchorpoint')
->innerJoin('ch', $this->tableNamePrefix . '_node', 'cn', 'cn.relationanchorpoint = ch.childnodeanchor')
->leftJoin('pn', $this->tableNamePrefix . '_restrictionrelation', 'r', 'r.originnodeaggregateid = pn.nodeaggregateid AND r.contentstreamid = ph.contentstreamid AND r.affectednodeaggregateid = pn.nodeaggregateid AND r.dimensionspacepointhash = ph.dimensionspacepointhash')
->leftJoin('pn', $this->tableNamePrefix . '_restrictionrelation', 'r', 'r.originnodeaggregateid = pn.nodeaggregateid AND r.contentstreamid = :contentStreamId AND r.affectednodeaggregateid = pn.nodeaggregateid AND r.dimensionspacepointhash = ph.dimensionspacepointhash')
->where('pn.nodeaggregateid = :parentNodeAggregateId')
->andWhere('ph.contentstreamid = :contentStreamId')
->andWhere('ch.contentstreamid = :contentStreamId')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ public function findNodeById(NodeAggregateId $nodeAggregateId): ?Node
->where('n.nodeaggregateid = :nodeAggregateId')->setParameter('nodeAggregateId', $nodeAggregateId->value)
->andWhere('h.contentstreamid = :contentStreamId')->setParameter('contentStreamId', $this->contentStreamId->value)
->andWhere('h.dimensionspacepointhash = :dimensionSpacePointHash')->setParameter('dimensionSpacePointHash', $this->dimensionSpacePoint->hash);
$this->addRestrictionRelationConstraints($queryBuilder);
$this->addRestrictionRelationConstraints($queryBuilder, 'n', 'h', ':contentStreamId', ':dimensionSpacePointHash');
return $this->fetchNode($queryBuilder);
}

Expand All @@ -190,7 +190,7 @@ public function findRootNodeByType(NodeTypeName $nodeTypeName): ?Node
->andWhere('h.dimensionspacepointhash = :dimensionSpacePointHash')->setParameter('dimensionSpacePointHash', $this->dimensionSpacePoint->hash)
->andWhere('n.classification = :nodeAggregateClassification')
->setParameter('nodeAggregateClassification', NodeAggregateClassification::CLASSIFICATION_ROOT->value);
$this->addRestrictionRelationConstraints($queryBuilder);
$this->addRestrictionRelationConstraints($queryBuilder, 'n', 'h', ':contentStreamId', ':dimensionSpacePointHash');
return $this->fetchNode($queryBuilder);
}

Expand All @@ -207,7 +207,7 @@ public function findParentNode(NodeAggregateId $childNodeAggregateId): ?Node
->andWhere('ch.contentstreamid = :contentStreamId')
->andWhere('ph.dimensionspacepointhash = :dimensionSpacePointHash')->setParameter('dimensionSpacePointHash', $this->dimensionSpacePoint->hash)
->andWhere('ch.dimensionspacepointhash = :dimensionSpacePointHash');
$this->addRestrictionRelationConstraints($queryBuilder, 'cn', 'ch');
$this->addRestrictionRelationConstraints($queryBuilder, 'cn', 'ch', ':contentStreamId', ':dimensionSpacePointHash');
return $this->fetchNode($queryBuilder);
}

Expand Down Expand Up @@ -247,7 +247,7 @@ private function findChildNodeConnectedThroughEdgeName(NodeAggregateId $parentNo
->andWhere('h.contentstreamid = :contentStreamId')->setParameter('contentStreamId', $this->contentStreamId->value)
->andWhere('h.dimensionspacepointhash = :dimensionSpacePointHash')->setParameter('dimensionSpacePointHash', $this->dimensionSpacePoint->hash)
->andWhere('h.name = :edgeName')->setParameter('edgeName', $nodeName->value);
$this->addRestrictionRelationConstraints($queryBuilder, 'cn');
$this->addRestrictionRelationConstraints($queryBuilder, 'cn', 'h', ':contentStreamId', ':dimensionSpacePointHash');
return $this->fetchNode($queryBuilder);
}

Expand Down Expand Up @@ -296,7 +296,7 @@ public function findSubtree(NodeAggregateId $entryNodeAggregateId, FindSubtreeFi
->where('h.contentstreamid = :contentStreamId')
->andWhere('h.dimensionspacepointhash = :dimensionSpacePointHash')
->andWhere('n.nodeaggregateid = :entryNodeAggregateId');
$this->addRestrictionRelationConstraints($queryBuilderInitial);
$this->addRestrictionRelationConstraints($queryBuilderInitial, 'n', 'h', ':contentStreamId', ':dimensionSpacePointHash');

$queryBuilderRecursive = $this->createQueryBuilder()
->select('c.*, h.name, h.contentstreamid, p.nodeaggregateid AS parentNodeAggregateId, p.level + 1 AS level, h.position')
Expand All @@ -311,7 +311,7 @@ public function findSubtree(NodeAggregateId $entryNodeAggregateId, FindSubtreeFi
if ($filter->nodeTypes !== null) {
$this->addNodeTypeCriteria($queryBuilderRecursive, $filter->nodeTypes, 'c');
}
$this->addRestrictionRelationConstraints($queryBuilderRecursive, 'c');
$this->addRestrictionRelationConstraints($queryBuilderRecursive, 'c', 'h', ':contentStreamId', ':dimensionSpacePointHash');

$queryBuilderCte = $this->createQueryBuilder()
->select('*')
Expand Down Expand Up @@ -388,7 +388,7 @@ public function findClosestNode(NodeAggregateId $entryNodeAggregateId, FindClose
->andWhere('ph.contentstreamid = :contentStreamId')
->andWhere('ph.dimensionspacepointhash = :dimensionSpacePointHash')
->andWhere('n.nodeaggregateid = :entryNodeAggregateId');
$this->addRestrictionRelationConstraints($queryBuilderInitial, 'n', 'ph');
$this->addRestrictionRelationConstraints($queryBuilderInitial, 'n', 'ph', ':contentStreamId', ':dimensionSpacePointHash');

$queryBuilderRecursive = $this->createQueryBuilder()
->select('p.*, h.name, h.contentstreamid, h.parentnodeanchor')
Expand All @@ -397,7 +397,7 @@ public function findClosestNode(NodeAggregateId $entryNodeAggregateId, FindClose
->innerJoin('p', $this->tableNamePrefix . '_hierarchyrelation', 'h', 'h.childnodeanchor = p.relationanchorpoint')
->where('h.contentstreamid = :contentStreamId')
->andWhere('h.dimensionspacepointhash = :dimensionSpacePointHash');
$this->addRestrictionRelationConstraints($queryBuilderRecursive, 'p');
$this->addRestrictionRelationConstraints($queryBuilderRecursive, 'p', 'h', ':contentStreamId', ':dimensionSpacePointHash');

$queryBuilderCte = $this->createQueryBuilder()
->select('*')
Expand Down Expand Up @@ -497,18 +497,32 @@ private function createUniqueParameterName(): string
return 'param_' . (++$this->dynamicParameterCount);
}

private function addRestrictionRelationConstraints(QueryBuilder $queryBuilder, string $nodeTableAlias = 'n', string $hierarchyRelationTableAlias = 'h'): void
/**
* @param QueryBuilder $queryBuilder
* @param string $nodeTableAlias
* @param string $hierarchyRelationTableAlias
* @param string|null $contentStreamIdParameter if not given, condition will be on the hierachy relation content stream id
* @param string|null $dimensionspacePointHashParameter if not given, condition will be on the hierachy relation dimension space point hash
* @return void
*/
private function addRestrictionRelationConstraints(QueryBuilder $queryBuilder, string $nodeTableAlias = 'n', string $hierarchyRelationTableAlias = 'h', ?string $contentStreamIdParameter = null, ?string $dimensionspacePointHashParameter = null): void
{
if ($this->visibilityConstraints->isDisabledContentShown()) {
return;
}

$nodeTablePrefix = $nodeTableAlias === '' ? '' : $nodeTableAlias . '.';
$hierarchyRelationTablePrefix = $hierarchyRelationTableAlias === '' ? '' : $hierarchyRelationTableAlias . '.';

$contentStreamIdCondition = 'r.contentstreamid = ' . ($contentStreamIdParameter ?? ($hierarchyRelationTablePrefix . 'contentstreamid'));

$dimensionspacePointHashCondition = 'r.dimensionspacepointhash = ' . ($dimensionspacePointHashParameter ?? ($hierarchyRelationTablePrefix . 'dimensionspacepointhash'));

$subQueryBuilder = $this->createQueryBuilder()
->select('1')
->from($this->tableNamePrefix . '_restrictionrelation', 'r')
->where('r.contentstreamid = ' . $hierarchyRelationTablePrefix . 'contentstreamid')
->andWhere('r.dimensionspacepointhash = ' . $hierarchyRelationTablePrefix . 'dimensionspacepointhash')
->where($contentStreamIdCondition)
->andWhere($dimensionspacePointHashCondition)
->andWhere('r.affectednodeaggregateid = ' . $nodeTablePrefix . 'nodeaggregateid');
$queryBuilder->andWhere(
'NOT EXISTS (' . $subQueryBuilder->getSQL() . ')'
Expand Down Expand Up @@ -626,7 +640,7 @@ private function buildChildNodesQuery(NodeAggregateId $parentNodeAggregateId, Fi
if ($filter->propertyValue !== null) {
$this->addPropertyValueConstraints($queryBuilder, $filter->propertyValue);
}
$this->addRestrictionRelationConstraints($queryBuilder);
$this->addRestrictionRelationConstraints($queryBuilder, 'n', 'h', ':contentStreamId', ':dimensionSpacePointHash');
return $queryBuilder;
}

Expand All @@ -646,8 +660,8 @@ private function buildReferencesQuery(bool $backReferences, NodeAggregateId $nod
->andWhere('sh.dimensionspacepointhash = :dimensionSpacePointHash')
->andWhere('dh.contentstreamid = :contentStreamId')->setParameter('contentStreamId', $this->contentStreamId->value)
->andWhere('sh.contentstreamid = :contentStreamId');
$this->addRestrictionRelationConstraints($queryBuilder, 'dn', 'dh');
$this->addRestrictionRelationConstraints($queryBuilder, 'sn', 'sh');
$this->addRestrictionRelationConstraints($queryBuilder, 'dn', 'dh', ':contentStreamId', ':dimensionSpacePointHash');
$this->addRestrictionRelationConstraints($queryBuilder, 'sn', 'sh', ':contentStreamId', ':dimensionSpacePointHash');
if ($filter->nodeTypes !== null) {
$this->addNodeTypeCriteria($queryBuilder, $filter->nodeTypes, "{$destinationTablePrefix}n");
}
Expand Down Expand Up @@ -713,7 +727,7 @@ private function buildSiblingsQuery(bool $preceding, NodeAggregateId $siblingNod
->andWhere('h.position ' . ($preceding ? '<' : '>') . ' (' . $siblingPositionSubQuery->getSQL() . ')')
->orderBy('h.position', $preceding ? 'DESC' : 'ASC');

$this->addRestrictionRelationConstraints($queryBuilder);
$this->addRestrictionRelationConstraints($queryBuilder, 'n', 'h', ':contentStreamId', ':dimensionSpacePointHash');
if ($filter->nodeTypes !== null) {
$this->addNodeTypeCriteria($queryBuilder, $filter->nodeTypes);
}
Expand Down Expand Up @@ -746,8 +760,8 @@ private function buildAncestorNodesQueries(NodeAggregateId $entryNodeAggregateId
->andWhere('ph.contentstreamid = :contentStreamId')
->andWhere('ph.dimensionspacepointhash = :dimensionSpacePointHash')
->andWhere('c.nodeaggregateid = :entryNodeAggregateId');
$this->addRestrictionRelationConstraints($queryBuilderInitial, 'n', 'ph');
$this->addRestrictionRelationConstraints($queryBuilderInitial, 'c', 'ch');
$this->addRestrictionRelationConstraints($queryBuilderInitial, 'n', 'ph', ':contentStreamId', ':dimensionSpacePointHash');
$this->addRestrictionRelationConstraints($queryBuilderInitial, 'c', 'ch', ':contentStreamId', ':dimensionSpacePointHash');

$queryBuilderRecursive = $this->createQueryBuilder()
->select('p.*, h.name, h.contentstreamid, h.parentnodeanchor')
Expand All @@ -756,7 +770,7 @@ private function buildAncestorNodesQueries(NodeAggregateId $entryNodeAggregateId
->innerJoin('p', $this->tableNamePrefix . '_hierarchyrelation', 'h', 'h.childnodeanchor = p.relationanchorpoint')
->where('h.contentstreamid = :contentStreamId')
->andWhere('h.dimensionspacepointhash = :dimensionSpacePointHash');
$this->addRestrictionRelationConstraints($queryBuilderRecursive, 'p');
$this->addRestrictionRelationConstraints($queryBuilderRecursive, 'p', 'h', ':contentStreamId', ':dimensionSpacePointHash');

$queryBuilderCte = $this->createQueryBuilder()
->select('*')
Expand Down Expand Up @@ -788,7 +802,7 @@ private function buildDescendantNodesQueries(NodeAggregateId $entryNodeAggregate
->andWhere('ph.contentstreamid = :contentStreamId')
->andWhere('ph.dimensionspacepointhash = :dimensionSpacePointHash')
->andWhere('p.nodeaggregateid = :entryNodeAggregateId');
$this->addRestrictionRelationConstraints($queryBuilderInitial);
$this->addRestrictionRelationConstraints($queryBuilderInitial, 'n', 'h', ':contentStreamId', ':dimensionSpacePointHash');

$queryBuilderRecursive = $this->createQueryBuilder()
->select('c.*, h.name, h.contentstreamid, p.nodeaggregateid AS parentNodeAggregateId, p.level + 1 AS level, h.position')
Expand All @@ -797,7 +811,7 @@ private function buildDescendantNodesQueries(NodeAggregateId $entryNodeAggregate
->innerJoin('p', $this->tableNamePrefix . '_node', 'c', 'c.relationanchorpoint = h.childnodeanchor')
->where('h.contentstreamid = :contentStreamId')
->andWhere('h.dimensionspacepointhash = :dimensionSpacePointHash');
$this->addRestrictionRelationConstraints($queryBuilderRecursive, 'c');
$this->addRestrictionRelationConstraints($queryBuilderRecursive, 'c', 'h', ':contentStreamId', ':dimensionSpacePointHash');

$queryBuilderCte = $this->createQueryBuilder()
->select('*')
Expand Down

0 comments on commit 3a1a77a

Please sign in to comment.