Skip to content

Fix overlay bug with multiple field patches #3623

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Apr 11, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,16 @@ Map<DocumentKey, OverlayedDocument> getOverlayedDocuments(
return computeViews(docs, overlays, new HashSet<>());
}

/*Computes the local view for doc */
/**
* Computes the local view for the given documents.
*
* @param docs The documents to compute views for. It also has the base version of the documents.
* @param overlays The overlays that need to be applied to the given base version of the
* documents.
* @param existenceStateChanged A set of documents that might there existence states changed. This
* is used to determine if we need to re-calculate overlays from mutation queues.
* @return A map represents the local documents view.
*/
private Map<DocumentKey, OverlayedDocument> computeViews(
Map<DocumentKey, MutableDocument> docs,
Map<DocumentKey, Overlay> overlays,
Expand All @@ -161,7 +170,7 @@ private Map<DocumentKey, OverlayedDocument> computeViews(
&& (overlay == null || overlay.getMutation() instanceof PatchMutation)) {
recalculateDocuments.put(doc.getKey(), doc);
} else if (overlay != null) {
mutatedFields.put(doc.getKey(), overlay.getFieldMask());
mutatedFields.put(doc.getKey(), overlay.getMutation().getFieldMask());
overlay.getMutation().applyToLocalView(doc, null, Timestamp.now());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@

/** Represents a local view (overlay) of a document, and the fields that are locally mutated. */
public class OverlayedDocument {
private Document overlay;
private Document overlayedDocument;
private FieldMask mutatedFields;

OverlayedDocument(Document overlay, FieldMask mutatedFields) {
this.overlay = overlay;
OverlayedDocument(Document overlayedDocument, FieldMask mutatedFields) {
this.overlayedDocument = overlayedDocument;
this.mutatedFields = mutatedFields;
}

public Document getDocument() {
return overlay;
return overlayedDocument;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,9 @@ public void applyToRemoteDocument(MutableDocument document, MutationResult mutat

return previousMask;
}

@Override
public @Nullable FieldMask getFieldMask() {
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,12 @@ public abstract void applyToRemoteDocument(
public abstract @Nullable FieldMask applyToLocalView(
MutableDocument document, @Nullable FieldMask previousMask, Timestamp localWriteTime);

/**
* Returns a {@code FieldMask} representing the fields that will be changed by applying this
* mutation. Returns {@code null} if the mutation will overwrite the entire document.
*/
public abstract @Nullable FieldMask getFieldMask();

/** Helper for derived classes to implement .equals(). */
boolean hasSameKeyAndPrecondition(Mutation other) {
return key.equals(other.key) && precondition.equals(other.precondition);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,11 @@ public void applyToRemoteDocument(MutableDocument document, MutationBatchResult
}

/**
* Computes the local view of a document given all the mutations in this batch. Returns an {@link
* FieldMask} representing all the fields that are mutated.
* Computes the local view of a document given all the mutations in this batch.
*
* @param mutatedFields Fields that are already mutated before applying the current one.
* @return An {@link FieldMask} representing all the fields that are mutated.
*/
public FieldMask applyToLocalView(MutableDocument document) {
FieldMask mutatedFields = FieldMask.fromSet(new HashSet<>());
return applyToLocalView(document, mutatedFields);
}

public FieldMask applyToLocalView(MutableDocument document, @Nullable FieldMask mutatedFields) {
// First, apply the base state. This allows us to apply non-idempotent transform against a
// consistent set of values.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,4 @@ public static Overlay create(int largestBatchId, Mutation mutation) {
public DocumentKey getKey() {
return getMutation().getKey();
}

public FieldMask getFieldMask() {
return getMutation() instanceof PatchMutation
? ((PatchMutation) getMutation()).getMask()
: null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ public ObjectValue getValue() {
* Returns the mask to apply to {@link #getValue}, where only fields that are in both the
* fieldMask and the value will be updated.
*/
public FieldMask getMask() {
@Override
public FieldMask getFieldMask() {
return mask;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ public FieldMask applyToLocalView(
return null;
}

@Override
public @Nullable FieldMask getFieldMask() {
return null;
}

/** Returns the object value to use when setting the document. */
public ObjectValue getValue() {
return value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,9 @@ public FieldMask applyToLocalView(
MutableDocument document, @Nullable FieldMask previousMask, Timestamp localWriteTime) {
throw Assert.fail("VerifyMutation should only be used in Transactions.");
}

@Override
public @Nullable FieldMask getFieldMask() {
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ public com.google.firestore.v1.Write encodeMutation(Mutation mutation) {
builder.setUpdate(encodeDocument(mutation.getKey(), ((SetMutation) mutation).getValue()));
} else if (mutation instanceof PatchMutation) {
builder.setUpdate(encodeDocument(mutation.getKey(), ((PatchMutation) mutation).getValue()));
builder.setUpdateMask(encodeDocumentMask(((PatchMutation) mutation).getMask()));
builder.setUpdateMask(encodeDocumentMask(((PatchMutation) mutation).getFieldMask()));
} else if (mutation instanceof DeleteMutation) {
builder.setDelete(encodeKey(mutation.getKey()));
} else if (mutation instanceof VerifyMutation) {
Expand Down