From bdca25e96e8fc9b6379c599ef001a256e474688e Mon Sep 17 00:00:00 2001 From: Stefania Alborghetti Date: Tue, 13 Dec 2016 12:05:57 +0800 Subject: [PATCH] cqlsh copy-from: sort user type fields in csv patch by Stefania Alborghetti; reviewed by Paulo Motta for CASSANDRA-12959 --- CHANGES.txt | 1 + pylib/cqlshlib/copyutil.py | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index a2e61fbf38..a99f79ae4a 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 2.1.17 + * cqlsh copy-from: sort user type fields in csv (CASSANDRA-12959) * Fix missed signal when commit log segments are recycled (CASSANDRA-13037) * Fix RecoveryManagerTruncateTest (CASSANDRA-12802) * Don't skip sstables based on maxLocalDeletionTime (CASSANDRA-12765) diff --git a/pylib/cqlshlib/copyutil.py b/pylib/cqlshlib/copyutil.py index 0016dfdb63..5565fed0e5 100644 --- a/pylib/cqlshlib/copyutil.py +++ b/pylib/cqlshlib/copyutil.py @@ -1856,10 +1856,15 @@ class ImportConversion(object): an attribute, so we are using named tuples. It must also be hashable, so we cannot use dictionaries. Maybe there is a way to instantiate ct directly but I could not work it out. + Also note that it is possible that the subfield names in the csv are in the + wrong order, so we must sort them according to ct.fieldnames, see CASSANDRA-12959. """ vals = [v for v in [split('{%s}' % vv, sep=':') for vv in split(val)]] - ret_type = namedtuple(ct.typename, [unprotect(v[0]) for v in vals]) - return ret_type(*tuple(convert(t, v[1]) for t, v in zip(ct.subtypes, vals))) + dict_vals = dict((unprotect(v[0]), v[1]) for v in vals) + sorted_converted_vals = [(n, convert(t, dict_vals[n]) if n in dict_vals else self.get_null_val()) + for n, t in zip(ct.fieldnames, ct.subtypes)] + ret_type = namedtuple(ct.typename, [v[0] for v in sorted_converted_vals]) + return ret_type(*tuple(v[1] for v in sorted_converted_vals)) def convert_single_subtype(val, ct=cql_type): return converters.get(ct.subtypes[0].typename, convert_unknown)(val, ct=ct.subtypes[0])