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

login
register
mail settings
Submitter Yuya Nishihara
Date June 23, 2016, 3:59 p.m.
Message ID <fb16f5ab09a67c438615.1466697596@mimosa>
Download mbox | patch
Permalink /patch/15582/
State Accepted
Headers show

Comments

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

present() is special in that it forwards the argument set with no
modification. So the ordering requirement should also be forwarded.

Patch

diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -2491,7 +2491,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 'present(set)' is
+        # known to return the argument set with no modification, so forward
+        # the requirement in that case.
+        d = defineorder
+        if f == "present":
+            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
@@ -1190,7 +1190,9 @@  ordering defined by it.
       <baseset [0, 1]>>>
   2
 
- 'present()' should do nothing other than suppressing an error:
+ because 'present()' does nothing other than suppressing an error, the
+ ordering requirement should be forwarded to the nested expression, and
+ '_unordered' should be inserted only when necessary:
 
   $ try --optimize '2:0 & present(0 + 1 + 2)'
   (and
@@ -1211,14 +1213,45 @@  ordering defined by it.
     (func
       ('symbol', 'present')
       (func
-        ('symbol', '_list')
-        ('string', '0\x001\x002'))))
+        ('symbol', '_unordered')
+        (func
+          ('symbol', '_list')
+          ('string', '0\x001\x002')))))
   * set:
-  <baseset [0, 1, 2]>
+  <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
-  2
- BROKEN: should be '2 1 0'
+  0
 
  'reverse()' should take effect only if it is the outermost expression: