From 52aa1efa23dc43b3cf468f8bc1743d05b56e020f Mon Sep 17 00:00:00 2001 From: Michael Hanselmann <hansmi@google.com> Date: Thu, 11 Oct 2012 10:44:12 +0200 Subject: [PATCH] query: Report data type for unary operators MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All data kinds (used to restrict the data collected) referenced in a filter can be requested once it's been βcompiledβ. However, the kinds of fields used in boolean expressions (e.g. ["?", "xyz"]) were not recorded. This patch changes the code accordingly and provides a unit test update. Signed-off-by: Michael Hanselmann <hansmi@google.com> Reviewed-by: Iustin Pop <iustin@google.com> --- lib/query.py | 16 +++++++++++----- test/ganeti.query_unittest.py | 13 +++++++++++++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/lib/query.py b/lib/query.py index b922bf974..01b434b00 100644 --- a/lib/query.py +++ b/lib/query.py @@ -269,13 +269,16 @@ class _FilterHints: if op != qlang.OP_OR: self._NeedAllNames() - def NoteUnaryOp(self, op): # pylint: disable=W0613 + def NoteUnaryOp(self, op, datakind): # pylint: disable=W0613 """Called when handling an unary operation. @type op: string @param op: Operator """ + if datakind is not None: + self._datakinds.add(datakind) + self._NeedAllNames() def NoteBinaryOp(self, op, datakind, name, value): @@ -557,19 +560,22 @@ class _FilterCompilerHelper: """ assert op_fn is None - if hints_fn: - hints_fn(op) - if len(operands) != 1: raise errors.ParameterError("Unary operator '%s' expects exactly one" " operand" % op) if op == qlang.OP_TRUE: - (_, _, _, retrieval_fn) = self._LookupField(operands[0]) + (_, datakind, _, retrieval_fn) = self._LookupField(operands[0]) + + if hints_fn: + hints_fn(op, datakind) op_fn = operator.truth arg = retrieval_fn elif op == qlang.OP_NOT: + if hints_fn: + hints_fn(op, None) + op_fn = operator.not_ arg = self._Compile(operands[0], level + 1) else: diff --git a/test/ganeti.query_unittest.py b/test/ganeti.query_unittest.py index f1e848b60..024102aac 100755 --- a/test/ganeti.query_unittest.py +++ b/test/ganeti.query_unittest.py @@ -1521,6 +1521,19 @@ class TestQueryFilter(unittest.TestCase): self.assertEqual(q.RequestedData(), set([DK_B])) self.assertEqual(q.Query(data), [[]]) + # Data type in boolean operator + q = query.Query(fielddefs, [], namefield="name", + qfilter=["?", "name"]) + self.assertTrue(q.RequestedNames() is None) + self.assertEqual(q.RequestedData(), set([DK_A])) + self.assertEqual(q.Query(data), [[], [], []]) + + q = query.Query(fielddefs, [], namefield="name", + qfilter=["!", ["?", "name"]]) + self.assertTrue(q.RequestedNames() is None) + self.assertEqual(q.RequestedData(), set([DK_A])) + self.assertEqual(q.Query(data), []) + def testFilterContains(self): fielddefs = query._PrepareFieldList([ (query._MakeField("name", "Name", constants.QFT_TEXT, "Name"), -- GitLab