diff --git a/test/box_big/sql.result b/test/box_big/sql.result
new file mode 100644
index 0000000000000000000000000000000000000000..5e9737fdf00dd47ddea9836312a004a97daf8bd7
--- /dev/null
+++ b/test/box_big/sql.result
@@ -0,0 +1,18 @@
+insert into t0 values ('Doe', 'Richard')
+Insert OK, 1 row affected
+insert into t0 values ('Roe', 'Richard')
+Insert OK, 1 row affected
+insert into t0 values ('Woe', 'Richard')
+Insert OK, 1 row affected
+insert into t0 values ('Major', 'Tomas')
+Insert OK, 1 row affected
+insert into t0 values ('Kytes', 'Tomas')
+Insert OK, 1 row affected
+insert into t0 values ('Stiles', 'Tomas')
+Insert OK, 1 row affected
+insert into t0 values ('Wales', 'Tomas')
+Insert OK, 1 row affected
+insert into t0 values ('Callaghan', 'Tomas')
+Insert OK, 1 row affected
+select * from t0 where k1='Richard' or k1='Tomas' or k1='Tomas' limit 5
+An error occurred: ERR_CODE_ILLEGAL_PARAMS, 'Illegal parameters'
diff --git a/test/box_big/sql.test b/test/box_big/sql.test
new file mode 100644
index 0000000000000000000000000000000000000000..8fc4b331350db63cbb06aab32befde1f537d067b
--- /dev/null
+++ b/test/box_big/sql.test
@@ -0,0 +1,14 @@
+# encoding: tarantool
+
+exec sql "insert into t0 values ('Doe', 'Richard')"
+exec sql "insert into t0 values ('Roe', 'Richard')"
+exec sql "insert into t0 values ('Woe', 'Richard')"
+exec sql "insert into t0 values ('Major', 'Tomas')"
+exec sql "insert into t0 values ('Kytes', 'Tomas')"
+exec sql "insert into t0 values ('Stiles', 'Tomas')"
+exec sql "insert into t0 values ('Wales', 'Tomas')"
+exec sql "insert into t0 values ('Callaghan', 'Tomas')"
+# xxx: bug
+exec sql "select * from t0 where k1='Richard' or k1='Tomas' or k1='Tomas' limit 5"
+
+# vim: syntax=python
diff --git a/test/box_big/suite.ini b/test/box_big/suite.ini
new file mode 100644
index 0000000000000000000000000000000000000000..8c7fe6ef267ab8a5c4fe0cd31165fc6fabfa778a
--- /dev/null
+++ b/test/box_big/suite.ini
@@ -0,0 +1,5 @@
+[default]
+description = tarantool/silverbox, various namespace configurations and properties
+config = tarantool.cfg
+# put disabled tests here
+#disabled = sql.test
diff --git a/test/box_big/tarantool.cfg b/test/box_big/tarantool.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..fbbe26eeb6082521bb178ce46d82600d919269ee
--- /dev/null
+++ b/test/box_big/tarantool.cfg
@@ -0,0 +1,24 @@
+slab_alloc_arena = 0.1
+
+pid_file = "box.pid"
+
+
+# Use -a not -a to work correctly on FreeBSD
+#
+logger="tee -a tarantool.log"
+
+primary_port = 33013
+secondary_port = 33014
+admin_port = 33015
+
+rows_per_wal = 50
+
+namespace[0].enabled = 1
+namespace[0].index[0].type = "HASH"
+namespace[0].index[0].unique = 1
+namespace[0].index[0].key_field[0].fieldno = 0
+namespace[0].index[0].key_field[0].type = "STR"
+namespace[0].index[1].type = "TREE"
+namespace[0].index[1].unique = 0
+namespace[0].index[1].key_field[0].fieldno = 1
+namespace[0].index[1].key_field[0].type = "STR"
diff --git a/test/lib/sql.g b/test/lib/sql.g
index 087fff5383b30dd8c4cc0f927fee1aec045c375d..86d2434d573de2f327dab3c12a8544a384881706 100644
--- a/test/lib/sql.g
+++ b/test/lib/sql.g
@@ -5,6 +5,10 @@ object_no_re = re.compile("[a-z_]*", re.I)
 
 %%
 
+# The grammar below solely covers the functionality provided by
+# Tarantool binary protocol, from which follow all the
+# limitations. For reference please see doc/box-protocol.txt.
+
 parser sql:
 
     ignore:           '\\s+'
@@ -21,6 +25,8 @@ parser sql:
     token WHERE:      'where'
     token VALUES:     'values'
     token SET:        'set'
