Commit dfbfbe55 authored by Tim Peters's avatar Tim Peters

Special-case None search() results in AND, AND NOT, and OR contexts, and

uncomment the test cases that were failing in these contexts.

Read it and weep <wink>:  In an AND context, None is treated like the
universal set, which jibes with the convenient fiction that stop words
appear in every doc.  However, in AND NOT and OR contexts, None is
treated like the empty set, which doesn't jibe with anything except that
we want

    real_word AND NOT stop_word

and

    real_word OR stop_word

to act like

    real_word

If we treated None as if it were the universal set, these results would
be (respectively) the empty set and the universal set instead.

At a higher level, we *are* consistent with the notion that a query with
a stop word acts the same as if the clause with the stop word weren't
present.  That's what really drives this schizophrenic (context-dependent)
treatment of None.
parent f968ebb5
...@@ -69,10 +69,19 @@ class AndNode(ParseTreeNode): ...@@ -69,10 +69,19 @@ class AndNode(ParseTreeNode):
Nots = [] Nots = []
for subnode in self.getValue(): for subnode in self.getValue():
if subnode.nodeType() == "NOT": if subnode.nodeType() == "NOT":
Nots.append((subnode.getValue().executeQuery(index), 1)) r = subnode.getValue().executeQuery(index)
# If None, technically it matches every doc, but we treat
# it as if it matched none (we want
# real_word AND NOT stop_word
# to act like plain real_word).
if r is not None:
Nots.append((r, 1))
else: else:
L.append((subnode.executeQuery(index), 1)) r = subnode.executeQuery(index)
assert L # If None, technically it matches every doc, so needn't be
# included.
if r is not None:
L.append((r, 1))
set = mass_weightedIntersection(L) set = mass_weightedIntersection(L)
if Nots: if Nots:
notset = mass_weightedUnion(Nots) notset = mass_weightedUnion(Nots)
...@@ -84,8 +93,15 @@ class OrNode(ParseTreeNode): ...@@ -84,8 +93,15 @@ class OrNode(ParseTreeNode):
_nodeType = "OR" _nodeType = "OR"
def executeQuery(self, index): def executeQuery(self, index):
weighted = [(node.executeQuery(index), 1) weighted = []
for node in self.getValue()] for node in self.getValue():
r = node.executeQuery(index)
# If None, technically it matches every doc, but we treat
# it as if it matched none (we want
# real_word OR stop_word
# to act like plain real_word).
if r is not None:
weighted.append((r, 1))
return mass_weightedUnion(weighted) return mass_weightedUnion(weighted)
class AtomNode(ParseTreeNode): class AtomNode(ParseTreeNode):
......
...@@ -127,13 +127,13 @@ class ZCIndexTestsBase: ...@@ -127,13 +127,13 @@ class ZCIndexTestsBase:
self.assertEqual(num, 1) self.assertEqual(num, 1)
self.assertEqual(r[0][0], 1) self.assertEqual(r[0][0], 1)
# r, num = self.zc_index.query('question AND NOT to AND NOT be') r, num = self.zc_index.query('question AND NOT to AND NOT be')
# self.assertEqual(num, 1) self.assertEqual(num, 1)
# self.assertEqual(r[0][0], 1) self.assertEqual(r[0][0], 1)
# r, num = self.zc_index.query('question OR to OR be') r, num = self.zc_index.query('question OR to OR be')
# self.assertEqual(num, 1) self.assertEqual(num, 1)
# self.assertEqual(r[0][0], 1) self.assertEqual(r[0][0], 1)
r, num = self.zc_index.query('question to be') r, num = self.zc_index.query('question to be')
self.assertEqual(num, 1) self.assertEqual(num, 1)
...@@ -145,8 +145,8 @@ class ZCIndexTestsBase: ...@@ -145,8 +145,8 @@ class ZCIndexTestsBase:
r, num = self.zc_index.query('to AND be') r, num = self.zc_index.query('to AND be')
self.assertEqual(num, 0) self.assertEqual(num, 0)
# r, num = self.zc_index.query('to OR be') r, num = self.zc_index.query('to OR be')
# self.assertEqual(num, 0) self.assertEqual(num, 0)
r, num = self.zc_index.query('to AND NOT be') r, num = self.zc_index.query('to AND NOT be')
self.assertEqual(num, 0) self.assertEqual(num, 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment