@@ -253,33 +253,30 @@ fn validate_static_schema(
253253 custom_partition : & str ,
254254 static_schema_flag : & str ,
255255) -> Result < Arc < Schema > , CreateStreamError > {
256- let mut schema = Arc :: new ( Schema :: empty ( ) ) ;
257- if !body. is_empty ( ) && static_schema_flag == "true" {
258- let static_schema: StaticSchema = serde_json:: from_slice ( body) ?;
259-
260- let parsed_schema = convert_static_schema_to_arrow_schema (
261- static_schema. clone ( ) ,
262- time_partition,
263- custom_partition,
264- ) ;
265- if let Ok ( parsed_schema) = parsed_schema {
266- schema = parsed_schema;
267- } else {
256+ if static_schema_flag == "true" {
257+ if body. is_empty ( ) {
268258 return Err ( CreateStreamError :: Custom {
269- msg : format ! ( "Unable to commit static schema, logstream {stream_name} not created" ) ,
259+ msg : format ! (
260+ "Please provide schema in the request body for static schema logstream {stream_name}"
261+ ) ,
270262 status : StatusCode :: BAD_REQUEST ,
271263 } ) ;
272264 }
273- } else if body. is_empty ( ) && static_schema_flag == "true" {
274- return Err ( CreateStreamError :: Custom {
265+
266+ let static_schema: StaticSchema = serde_json:: from_slice ( body) ?;
267+ let parsed_schema =
268+ convert_static_schema_to_arrow_schema ( static_schema, time_partition, custom_partition)
269+ . map_err ( |_| CreateStreamError :: Custom {
275270 msg : format ! (
276- "Please provide schema in the request body for static schema logstream {stream_name}"
271+ "Unable to commit static schema, logstream {stream_name} not created "
277272 ) ,
278273 status : StatusCode :: BAD_REQUEST ,
279- } ) ;
274+ } ) ?;
275+
276+ return Ok ( parsed_schema) ;
280277 }
281278
282- Ok ( schema )
279+ Ok ( Arc :: new ( Schema :: empty ( ) ) )
283280}
284281
285282async fn create_update_stream (
@@ -291,81 +288,71 @@ async fn create_update_stream(
291288 fetch_headers_from_put_stream_request ( req) ;
292289
293290 if metadata:: STREAM_INFO . stream_exists ( stream_name) && update_stream != "true" {
294- // Error if the log stream already exists
295291 return Err ( StreamError :: Custom {
296- msg : format ! (
297- "Logstream {stream_name} already exists, please create a new log stream with unique name"
298- ) ,
299- status : StatusCode :: BAD_REQUEST ,
300- } ) ;
301- }
302-
303- if !time_partition. is_empty ( ) && update_stream == "true" {
304- return Err ( StreamError :: Custom {
305- msg : "Altering the time partition of an existing stream is restricted." . to_string ( ) ,
292+ msg : format ! (
293+ "Logstream {stream_name} already exists, please create a new log stream with unique name"
294+ ) ,
306295 status : StatusCode :: BAD_REQUEST ,
307296 } ) ;
308297 }
309- let mut time_partition_in_days: & str = "" ;
310- if !time_partition_limit. is_empty ( ) {
311- let time_partition_days = validate_time_partition_limit ( & time_partition_limit) ;
312- if let Err ( err) = time_partition_days {
313- return Err ( StreamError :: CreateStream ( err) ) ;
314- } else {
315- time_partition_in_days = time_partition_days. unwrap ( ) ;
316- if update_stream == "true" {
317- if let Err ( err) = update_time_partition_limit_in_stream (
318- stream_name. to_string ( ) ,
319- time_partition_in_days,
320- )
321- . await
322- {
323- return Err ( StreamError :: CreateStream ( err) ) ;
324- }
325- return Ok ( ( ) ) ;
326- }
298+
299+ if update_stream == "true" {
300+ if !STREAM_INFO . stream_exists ( stream_name) {
301+ return Err ( StreamError :: StreamNotFound ( stream_name. to_string ( ) ) ) ;
302+ }
303+ if !time_partition. is_empty ( ) {
304+ return Err ( StreamError :: Custom {
305+ msg : "Altering the time partition of an existing stream is restricted." . to_string ( ) ,
306+ status : StatusCode :: BAD_REQUEST ,
307+ } ) ;
327308 }
328- }
329309
330- if !static_schema_flag. is_empty ( ) && update_stream == "true" {
331- return Err ( StreamError :: Custom {
332- msg : "Altering the schema of an existing stream is restricted." . to_string ( ) ,
333- status : StatusCode :: BAD_REQUEST ,
334- } ) ;
335- }
310+ if !static_schema_flag. is_empty ( ) {
311+ return Err ( StreamError :: Custom {
312+ msg : "Altering the schema of an existing stream is restricted." . to_string ( ) ,
313+ status : StatusCode :: BAD_REQUEST ,
314+ } ) ;
315+ }
336316
337- if !custom_partition. is_empty ( ) {
338- if let Err ( err) = validate_custom_partition ( & custom_partition) {
339- return Err ( StreamError :: CreateStream ( err) ) ;
317+ if !time_partition_limit. is_empty ( ) {
318+ let time_partition_days = validate_time_partition_limit ( & time_partition_limit) ?;
319+ update_time_partition_limit_in_stream ( stream_name. to_string ( ) , time_partition_days)
320+ . await ?;
321+ return Ok ( ( ) ) ;
340322 }
341- if update_stream == "true" {
342- if let Err ( err) =
343- update_custom_partition_in_stream ( stream_name. to_string ( ) , & custom_partition) . await
344- {
345- return Err ( StreamError :: CreateStream ( err) ) ;
346- }
323+
324+ if !custom_partition. is_empty ( ) {
325+ validate_custom_partition ( & custom_partition) ?;
326+ update_custom_partition_in_stream ( stream_name. to_string ( ) , & custom_partition) . await ?;
327+ return Ok ( ( ) ) ;
328+ } else {
329+ update_custom_partition_in_stream ( stream_name. to_string ( ) , "" ) . await ?;
347330 return Ok ( ( ) ) ;
348331 }
349332 }
333+ let mut time_partition_in_days = "" ;
334+ if !time_partition_limit. is_empty ( ) {
335+ time_partition_in_days = validate_time_partition_limit ( & time_partition_limit) ?;
336+ }
337+ if !custom_partition. is_empty ( ) {
338+ validate_custom_partition ( & custom_partition) ?;
339+ }
350340
351341 let schema = validate_static_schema (
352342 body,
353343 stream_name,
354344 & time_partition,
355345 & custom_partition,
356346 & static_schema_flag,
357- ) ;
358- if let Err ( err) = schema {
359- return Err ( StreamError :: CreateStream ( err) ) ;
360- }
347+ ) ?;
361348
362349 create_stream (
363350 stream_name. to_string ( ) ,
364351 & time_partition,
365352 time_partition_in_days,
366353 & custom_partition,
367354 & static_schema_flag,
368- schema. unwrap ( ) ,
355+ schema,
369356 false ,
370357 )
371358 . await ?;
@@ -753,6 +740,36 @@ pub async fn update_custom_partition_in_stream(
753740 stream_name : String ,
754741 custom_partition : & str ,
755742) -> Result < ( ) , CreateStreamError > {
743+ let static_schema_flag = STREAM_INFO . get_static_schema_flag ( & stream_name) . unwrap ( ) ;
744+ if static_schema_flag. is_some ( ) {
745+ let schema = STREAM_INFO . schema ( & stream_name) . unwrap ( ) ;
746+
747+ if !custom_partition. is_empty ( ) {
748+ let custom_partition_list = custom_partition. split ( ',' ) . collect :: < Vec < & str > > ( ) ;
749+ let custom_partition_exists: HashMap < _ , _ > = custom_partition_list
750+ . iter ( )
751+ . map ( |& partition| {
752+ (
753+ partition. to_string ( ) ,
754+ schema
755+ . fields ( )
756+ . iter ( )
757+ . any ( |field| field. name ( ) == partition) ,
758+ )
759+ } )
760+ . collect ( ) ;
761+
762+ for partition in & custom_partition_list {
763+ if !custom_partition_exists[ * partition] {
764+ return Err ( CreateStreamError :: Custom {
765+ msg : format ! ( "custom partition field {} does not exist in the schema for the stream {}" , partition, stream_name) ,
766+ status : StatusCode :: BAD_REQUEST ,
767+ } ) ;
768+ }
769+ }
770+ }
771+ }
772+
756773 let storage = CONFIG . storage ( ) . get_object_store ( ) ;
757774 if let Err ( err) = storage
758775 . update_custom_partition_in_stream ( & stream_name, custom_partition)
0 commit comments