@@ -2,8 +2,10 @@ use std::str::FromStr;
22
33use super :: extern_db:: ExternDBTrait ;
44use crate :: common:: BlockPtr ;
5+ use crate :: debug;
56use crate :: error;
67use crate :: errors:: DatabaseError ;
8+ use crate :: info;
79use crate :: messages:: RawEntity ;
810use crate :: runtime:: asc:: native_types:: store:: Bytes ;
911use crate :: runtime:: asc:: native_types:: store:: StoreValueKind ;
@@ -92,24 +94,28 @@ impl Scylladb {
9294 . to_string ( )
9395 }
9496
95- fn cql_value_to_store_value ( field_kind : FieldKind , value : CqlValue ) -> Value {
97+ fn cql_value_to_store_value ( field_kind : FieldKind , value : Option < CqlValue > ) -> Value {
9698 match field_kind. kind {
97- StoreValueKind :: Int => Value :: Int ( value. as_int ( ) . unwrap ( ) ) ,
98- StoreValueKind :: Int8 => Value :: Int8 ( value. as_bigint ( ) . unwrap ( ) ) ,
99- StoreValueKind :: String => Value :: String ( value. as_text ( ) . unwrap ( ) . to_owned ( ) ) ,
100- StoreValueKind :: Bool => Value :: Bool ( value. as_boolean ( ) . unwrap ( ) ) ,
99+ StoreValueKind :: Int => Value :: Int ( value. unwrap ( ) . as_int ( ) . unwrap ( ) ) ,
100+ StoreValueKind :: Int8 => Value :: Int8 ( value. unwrap ( ) . as_bigint ( ) . unwrap ( ) ) ,
101+ StoreValueKind :: String => Value :: String ( value. unwrap ( ) . as_text ( ) . unwrap ( ) . to_owned ( ) ) ,
102+ StoreValueKind :: Bool => Value :: Bool ( value. unwrap ( ) . as_boolean ( ) . unwrap ( ) ) ,
101103 StoreValueKind :: BigDecimal => {
102- Value :: BigDecimal ( BigDecimal :: from_str ( value. as_text ( ) . unwrap ( ) ) . unwrap ( ) )
104+ Value :: BigDecimal ( BigDecimal :: from_str ( value. unwrap ( ) . as_text ( ) . unwrap ( ) ) . unwrap ( ) )
103105 }
104106 StoreValueKind :: BigInt => {
105- Value :: BigInt ( BigInt :: from_str ( value. as_text ( ) . unwrap ( ) ) . unwrap ( ) )
107+ Value :: BigInt ( BigInt :: from_str ( value. unwrap ( ) . as_text ( ) . unwrap ( ) ) . unwrap ( ) )
106108 }
107109 StoreValueKind :: Bytes => {
108- let bytes = value. as_blob ( ) . unwrap ( ) ;
110+ let bytes_value = value. unwrap ( ) ;
111+ let bytes = bytes_value. as_blob ( ) . unwrap ( ) ;
109112 Value :: Bytes ( Bytes :: from ( bytes. as_slice ( ) ) )
110113 }
111114 StoreValueKind :: Array => {
112- let inner_values = value. as_list ( ) . cloned ( ) . unwrap_or_default ( ) ;
115+ if value. is_none ( ) {
116+ return Value :: List ( vec ! [ ] ) ;
117+ }
118+ let inner_values = value. unwrap ( ) . as_list ( ) . cloned ( ) . unwrap_or_default ( ) ;
113119 let inner_values = inner_values
114120 . into_iter ( )
115121 . map ( |inner_val| {
@@ -119,7 +125,7 @@ impl Scylladb {
119125 relation : None ,
120126 list_inner_kind : None ,
121127 } ,
122- inner_val,
128+ Some ( inner_val) ,
123129 )
124130 } )
125131 . collect :: < Vec < _ > > ( ) ;
@@ -141,28 +147,28 @@ impl Scylladb {
141147
142148 for row in rows {
143149 let mut entity = RawEntity :: new ( ) ;
144- for ( idx, column) in row. columns . into_iter ( ) . flatten ( ) . enumerate ( ) {
145- let col_spec = col_specs[ idx] . to_owned ( ) ;
146- let field_name = col_spec. name ;
150+ for ( idx, column) in row. columns . iter ( ) . enumerate ( ) {
151+ let col_spec = col_specs[ idx] . clone ( ) ;
152+ let field_name = col_spec. name . clone ( ) ;
147153
148154 if field_name == "is_deleted" {
149155 entity. insert (
150156 "is_deleted" . to_string ( ) ,
151- Value :: Bool ( column. as_boolean ( ) . unwrap ( ) ) ,
157+ Value :: Bool ( column. clone ( ) . unwrap ( ) . as_boolean ( ) . unwrap ( ) ) ,
152158 ) ;
153159 continue ;
154160 }
155161
156162 if field_name == "block_ptr_number" {
157163 entity. insert (
158164 "block_ptr_number" . to_string ( ) ,
159- Value :: Int8 ( column. as_bigint ( ) . unwrap ( ) ) ,
165+ Value :: Int8 ( column. clone ( ) . unwrap ( ) . as_bigint ( ) . unwrap ( ) ) ,
160166 ) ;
161167 continue ;
162168 }
163169
164170 let field_kind = self . schema_lookup . get_field ( entity_type, & field_name) ;
165- let value = Scylladb :: cql_value_to_store_value ( field_kind, column) ;
171+ let value = Scylladb :: cql_value_to_store_value ( field_kind, column. clone ( ) ) ;
166172 entity. insert ( field_name, value) ;
167173 }
168174
@@ -249,10 +255,25 @@ impl Scylladb {
249255 CqlValue :: BigInt ( block_ptr. number as i64 ) ,
250256 data. get( "is_deleted" ) . unwrap( ) . clone( ) . into( ) ,
251257 ] ;
252- for ( field_name, _field_kind) in schema. iter ( ) {
253- let value = data. get ( field_name) . cloned ( ) . unwrap ( ) ;
258+ for ( field_name, field_kind) in schema. iter ( ) {
259+ let value = match data. get ( field_name) {
260+ None => {
261+ //handle case when field is missing but has in schema
262+ debug ! (
263+ Scylladb ,
264+ "Missing field" ;
265+ entity_type => entity_type,
266+ field_name => field_name,
267+ data => format!( "{:?}" , data)
268+ ) ;
269+ let default_value =
270+ Scylladb :: cql_value_to_store_value ( field_kind. clone ( ) , None ) ;
271+ CqlValue :: from ( default_value)
272+ }
273+ Some ( val) => CqlValue :: from ( val. clone ( ) ) ,
274+ } ;
275+ values_params. push ( value) ;
254276 fields. push ( format ! ( "\" {}\" " , field_name) ) ;
255- values_params. push ( CqlValue :: from ( value) ) ;
256277 column_values. push ( "?" . to_string ( ) ) ;
257278 }
258279
0 commit comments