+    token OR:         'or'
+    token LIMIT:      'limit'
     token END:        '\\s*$'
 
     rule sql:         (insert {{ stmt = insert }} |
@@ -31,19 +37,27 @@ parser sql:
                       
     rule insert:      INSERT [INTO] ident VALUES value_list
                       {{ return sql_ast.StatementInsert(ident, value_list) }}
-    rule update:      UPDATE ident SET update_list opt_where 
-                      {{ return sql_ast.StatementUpdate(ident, update_list, opt_where) }}
-    rule delete:      DELETE FROM ident opt_where
-                      {{ return sql_ast.StatementDelete(ident, opt_where) }}
-    rule select:      SELECT '\*' FROM ident opt_where
-                      {{ return sql_ast.StatementSelect(ident, opt_where) }}
+    rule update:      UPDATE ident SET update_list opt_simple_where
+                      {{ return sql_ast.StatementUpdate(ident, update_list, opt_simple_where) }}
+    rule delete:      DELETE FROM ident opt_simple_where
+                      {{ return sql_ast.StatementDelete(ident, opt_simple_where) }}
+    rule select:      SELECT '\*' FROM ident opt_where opt_limit
+                      {{ return sql_ast.StatementSelect(ident, opt_where, opt_limit) }}
     rule ping:        PING
                       {{ return sql_ast.StatementPing() }}
     rule predicate:   ident '=' constant
                       {{ return (ident, constant) }}
-    rule opt_where:   {{ return None }}
+    rule opt_simple_where:   {{ return None }}
                       | WHERE predicate
                       {{ return predicate }}
+    rule opt_where:   {{ return None }}
+                      | WHERE disjunction
+                      {{ return disjunction }}
+    rule disjunction: predicate {{ disjunction = [predicate] }}
+                      [(OR predicate {{ disjunction.append(predicate) }})+]
+                      {{ return disjunction }}
+    rule opt_limit:   {{ return 0xffffffff }}
+                      | LIMIT NUM {{ return int(NUM) }}
     rule value_list:  '\(' expr {{ value_list = [expr] }}
                           [("," expr {{ value_list.append(expr) }} )+]
                       '\)' {{ return value_list }}
diff --git a/test/lib/sql.py b/test/lib/sql.py
index f1ef9ca2542ecdece96b5e3cb8e1742a250fbefd..67d75319ed2ba345919d5f3bfa29183ab0c9424a 100644
--- a/test/lib/sql.py
+++ b/test/lib/sql.py
@@ -30,6 +30,8 @@ class sqlScanner(runtime.Scanner):
         ('WHERE', re.compile('where')),
         ('VALUES', re.compile('values')),
         ('SET', re.compile('set')),
+        ('OR', re.compile('or')),
+        ('LIMIT', re.compile('limit')),
         ('END', re.compile('\\s*$')),
     ]
     def __init__(self, str,*args,**kw):
@@ -74,16 +76,16 @@ class sql(runtime.Parser):
         ident = self.ident(_context)
         SET = self._scan('SET', context=_context)
         update_list = self.update_list(_context)
-        opt_where = self.opt_where(_context)
-        return sql_ast.StatementUpdate(ident, update_list, opt_where)
+        opt_simple_where = self.opt_simple_where(_context)
+        return sql_ast.StatementUpdate(ident, update_list, opt_simple_where)
 
     def delete(self, _parent=None):
         _context = self.Context(_parent, self._scanner, 'delete', [])
         DELETE = self._scan('DELETE', context=_context)
         FROM = self._scan('FROM', context=_context)
         ident = self.ident(_context)
-        opt_where = self.opt_where(_context)
-        return sql_ast.StatementDelete(ident, opt_where)
+        opt_simple_where = self.opt_simple_where(_context)
+        return sql_ast.StatementDelete(ident, opt_simple_where)
 
     def select(self, _parent=None):
         _context = self.Context(_parent, self._scanner, 'select', [])
@@ -92,7 +94,8 @@ class sql(runtime.Parser):
         FROM = self._scan('FROM', context=_context)
         ident = self.ident(_context)
         opt_where = self.opt_where(_context)
-        return sql_ast.StatementSelect(ident, opt_where)
+        opt_limit = self.opt_limit(_context)
+        return sql_ast.StatementSelect(ident, opt_where, opt_limit)
 
     def ping(self, _parent=None):
         _context = self.Context(_parent, self._scanner, 'ping', [])
@@ -106,8 +109,8 @@ class sql(runtime.Parser):
         constant = self.constant(_context)
         return (ident, constant)
 
-    def opt_where(self, _parent=None):
-        _context = self.Context(_parent, self._scanner, 'opt_where', [])
+    def opt_simple_where(self, _parent=None):
+        _context = self.Context(_parent, self._scanner, 'opt_simple_where', [])
         _token = self._peek('WHERE', 'END', context=_context)
         if _token == 'END':
             return None
@@ -116,6 +119,38 @@ class sql(runtime.Parser):
             predicate = self.predicate(_context)
             return predicate
 
