Patchwork [4,of,7,V2] revset: forward ordering requirement to argument of present()

login
register
mail settings
Submitter Yuya Nishihara
Date June 3, 2016, 3:02 p.m.
Message ID <265d239157487116f20b.1464966147@mimosa>
Download mbox | patch
Permalink /patch/15375/
State Changes Requested
Delegated to: Augie Fackler
Headers show

Comments

Yuya Nishihara - June 3, 2016, 3:02 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1464782044 -32400
#      Wed Jun 01 20:54:04 2016 +0900
# Node ID 265d239157487116f20bb219a441ad0c55be26bb
# Parent  cdf3cd369a4e4f114b2ab555de1d3b30c8c3827a
revset: forward ordering requirement to argument of present()

present() is special in that it forwards the argument set with no modification.
We could handle this case by marking present() as "ordering" symbol, but we
have better option. This patch introduces new category "noop" to forward the
ordering requirement to arguments.

Patch

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -2087,6 +2087,12 @@  methods = {
     '_hexlist',
 ])
 
+# symbols which return the evaluated set with no modification. in other words,
+# functions that do 'return getset(repo, subset, x)'.
+_noopsymbols = set([
+    'present',
+])
+
 # constants for ordering policy, used in _optimize():
 # 1. starts with 'define'
 # 2. shifts to 'follow' by 'x & y'
@@ -2240,7 +2246,13 @@  def _optimize(x, small, order):
         return sum(ws), (op,) + ts
     elif op == 'func':
         f = getstring(x[1], _("not a symbol"))
-        wa, ta = _optimize(x[2], small, _defineorder)
+        # 'f' may have its own ordering requirement, but 'noop' function is
+        # known to return the argument set with no modification, so forward
+        # the requirement in that case.
+        d = _defineorder
+        if f in _noopsymbols:
+            d = order
+        wa, ta = _optimize(x[2], small, d)
         if f in ("author branch closed date desc file grep keyword "
                  "outgoing user"):
             w = 10 # slow
diff --git a/tests/test-revset.t b/tests/test-revset.t
--- a/tests/test-revset.t
+++ b/tests/test-revset.t
@@ -978,6 +978,69 @@  Test order of revisions in compound expr
   1
   0
 
+ because 'present()' does nothing other than suppressing errors, the ordering
+ requirement should be forwarded to the inner expression, and '_reorder'
+ should be inserted only when necessary:
+
+  $ try --optimize '2:0 & present(0 + 1 + 2)'
+  (and
+    (range
+      ('symbol', '2')
+      ('symbol', '0'))
+    (func
+      ('symbol', 'present')
+      (or
+        ('symbol', '0')
+        ('symbol', '1')
+        ('symbol', '2'))))
+  * optimized:
+  (and
+    (range
+      ('symbol', '2')
+      ('symbol', '0'))
+    (func
+      ('symbol', 'present')
+      (func
+        ('symbol', '_reorder')
+        (func
+          ('symbol', '_list')
+          ('string', '0\x001\x002')))))
+  * set:
+  <filteredset
+    <spanset- 0:2>,
+    <baseset [0, 1, 2]>>
+  2
+  1
+  0
+
+  $ try --optimize '2:0 & present(all())'
+  (and
+    (range
+      ('symbol', '2')
+      ('symbol', '0'))
+    (func
+      ('symbol', 'present')
+      (func
+        ('symbol', 'all')
+        None)))
+  * optimized:
+  (and
+    (range
+      ('symbol', '2')
+      ('symbol', '0'))
+    (func
+      ('symbol', 'present')
+      (func
+        ('symbol', 'all')
+        None)))
+  * set:
+  <filteredset
+    <spanset- 0:2>,
+    <spanset+ 0:9>>
+  2
+  1
+  0
+
  '_reorder' should be omitted if order doesn't matter:
 
   $ try --optimize '2:0 & not (0 + 1)'