diff --git a/Makefile.am b/Makefile.am
index b51685a30f80f879d07cee29bfbd492fb89c1f20..4bfd0943819091ebbf476f97b3dce1f05af173bd 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -138,6 +138,7 @@ pkgpython_PYTHON = \
 	lib/netutils.py \
 	lib/objects.py \
 	lib/opcodes.py \
+	lib/qlang.py \
 	lib/query.py \
 	lib/rpc.py \
 	lib/runtime.py \
@@ -443,6 +444,7 @@ python_tests = \
 	test/ganeti.netutils_unittest.py \
 	test/ganeti.objects_unittest.py \
 	test/ganeti.opcodes_unittest.py \
+	test/ganeti.qlang_unittest.py \
 	test/ganeti.query_unittest.py \
 	test/ganeti.rapi.client_unittest.py \
 	test/ganeti.rapi.resources_unittest.py \
diff --git a/lib/qlang.py b/lib/qlang.py
new file mode 100644
index 0000000000000000000000000000000000000000..ec4f41b96aa1b6644fd5eba13dcdb22ec528da80
--- /dev/null
+++ b/lib/qlang.py
@@ -0,0 +1,75 @@
+#
+#
+
+# Copyright (C) 2010 Google Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+
+"""Module for a simple query language"""
+
+from ganeti import errors
+
+
+OP_OR = "|"
+OP_EQUAL = "="
+
+
+def ReadSimpleFilter(namefield, filter_):
+  """Function extracting wanted names from restricted filter.
+
+  This should only be used until proper filtering is implemented. The filter
+  must either be empty or of the format C{["|", ["=", field, "name1"], ["=",
+  field, "name2"], ...]}.
+
+  """
+  if filter_ is None:
+    return []
+
+  if not isinstance(filter_, list):
+    raise errors.ParameterError("Filter should be list")
+
+  if not filter_ or filter_[0] != OP_OR:
+    raise errors.ParameterError("Filter should start with OR operator")
+
+  if len(filter_) < 2:
+    raise errors.ParameterError("Invalid filter, OR operator should have"
+                                " operands")
+
+  result = []
+
+  for idx, item in enumerate(filter_[1:]):
+    if not isinstance(item, list):
+      raise errors.ParameterError("Invalid OR operator, operand %s not a"
+                                  " list" % idx)
+
+    if len(item) != 3 or item[0] != OP_EQUAL:
+      raise errors.ParameterError("Invalid OR operator, operand %s is not an"
+                                  " equality filter" % idx)
+
+    (_, name, value) = item
+
+    if not isinstance(value, basestring):
+      raise errors.ParameterError("Operand %s for OR should compare against a"
+                                  " string" % idx)
+
+    if name != namefield:
+      raise errors.ParameterError("Operand %s for OR should filter field '%s',"
+                                  " not '%s'" % (idx, namefield, name))
+
+    result.append(value)
+
+  return result
diff --git a/test/ganeti.qlang_unittest.py b/test/ganeti.qlang_unittest.py
new file mode 100755
index 0000000000000000000000000000000000000000..c0ab03d597f80a90f54b3a79c5d70b7e2732c9f1
--- /dev/null
+++ b/test/ganeti.qlang_unittest.py
@@ -0,0 +1,60 @@
+#!/usr/bin/python
+#
+
+# Copyright (C) 2010 Google Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+
+"""Script for testing ganeti.qlang"""
+
+import unittest
+
+from ganeti import utils
+from ganeti import errors
+from ganeti import qlang
+
+import testutils
+
+
+class TestReadSimpleFilter(unittest.TestCase):
+  def _Test(self, filter_, expected):
+    self.assertEqual(qlang.ReadSimpleFilter("name", filter_), expected)
+
+  def test(self):
+    self._Test(None, [])
+    self._Test(["|", ["=", "name", "xyz"]], ["xyz"])
+
+    for i in [1, 3, 10, 25, 140]:
+      self._Test(["|"] + [["=", "name", "node%s" % j] for j in range(i)],
+                 ["node%s" % j for j in range(i)])
+
+  def testErrors(self):
+    for i in [123, True, False, "", "Hello World", "a==b",
+              [], ["x"], ["x", "y", "z"], ["|"],
+              ["|", ["="]], ["|", "x"], ["|", 123],
+              ["|", ["=", "otherfield", "xyz"]],
+              ["|", ["=", "name", "xyz"], "abc"],
+              ["|", ["=", "name", "xyz", "too", "long"]],
+              ["|", ["=", "name", []]],
+              ["|", ["=", "name", 999]],
+              ["|", ["=", "name", "abc"], ["=", "otherfield", "xyz"]]]:
+      self.assertRaises(errors.ParameterError, qlang.ReadSimpleFilter,
+                        "name", i)
+
+
+if __name__ == "__main__":
+  testutils.GanetiTestProgram()