diff --git a/generated_types/protos/influxdata/iox/catalog/v1/catalog.proto b/generated_types/protos/influxdata/iox/catalog/v1/catalog.proto index 34ccfa5d70..befe01daa2 100644 --- a/generated_types/protos/influxdata/iox/catalog/v1/catalog.proto +++ b/generated_types/protos/influxdata/iox/catalog/v1/catalog.proto @@ -79,12 +79,14 @@ message Transaction { // Definition of how this transaction relates to previous transaction and how it should be processed. enum Encoding { + ENCODING_UNSPECIFIED = 0; + // The actions in this message only encode changes to the previous transactions which must be processed // beforehand. This is the default for "ordinary" transactions. - DELTA = 0; + ENCODING_DELTA = 1; // The actions in this message contain the full state of the catalog at this point in time. This is used for checkpoints. - FULL = 1; + ENCODING_FULL = 2; } // Definition on how this transaction is encoded. diff --git a/parquet_file/src/catalog.rs b/parquet_file/src/catalog.rs index e9d4f30bbb..958110b09d 100644 --- a/parquet_file/src/catalog.rs +++ b/parquet_file/src/catalog.rs @@ -178,7 +178,7 @@ pub enum Error { DateTimeParseError { source: TryFromIntError }, #[snafu(display( - "Internal: Cannot parse encoding in serialized catalog: {} is not a valid variant", + "Internal: Cannot parse encoding in serialized catalog: {} is not a valid, specified variant", data ))] EncodingParseError { data: i32 }, @@ -785,7 +785,13 @@ fn parse_timestamp( /// Parse encoding from protobuf. fn parse_encoding(encoding: i32) -> Result { - proto::transaction::Encoding::from_i32(encoding).context(EncodingParseError { data: encoding }) + let parsed = proto::transaction::Encoding::from_i32(encoding) + .context(EncodingParseError { data: encoding })?; + if parsed == proto::transaction::Encoding::Unspecified { + Err(Error::EncodingParseError { data: encoding }) + } else { + Ok(parsed) + } } /// Key to address transactions. @@ -2151,7 +2157,7 @@ mod tests { .await; assert_eq!( res.unwrap_err().to_string(), - "Internal: Cannot parse encoding in serialized catalog: -1 is not a valid variant" + "Internal: Cannot parse encoding in serialized catalog: -1 is not a valid, specified variant" ); } @@ -2192,6 +2198,43 @@ mod tests { ); } + #[tokio::test] + async fn test_missing_encoding_in_transaction_file() { + let object_store = make_object_store(); + let server_id = make_server_id(); + let db_name = "db1"; + let trace = assert_single_catalog_inmem_works(&object_store, server_id, db_name).await; + + // break transaction file + assert!(trace.tkeys.len() >= 2); + let tkey = &trace.tkeys[0]; + let path = file_path( + &object_store, + server_id, + db_name, + tkey, + FileType::Transaction, + ); + let mut proto = load_transaction_proto(&object_store, &path).await.unwrap(); + proto.encoding = 0; + store_transaction_proto(&object_store, &path, &proto) + .await + .unwrap(); + + // loading catalog should fail now + let res = PreservedCatalog::::load( + Arc::clone(&object_store), + server_id, + db_name.to_string(), + (), + ) + .await; + assert_eq!( + res.unwrap_err().to_string(), + "Internal: Cannot parse encoding in serialized catalog: 0 is not a valid, specified variant" + ); + } + #[tokio::test] async fn test_wrong_encoding_in_checkpoint_file() { let object_store = make_object_store();