Commits

Matt Chaput committed a9a0ed4

Fixed problem with range query parsing regex (was too greedy across multiple ranges).
Fixes issue #212.

Comments (0)

Files changed (4)

src/whoosh/qparser/common.py

 parser modules.
 """
 
+from __future__ import print_function
 from whoosh.compat import string_type
 
 

src/whoosh/qparser/plugins.py

     (?P<start>
         ('[^']*?'\s+)             # single-quoted 
         |                         # or
-        (.+?(?=[Tt][Oo]))         # everything until "to"
+        ([^\]}]+?(?=[Tt][Oo]))    # everything until "to"
     )?
     [Tt][Oo]                      # "to"
     (?P<end>
         (\s+'[^']*?')             # single-quoted
         |                         # or
-        ((.+?)(?=]|}))            # everything until "]" or "}"
+        ([^\]}]+?)                # everything until "]" or "}"
     )?
     (?P<close>}|])                # Close paren
     """, verbose=True)

tests/test_parse_plugins.py

     assert_equal(q.startdate, adatetime(2010, 3, 30).floor())
     assert_equal(q.enddate, None)
 
-    print("!!!!!!!!!!!!!!!!!!!!")
     q = qp.parse(u("date:[30 march to next wednesday]"))
     print("q=", q)
     assert_equal(q.__class__, query.DateRange)
     assert_equal(q.startdate, adatetime(2010, 3, 30).floor())
     assert_equal(q.enddate, None)
 
+def test_daterange_multi():
+    schema = fields.Schema(text=fields.TEXT, start=fields.DATETIME, end=fields.DATETIME)
+    qp = qparser.QueryParser("text", schema)
+    basedate = datetime(2010, 9, 20, 15, 16, 6, 454000)
+    qp.add_plugin(dateparse.DateParserPlugin(basedate))
+
+    q = qp.parse("start:[2008 to] AND end:[2011 to 2011]")
+    assert_equal(q.__class__, query.And)
+    assert_equal(q[0].__class__, query.DateRange)
+    assert_equal(q[1].__class__, query.DateRange)
+    assert_equal(q[0].startdate, adatetime(2008).floor())
+    assert_equal(q[0].enddate, None)
+    assert_equal(q[1].startdate, adatetime(2011).floor())
+    assert_equal(q[1].enddate, adatetime(2011).ceil())
+
 def test_daterange_empty_field():
     schema = fields.Schema(test=fields.DATETIME)
     ix = RamStorage().create_index(schema)

tests/test_parsing.py

     assert_equal(q.start, None)
     assert_equal(q.end, None)
 
+def test_numrange_multi():
+    schema = fields.Schema(text=fields.TEXT, start=fields.NUMERIC, end=fields.NUMERIC)
+    qp = default.QueryParser("text", schema)
+
+    q = qp.parse("start:[2008 to]")
+    assert_equal(q.__class__, query.NumericRange)
+    assert_equal(q.fieldname, "start")
+    assert_equal(q.start, 2008)
+    assert_equal(q.end, None)
+
+    q = qp.parse("start:[2011 to 2012]")
+    assert_equal(q.__class__.__name__, "NumericRange")
+    assert_equal(q.fieldname, "start")
+    assert_equal(q.start, 2011)
+    assert_equal(q.end, 2012)
+
+    q = qp.parse("start:[2008 to] AND end:[2011 to 2012]")
+    assert_equal(q.__class__, query.And)
+    assert_equal(q[0].__class__, query.NumericRange)
+    assert_equal(q[1].__class__, query.NumericRange)
+    assert_equal(q[0].start, 2008)
+    assert_equal(q[0].end, None)
+    assert_equal(q[1].start, 2011)
+    assert_equal(q[1].end, 2012)
+
 def test_nonexistant_fieldnames():
     # Need an analyzer that won't mangle a URL
     a = analysis.SimpleAnalyzer("\\S+")