+    def opt_where(self, _parent=None):
+        _context = self.Context(_parent, self._scanner, 'opt_where', [])
+        _token = self._peek('WHERE', 'LIMIT', 'END', context=_context)
+        if _token != 'WHERE':
+            return None
+        else: # == 'WHERE'
+            WHERE = self._scan('WHERE', context=_context)
+            disjunction = self.disjunction(_context)
+            return disjunction
+
+    def disjunction(self, _parent=None):
+        _context = self.Context(_parent, self._scanner, 'disjunction', [])
+        predicate = self.predicate(_context)
+        disjunction = [predicate]
+        if self._peek('OR', 'LIMIT', 'END', context=_context) == 'OR':
+            while 1:
+                OR = self._scan('OR', context=_context)
+                predicate = self.predicate(_context)
+                disjunction.append(predicate)
+                if self._peek('OR', 'LIMIT', 'END', context=_context) != 'OR': break
+        return disjunction
+
+    def opt_limit(self, _parent=None):
+        _context = self.Context(_parent, self._scanner, 'opt_limit', [])
+        _token = self._peek('LIMIT', 'END', context=_context)
+        if _token == 'END':
+            return 0xffffffff
+        else: # == 'LIMIT'
+            LIMIT = self._scan('LIMIT', context=_context)
+            NUM = self._scan('NUM', context=_context)
+            return int(NUM)
+
     def value_list(self, _parent=None):
         _context = self.Context(_parent, self._scanner, 'value_list', [])
         self._scan("'\\('", context=_context)
diff --git a/test/lib/sql_ast.py b/test/lib/sql_ast.py
index 515340ccdaf994f78d4801b40eab3d7784c51c76..45050ad085dd0de6f054a3fd338e591620294d88 100644
--- a/test/lib/sql_ast.py
+++ b/test/lib/sql_ast.py
@@ -242,16 +242,22 @@ class StatementDelete(StatementPing):
 class StatementSelect(StatementPing):
   reqeust_type = SELECT_REQUEST_TYPE
 
-  def __init__(self, table_name, where):
+  def __init__(self, table_name, where, limit):
     self.namespace_no = table_name
-    if where:
-      (self.index_no, key) = where
-      self.key = [key]
-    else:
+    self.index_no = None
+    self.key_list = []
+    if not where:
       self.index_no = 0
-      self.key = [""]
+      self.key_list = ["",]
+    else:
+      for (index_no, key) in where:
+        self.key_list.append(key)
+        if self.index_no == None:
+          self.index_no = index_no
+        elif self.index_no != index_no:
+          raise RuntimeError("All key values in a disjunction must refer to the same index")
     self.offset = 0
-    self.limit = 0xffffffff
+    self.limit = limit
 
   def pack(self):
     buf = ctypes.create_string_buffer(PACKET_BUF_LEN)
@@ -260,8 +266,10 @@ class StatementSelect(StatementPing):
                      self.index_no,
                      self.offset,
                      self.limit,
-                     1)
-    (buf, offset) = pack_tuple(self.key, buf, SELECT_REQUEST_FIXED_LEN)
+                     len(self.key_list))
+    offset = SELECT_REQUEST_FIXED_LEN
+    for key in self.key_list:
+      (buf, offset) = pack_tuple([key], buf, offset)
 
     return buf[:offset]
 
diff --git a/test/lib/tarantool_silverbox_server.py b/test/lib/tarantool_silverbox_server.py
index 0022714a82129d107c1f3138af53de9fd2886b8a..5d63e7e539d098b66bd2c57f85b9a6f44cd77f8b 100644
--- a/test/lib/tarantool_silverbox_server.py
+++ b/test/lib/tarantool_silverbox_server.py
@@ -33,7 +33,7 @@ def prepare_gdb(args):
   if term not in ["xterm", "rxvt", "urxvt", "gnome-terminal", "konsole"]:
     raise RuntimeError("--gdb: unsupported terminal {0}".format(term))
 
-  args = [ term, "-e ", "gdb", "-ex", "break main", "-ex", "run"] + args
+  args = [ term, "-e", "gdb", "-ex", "break main", "-ex", "run"] + args
   return args
 
 
diff --git a/test/lib/test_suite.py b/test/lib/test_suite.py
index 6a4bec88eb164bbb2037aacb57f0f44fbb3b5558..1d82b3c18ae12c1c7c1755830cd37a36afcd0b0b 100644
--- a/test/lib/test_suite.py
+++ b/test/lib/test_suite.py
@@ -260,6 +260,8 @@ class TestSuite:
   def run_all(self):
     """For each file in the test suite, run client program
     assuming each file represents an individual test."""
+    if len(self.tests) == 0:
+       return 0
     server = TarantoolSilverboxServer(self.args, self.ini)
     server.install()
     server.start()
diff --git a/test/test-run.py b/test/test-run.py
index 78bd629ede6be2614d0d3d8460b516b1ce486003..d682c1755ef45ccd1e3016348f8d8b86d683927b 100755
--- a/test/test-run.py
+++ b/test/test-run.py
@@ -60,8 +60,9 @@ class Options:
         dest = 'suites',
         metavar = "suite",
         nargs="*",
-        default = ["box"],
-        help = """List of tests suites to look for tests in. Default: "box".""")
+        default = ["box", "box_big"],
+        help = """List of tests suites to look for tests in. Default: "box",
+        "box_big".""")
 
     parser.add_argument(
         "--force",
@@ -156,7 +157,7 @@ def main():
       suites.append(TestSuite(suite_name, options.args))
 
     for suite in suites:
-      failed_tests = suite.run_all()
+      failed_tests += suite.run_all()
   except RuntimeError as e:
     print "\nFatal error: {0}. Execution aborted.".format(e)
     return (-1)