cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From stefa...@apache.org
Subject [02/10] cassandra git commit: cqlsh COPY FROM fails for null values with non-prepared statements
Date Wed, 27 Apr 2016 01:12:17 GMT
cqlsh COPY FROM fails for null values with non-prepared statements

patch by Stefania Alborghetti and Robert Stupp; reviewed by Robert Stupp for CASSANDRA-11631


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

Branch: refs/heads/cassandra-2.2
Commit: 72057c6971abf40e2d1a545c4b511be84a4eb69f
Parents: b25139f
Author: Stefania Alborghetti <stefania.alborghetti@datastax.com>
Authored: Mon Apr 25 10:33:54 2016 +0800
Committer: Stefania Alborghetti <stefania.alborghetti@datastax.com>
Committed: Wed Apr 27 09:05:48 2016 +0800

----------------------------------------------------------------------
 CHANGES.txt                |  1 +
 pylib/cqlshlib/copyutil.py | 36 +++++++++++++++++++++++++++---------
 2 files changed, 28 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/72057c69/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index ff26fde..5885a9a 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 2.1.15
+ * cqlsh COPY FROM fails for null values with non-prepared statements (CASSANDRA-11631)
  * Make cython optional in pylib/setup.py (CASSANDRA-11630)
  * Change order of directory searching for cassandra.in.sh to favor local one (CASSANDRA-11628)
  * cqlsh COPY FROM fails with []{} chars in UDT/tuple fields/values (CASSANDRA-11633)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/72057c69/pylib/cqlshlib/copyutil.py
----------------------------------------------------------------------
diff --git a/pylib/cqlshlib/copyutil.py b/pylib/cqlshlib/copyutil.py
index e12b72f..d68812c 100644
--- a/pylib/cqlshlib/copyutil.py
+++ b/pylib/cqlshlib/copyutil.py
@@ -1634,6 +1634,7 @@ class ImportConversion(object):
         self.thousands_sep = parent.thousands_sep
         self.boolean_styles = parent.boolean_styles
         self.time_format = parent.time_format
+        self.debug = parent.debug
 
         self.table_meta = table_meta
         self.primary_key_indexes = [self.columns.index(col.name) for col in self.table_meta.primary_key]
@@ -1682,7 +1683,16 @@ class ImportConversion(object):
                 return CqlRuleSet.dequote_value(v)
 
         def convert(t, v):
-            return converters.get(t.typename, convert_unknown)(unprotect(v), ct=t)
+            v = unprotect(v)
+            if v == self.nullval:
+                return self.get_null_val()
+            return converters.get(t.typename, convert_unknown)(v, ct=t)
+
+        def convert_mandatory(t, v):
+            v = unprotect(v)
+            if v == self.nullval:
+                raise ParseError('Empty values are not allowed')
+            return converters.get(t.typename, convert_unknown)(v, ct=t)
 
         def convert_blob(v, **_):
             try:
@@ -1788,13 +1798,13 @@ class ImportConversion(object):
             return Time(v)
 
         def convert_tuple(val, ct=cql_type):
-            return tuple(convert(t, v) for t, v in zip(ct.subtypes, split(val)))
+            return tuple(convert_mandatory(t, v) for t, v in zip(ct.subtypes, split(val)))
 
         def convert_list(val, ct=cql_type):
-            return list(convert(ct.subtypes[0], v) for v in split(val))
+            return list(convert_mandatory(ct.subtypes[0], v) for v in split(val))
 
         def convert_set(val, ct=cql_type):
-            return frozenset(convert(ct.subtypes[0], v) for v in split(val))
+            return frozenset(convert_mandatory(ct.subtypes[0], v) for v in split(val))
 
         def convert_map(val, ct=cql_type):
             """
@@ -1806,7 +1816,7 @@ class ImportConversion(object):
             class ImmutableDict(frozenset):
                 iteritems = frozenset.__iter__
 
-            return ImmutableDict(frozenset((convert(ct.subtypes[0], v[0]), convert(ct.subtypes[1],
v[1]))
+            return ImmutableDict(frozenset((convert_mandatory(ct.subtypes[0], v[0]), convert(ct.subtypes[1],
v[1]))
                                  for v in [split('{%s}' % vv, sep=':') for vv in split(val)]))
 
         def convert_user_type(val, ct=cql_type):
@@ -1862,6 +1872,9 @@ class ImportConversion(object):
 
         return converters.get(cql_type.typename, convert_unknown)
 
+    def get_null_val(self):
+        return None if self.use_prepared_statements else "NULL"
+
     def convert_row(self, row):
         """
         Convert the row into a list of parsed values if using prepared statements, else simply
apply the
@@ -1877,10 +1890,15 @@ class ImportConversion(object):
             if row[i] == self.nullval:
                 raise ParseError(self.get_null_primary_key_message(i))
 
-        try:
-            return [conv(val) if val != self.nullval else None for conv, val in zip(converters,
row)]
-        except Exception, e:
-            raise ParseError(str(e))
+        def convert(c, v):
+            try:
+                return c(v) if v != self.nullval else self.get_null_val()
+            except Exception, e:
+                if self.debug:
+                    traceback.print_exc()
+                raise ParseError("Failed to parse %s : %s" % (val, str(e)))
+
+        return [convert(conv, val) for conv, val in zip(converters, row)]
 
     def get_null_primary_key_message(self, idx):
         message = "Cannot insert null value for primary key column '%s'." % (self.columns[idx],)


Mime
View raw message