Skip to content

Commit 455da70

Browse files
committed
Fix tenant-per-document in SQL race reconciliation and deferred relationship keys
1 parent 242c9a8 commit 455da70

2 files changed

Lines changed: 36 additions & 13 deletions

File tree

src/Database/Adapter/SQL.php

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2677,12 +2677,27 @@ public function createDocuments(Document $collection, array $documents, bool $ig
26772677
}
26782678

26792679
$tenantWhere = '';
2680+
$tenantSelect = '';
26802681
if ($this->sharedTables) {
2681-
$tenantWhere = ' AND _tenant = :_vfy_tenant';
2682-
$verifyBinds[':_vfy_tenant'] = $this->getTenant();
2682+
if ($this->tenantPerDocument) {
2683+
$tenants = \array_values(\array_unique(\array_filter(
2684+
\array_map(fn (Document $doc) => $doc->getTenant(), $documents)
2685+
)));
2686+
$tenantPlaceholders = [];
2687+
foreach ($tenants as $j => $tenant) {
2688+
$tKey = ':_vfy_tenant_' . $j;
2689+
$tenantPlaceholders[] = $tKey;
2690+
$verifyBinds[$tKey] = $tenant;
2691+
}
2692+
$tenantWhere = ' AND _tenant IN (' . \implode(', ', $tenantPlaceholders) . ')';
2693+
$tenantSelect = ', _tenant';
2694+
} else {
2695+
$tenantWhere = ' AND _tenant = :_vfy_tenant';
2696+
$verifyBinds[':_vfy_tenant'] = $this->getTenant();
2697+
}
26832698
}
26842699

2685-
$verifySql = 'SELECT _uid, ' . $this->quote($this->filter('_createdAt'))
2700+
$verifySql = 'SELECT _uid' . $tenantSelect . ', ' . $this->quote($this->filter('_createdAt'))
26862701
. ' FROM ' . $this->getSQLTable($name)
26872702
. ' WHERE _uid IN (' . \implode(', ', $verifyPlaceholders) . ')'
26882703
. $tenantWhere;
@@ -2698,16 +2713,19 @@ public function createDocuments(Document $collection, array $documents, bool $ig
26982713
// Keep only docs whose _createdAt matches what we set (= ours, not racer's)
26992714
$actualTimestamps = [];
27002715
foreach ($rows as $row) {
2701-
$actualTimestamps[$row['_uid']] = $row['_createdAt'];
2716+
$key = ($this->sharedTables && $this->tenantPerDocument)
2717+
? $row['_tenant'] . ':' . $row['_uid']
2718+
: $row['_uid'];
2719+
$actualTimestamps[$key] = $row['_createdAt'];
27022720
}
27032721

27042722
$insertedDocs = [];
2705-
$insertedUids = [];
27062723
foreach ($documents as $doc) {
2707-
$uid = $doc->getId();
2708-
if (isset($actualTimestamps[$uid]) && $actualTimestamps[$uid] === $expectedTimestamps[$uid]) {
2724+
$key = ($this->sharedTables && $this->tenantPerDocument)
2725+
? $doc->getTenant() . ':' . $doc->getId()
2726+
: $doc->getId();
2727+
if (isset($actualTimestamps[$key]) && $actualTimestamps[$key] === $expectedTimestamps[$doc->getId()]) {
27092728
$insertedDocs[] = $doc;
2710-
$insertedUids[$uid] = true;
27112729
}
27122730
}
27132731
$documents = $insertedDocs;

src/Database/Database.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5786,7 +5786,10 @@ public function createDocuments(
57865786
$document->removeAttribute($key);
57875787
}
57885788
if (!empty($relationshipData)) {
5789-
$deferredRelationships[$document->getId()] = $relationshipData;
5789+
$deferKey = $tenantPerDocument
5790+
? $document->getTenant() . ':' . $document->getId()
5791+
: $document->getId();
5792+
$deferredRelationships[$deferKey] = $relationshipData;
57905793
}
57915794
} elseif ($this->resolveRelationships) {
57925795
$preExistKey = $tenantPerDocument
@@ -5821,14 +5824,16 @@ public function createDocuments(
58215824
// In ignore mode, create relationships only for docs actually inserted
58225825
if ($ignore && $this->resolveRelationships && \count($deferredRelationships) > 0) {
58235826
foreach ($batch as $insertedDoc) {
5824-
$docId = $insertedDoc->getId();
5825-
if (\array_key_exists($docId, $deferredRelationships)) {
5827+
$deferKey = $tenantPerDocument
5828+
? $insertedDoc->getTenant() . ':' . $insertedDoc->getId()
5829+
: $insertedDoc->getId();
5830+
if (\array_key_exists($deferKey, $deferredRelationships)) {
58265831
$relDoc = clone $insertedDoc;
5827-
foreach ($deferredRelationships[$docId] as $key => $value) {
5832+
foreach ($deferredRelationships[$deferKey] as $key => $value) {
58285833
$relDoc->setAttribute($key, $value);
58295834
}
58305835
$this->silent(fn () => $this->createDocumentRelationships($collection, $relDoc));
5831-
unset($deferredRelationships[$docId]);
5836+
unset($deferredRelationships[$deferKey]);
58325837
}
58335838
}
58345839
}

0 commit comments

Comments
 (0)