@@ -0,0 +1,182 @@
1+# Automatic Merge Notes
3+These notes present cases where two diverging transaction branches can be automatically merged. Later, we cover transaction branches which cannot be automatically merged without user intervention (either in advance or in real-time).
5+In the following diagrams, "A" is the divergence point (parent) for two branches "B1" and "B2". "B1" and "B2" are subsequently merged to "C".
9+. Thus, the result C is equivalent to executing just one branch of changes.
53+## 4. Two transactions add/remove different tuples
55+ should discard all of a branches changes and not just the conflicted tuple changes.
93+### 5b. Perform some logic to determine how to merge conflicting tuple atoms
95+A stored procedure could determine which branch to choose or even how to merge values at the tuple or atom level. For example, the stored procedure could determine the "name" atom in the merged tuple result to be "Jim or James Garbez" (product) or "J. Garbez" (commonality) or even just "Garbez" (commonality) or the procedure could claim that the longer name is more likely to be correct.
97+In general, the stored procedure could inspect (reading only) the two branches in the tree and make any deterministic decision it wishes to make based solely on those branches (maintaining the purity of the function).
99+### 5c. Use the earlier/later changed
101+The chosen branch is determined by its commit timestamp. The other branch's changes are discarded entirely.
103+### 5d. Revert to shared ancestor
105+Due to ambiguity, the rule could be to revert to the parent ancestor state which is the first knwon consistent state prior to the branching.
107+### 6. User intervention
109+If none of the above strategies result in a non-constraint-violating merge transaction, then the merge must fail, perhaps marking some state for a human to intervene and take action (which may include no action).
113+## 1. Adding/removing a relation
115+![graph](http://g.gravizo.com/g?
119+A -> B1 [label="x:=true"];
120+A -> B2 [label="y:=true"];
121+B1 -> C [label="merge"];
122+B2 -> C [label="merge"];
123+C [label="C|x:=true and y:=true"];
127+If a relation has no cross-constraints with another relation, then adding either at any point in the timeline cannot interfere with the other.
129+## 2. Changing constraints
131+![graph](http://g.gravizo.com/g?
134+A [label="A|employee[id Int, name Text]|[[3, \"Jim Garbez\"]]"];
135+A -> B1 [label="+ key employee[id]"];
136+A -> B2 [label="+ key employee[name]"];
137+B1 -> C [label="merge"];
138+B2 -> C [label="merge"];
143+From all the examples, this is likely the most interesting since detecting when constraints conflict is not immediately obvious. Consider, for example, if A->B2 added a constraint "+ key employee[id,name]". This would not create a conflict under the conditions that both constraints can be added to the merge without causing a constraint violation, but is that the genuine intention of the user?
145+Consider this example:
147+![graph](http://g.gravizo.com/g?
150+A [label="A|integers[i Int]|[]"];
151+A -> B1 [label="+ constraint i<0"];
152+A -> B2 [label="+ constraint i>0"];
153+B1 -> C [label="merge"];
154+B2 -> C [label="merge"];
159+The end result is a relation "i" which cannot contain any tuples. Clearly, neither branch intended this to be the case, so does it make sense to merely concatenate the constraints?
163+The function to perform the merge should be of type:
166+mergeBranches :: TransactionGraph -> BranchName -> BranchName -> TransactionGraph
167+mergeBranches subGraph branchNameA branchNameB = ...
170+The subGraph argument is a subGraph of the entire database transaction graph starting at the common ancestor and including all transactions from both branches until the potential merge point. This is a sub graph because I have not been able to think of a circumstance where more context would be necessary. For convenience, the merge system should also include a transaction diff function of type:
173+diffTransactions :: Transaction -> Transaction -> DatabaseContextExpr
176+This function should make a best effort to compress the actual differences into as few actions as possible, though further research will likely discover a canonical representation. Specifically, when diff'ing two transaction in sequence, this function should hopefully return the minimal statements needed to get from one transaction state to the next. This diff function's result can then be analyzed by the merge function in its decision-making.
178+Each merge strategy can be implemented using separate functions of the above type, but deciding which to apply or which strategy should win automatically is likely an open research problem. Likely, this decision-making must be left up to the database developer who has the full context needed in order to make the decision.
180+In addition, it would seem valuable to the algorithms to determine which constraints would be violated without executing the action. Even if this were determinable some of the time, it would appear to be a valuable optimization.
182+The parallels between transaction merging and parallel lock management should not be underestimated. However, instead of critical sections, constraints appear to be able to represent additional complexity not usually attributed to locking.