You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by mi...@apache.org on 2014/05/29 00:15:10 UTC

[2/3] git commit: cqlsh: Handle collections embedded into UDTs correctly.

cqlsh: Handle collections embedded into UDTs correctly.

patch by Mikhail Stepura; reviewed by Tyler Hobbs for CASSANDRA-7267


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/3391b99a
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/3391b99a
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/3391b99a

Branch: refs/heads/trunk
Commit: 3391b99a0bd38882dbee2261ddcdca77cc634722
Parents: ea02b69
Author: Mikhail Stepura <mi...@apache.org>
Authored: Tue May 27 20:05:34 2014 -0700
Committer: Mikhail Stepura <mi...@apache.org>
Committed: Wed May 28 15:14:25 2014 -0700

----------------------------------------------------------------------
 CHANGES.txt                                |  1 +
 bin/cqlsh                                  |  5 +++
 pylib/cqlshlib/test/test_cqlsh_output.py   | 30 ++++++++++++++
 pylib/cqlshlib/test/test_keyspace_init.cql | 40 ++++++++++++++++++
 pylib/cqlshlib/usertypes.py                | 55 ++++++++++++++++++++++++-
 5 files changed, 130 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/3391b99a/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index f62d5b0..fe8242b 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -28,6 +28,7 @@
  * Backport Thrift MultiSliceRequest (CASSANDRA-7027)
  * Handle overlapping MultiSlices (CASSANDRA-7279)
  * Fix DataOutputTest on Windows (CASSANDRA-7265)
+ * Embedded sets in user defined data-types are not updating (CASSANDRA-7267)
 Merged from 2.0:
  * Copy compaction options to make sure they are reloaded (CASSANDRA-7290)
  * Add option to do more aggressive tombstone compactions (CASSANDRA-6563)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/3391b99a/bin/cqlsh
----------------------------------------------------------------------
diff --git a/bin/cqlsh b/bin/cqlsh
index 1397f85..914d175 100755
--- a/bin/cqlsh
+++ b/bin/cqlsh
@@ -119,6 +119,7 @@ from cqlshlib.displaying import (RED, BLUE, ANSI_RESET, COLUMN_NAME_COLORS,
 from cqlshlib.formatting import format_by_type
 from cqlshlib.util import trim_if_present
 from cqlshlib.tracing import print_trace_session
+from cqlshlib.usertypes import deserialize_safe_collection, deserialize_safe_map
 
 HISTORY_DIR = os.path.expanduser(os.path.join('~', '.cassandra'))
 CONFIG_FILE = os.path.join(HISTORY_DIR, 'cqlshrc')
@@ -521,6 +522,10 @@ class Shell(cmd.Cmd):
         #Python driver returns BLOBs as string, but we expect them as buffer()
         cassandra.cqltypes.BytesType.deserialize = staticmethod(cassandra.cqltypes.BytesType.validate)
         cassandra.cqltypes.CassandraType.support_empty_values = True
+        # see CASSANDRA-7267
+        cassandra.cqltypes._SimpleParameterizedType.deserialize_safe = classmethod(deserialize_safe_collection)
+        # see CASSANDRA-7267
+        cassandra.cqltypes.MapType.deserialize_safe = classmethod(deserialize_safe_map)
         self.empty_lines = 0
         self.statement_error = False
         self.single_statement = single_statement

http://git-wip-us.apache.org/repos/asf/cassandra/blob/3391b99a/pylib/cqlshlib/test/test_cqlsh_output.py
----------------------------------------------------------------------
diff --git a/pylib/cqlshlib/test/test_cqlsh_output.py b/pylib/cqlshlib/test/test_cqlsh_output.py
index d91b4f3..6689e4b 100644
--- a/pylib/cqlshlib/test/test_cqlsh_output.py
+++ b/pylib/cqlshlib/test/test_cqlsh_output.py
@@ -854,4 +854,34 @@ class TestCqlshOutput(BaseTestCase):
             (2 rows)
             nnnnnnnn
             """),
+        ), cqlver=cqlsh.DEFAULT_CQLVER)
+
+    def test_user_types_with_collections(self):
+        self.assertCqlverQueriesGiveColoredOutput((
+            ("select info from songs;", r"""
+             info
+             MMMM
+            ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+             {founded: '1970-01-02 20:24:54-0800', members: {'Adrian Smith', 'Bruce Dickinson', 'Dave Murray', 'Janick Gers', 'Nicko McBrain', 'Steve Harris'}, description: 'Pure evil metal'}
+             BYYYYYYYBBGGGGGGGGGGGGGGGGGGGGGGGGGGBBYYYYYYYBBBYYYYYYYYYYYYYYBBYYYYYYYYYYYYYYYYYBBYYYYYYYYYYYYYBBYYYYYYYYYYYYYBBYYYYYYYYYYYYYYYBBYYYYYYYYYYYYYYBBBYYYYYYYYYYYBBYYYYYYYYYYYYYYYYYB
+
+
+            (1 rows)
+            nnnnnnnn
+            """),
+        ), cqlver=cqlsh.DEFAULT_CQLVER)
+        self.assertCqlverQueriesGiveColoredOutput((
+            ("select tags from songs;", r"""
+             tags
+             MMMM
+            -------------------------------------------------
+
+             {tags: {'genre': 'metal', 'origin': 'england'}}
+             BYYYYBBBYYYYYYYBBYYYYYYYBBYYYYYYYYBBYYYYYYYYYBB
+
+
+            (1 rows)
+            nnnnnnnn
+            """),
         ), cqlver=cqlsh.DEFAULT_CQLVER)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/3391b99a/pylib/cqlshlib/test/test_keyspace_init.cql
----------------------------------------------------------------------
diff --git a/pylib/cqlshlib/test/test_keyspace_init.cql b/pylib/cqlshlib/test/test_keyspace_init.cql
index 2c3d81d..98932bc 100644
--- a/pylib/cqlshlib/test/test_keyspace_init.cql
+++ b/pylib/cqlshlib/test/test_keyspace_init.cql
@@ -231,3 +231,43 @@ values ('vpupkin',
          {city: 'Chigirinsk', address: null, zip: '676722'}},
         {{country: '+7', number: null},
          {country: null, number: '03'}});
+
+CREATE TYPE band_info_type (
+  founded timestamp,
+  members set<text>,
+  description text
+);
+
+CREATE TYPE tags (
+  tags map<text, text>
+);
+
+CREATE TABLE songs (
+    title text PRIMARY KEY,
+    band text,
+    info band_info_type,
+    tags tags
+);
+
+insert into songs (title, band, info, tags)
+values (
+    'The trooper',
+    'Iron Maiden',
+    {
+        founded:188694000,
+        members: {
+            'Bruce Dickinson',
+            'Dave Murray',
+            'Adrian Smith',
+            'Janick Gers',
+            'Steve Harris',
+            'Nicko McBrain'
+        },
+        description: 'Pure evil metal'
+     },
+    {
+        tags: {
+            'genre':'metal',
+            'origin':'england'
+        }
+    });

http://git-wip-us.apache.org/repos/asf/cassandra/blob/3391b99a/pylib/cqlshlib/usertypes.py
----------------------------------------------------------------------
diff --git a/pylib/cqlshlib/usertypes.py b/pylib/cqlshlib/usertypes.py
index 577a465..78a7fb0 100644
--- a/pylib/cqlshlib/usertypes.py
+++ b/pylib/cqlshlib/usertypes.py
@@ -14,7 +14,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from cassandra.marshal import int32_unpack
+from cassandra.marshal import int32_unpack, uint16_unpack
 from cassandra.cqltypes import CompositeType
 import collections
 from formatting import formatter_for, format_value_utype
@@ -60,5 +60,58 @@ class UserType(CompositeType):
 
         return Result(*result)
 
+def deserialize_safe_collection(cls, byts):
+    """
+        Temporary work around for CASSANDRA-7267
+    """
+    subtype, = cls.subtypes
+    unpack = uint16_unpack
+    length = 2
+    numelements = unpack(byts[:length])
+    if numelements == 0 and len(byts) > 2 :
+        unpack = int32_unpack
+        length = 4
+        numelements = unpack(byts[:length])
+    p = length
+    result = []
+    for n in xrange(numelements):
+        itemlen = unpack(byts[p:p + length])
+        p += length
+        item = byts[p:p + itemlen]
+        p += itemlen
+        result.append(subtype.from_binary(item))
+    return cls.adapter(result)
 
+try:
+    from collections import OrderedDict
+except ImportError:  # Python <2.7
+    from cassandra.util import OrderedDict
 
+def deserialize_safe_map(cls, byts):
+    """
+        Temporary work around for CASSANDRA-7267
+    """
+    subkeytype, subvaltype = cls.subtypes
+    unpack = uint16_unpack
+    length = 2
+    numelements = unpack(byts[:length])
+    if numelements == 0 and len(byts) > 2:
+        unpack = int32_unpack
+        length = 4
+        numelements = unpack(byts[:length])
+
+    p = length
+    themap = OrderedDict()
+    for n in xrange(numelements):
+        key_len = unpack(byts[p:p + length])
+        p += length
+        keybytes = byts[p:p + key_len]
+        p += key_len
+        val_len = unpack(byts[p:p + length])
+        p += length
+        valbytes = byts[p:p + val_len]
+        p += val_len
+        key = subkeytype.from_binary(keybytes)
+        val = subvaltype.from_binary(valbytes)
+        themap[key] = val
+    return themap