@@ -248,7 +248,6 @@ pub trait TimestampProvider {
248248 id_bundle : & CollectionIdBundle ,
249249 when : & QueryWhen ,
250250 oracle_read_ts : Option < Timestamp > ,
251- compute_instance : ComputeInstanceId ,
252251 real_time_recency_ts : Option < Timestamp > ,
253252 isolation_level : & IsolationLevel ,
254253 timeline : & Option < Timeline > ,
@@ -413,13 +412,9 @@ pub trait TimestampProvider {
413412 if !constraints. lower_bound ( ) . less_equal ( & candidate)
414413 || constraints. upper_bound ( ) . less_than ( & candidate)
415414 {
416- // TODO: Generate a better error msg, which includes all the constraints.
417- coord_bail ! ( generate_timestamp_not_valid_error_msg(
418- id_bundle,
419- compute_instance,
420- read_holds,
421- candidate
422- ) ) ;
415+ return Err ( AdapterError :: ImpossibleTimestampConstraints {
416+ constraints : constraints. display ( timeline. as_ref ( ) ) . to_string ( ) ,
417+ } ) ;
423418 } else {
424419 candidate
425420 }
@@ -444,7 +439,6 @@ pub trait TimestampProvider {
444439 session : & Session ,
445440 id_bundle : & CollectionIdBundle ,
446441 when : & QueryWhen ,
447- compute_instance : ComputeInstanceId ,
448442 timeline_context : & TimelineContext ,
449443 oracle_read_ts : Option < Timestamp > ,
450444 real_time_recency_ts : Option < Timestamp > ,
@@ -460,7 +454,6 @@ pub trait TimestampProvider {
460454 session,
461455 id_bundle,
462456 when,
463- compute_instance,
464457 timeline_context,
465458 oracle_read_ts,
466459 real_time_recency_ts,
@@ -475,7 +468,6 @@ pub trait TimestampProvider {
475468 session : & Session ,
476469 id_bundle : & CollectionIdBundle ,
477470 when : & QueryWhen ,
478- compute_instance : ComputeInstanceId ,
479471 timeline_context : & TimelineContext ,
480472 oracle_read_ts : Option < Timestamp > ,
481473 real_time_recency_ts : Option < Timestamp > ,
@@ -514,7 +506,6 @@ pub trait TimestampProvider {
514506 id_bundle,
515507 when,
516508 oracle_read_ts,
517- compute_instance,
518509 real_time_recency_ts,
519510 isolation_level,
520511 & timeline,
@@ -580,36 +571,6 @@ pub trait TimestampProvider {
580571 }
581572}
582573
583- fn generate_timestamp_not_valid_error_msg (
584- id_bundle : & CollectionIdBundle ,
585- compute_instance : ComputeInstanceId ,
586- read_holds : & ReadHolds < mz_repr:: Timestamp > ,
587- candidate : mz_repr:: Timestamp ,
588- ) -> String {
589- let mut invalid = Vec :: new ( ) ;
590-
591- if let Some ( compute_ids) = id_bundle. compute_ids . get ( & compute_instance) {
592- for id in compute_ids {
593- let since = read_holds. since ( id) ;
594- if !since. less_equal ( & candidate) {
595- invalid. push ( ( * id, since) ) ;
596- }
597- }
598- }
599-
600- for id in id_bundle. storage_ids . iter ( ) {
601- let since = read_holds. since ( id) ;
602- if !since. less_equal ( & candidate) {
603- invalid. push ( ( * id, since) ) ;
604- }
605- }
606-
607- format ! (
608- "Timestamp ({}) is not valid for all inputs: {:?}" ,
609- candidate, invalid,
610- )
611- }
612-
613574impl Coordinator {
614575 pub ( crate ) async fn oracle_read_ts (
615576 & self ,
@@ -658,7 +619,6 @@ impl Coordinator {
658619 session,
659620 id_bundle,
660621 when,
661- compute_instance,
662622 timeline_context,
663623 oracle_read_ts,
664624 real_time_recency_ts,
@@ -688,7 +648,6 @@ impl Coordinator {
688648 session,
689649 id_bundle,
690650 when,
691- compute_instance,
692651 timeline_context,
693652 oracle_read_ts,
694653 real_time_recency_ts,
@@ -979,15 +938,21 @@ mod constraints {
979938 if !self . lower . is_empty ( ) {
980939 writeln ! ( f, "lower:" ) ?;
981940 for ( ts, reason) in & self . lower {
982- let ts = ts. iter ( ) . map ( |t| t. display ( timeline) ) . collect :: < Vec < _ > > ( ) ;
983- writeln ! ( f, " ({:?}): {:?}" , reason, ts) ?;
941+ let ts: Vec < _ > = ts
942+ . iter ( )
943+ . map ( |t| format ! ( "{}" , t. display( timeline) ) )
944+ . collect ( ) ;
945+ writeln ! ( f, " ({}): [{}]" , reason, ts. join( ", " ) ) ?;
984946 }
985947 }
986948 if !self . upper . is_empty ( ) {
987949 writeln ! ( f, "upper:" ) ?;
988950 for ( ts, reason) in & self . upper {
989- let ts = ts. iter ( ) . map ( |t| t. display ( timeline) ) . collect :: < Vec < _ > > ( ) ;
990- writeln ! ( f, " ({:?}): {:?}" , reason, ts) ?;
951+ let ts: Vec < _ > = ts
952+ . iter ( )
953+ . map ( |t| format ! ( "{}" , t. display( timeline) ) )
954+ . collect ( ) ;
955+ writeln ! ( f, " ({}): [{}]" , reason, ts. join( ", " ) ) ?;
991956 }
992957 }
993958 Ok ( ( ) )
@@ -1052,52 +1017,43 @@ mod constraints {
10521017 pub enum Reason {
10531018 /// A compute input at a compute instance.
10541019 /// This is something like an index or view
1055- /// that is mantained by compute.
1020+ /// that is maintained by compute.
10561021 ComputeInput ( Vec < ( ComputeInstanceId , GlobalId ) > ) ,
10571022 /// A storage input.
10581023 StorageInput ( Vec < GlobalId > ) ,
10591024 /// A specified isolation level and the timestamp it requires.
10601025 IsolationLevel ( IsolationLevel ) ,
1061- /// Real-time recency may constrains the timestamp from below.
1026+ /// Real-time recency may constrain the timestamp from below.
10621027 RealTimeRecency ,
10631028 /// The query expressed its own constraint on the timestamp.
10641029 QueryAsOf ,
10651030 }
10661031
1067- impl Debug for Reason {
1032+ impl fmt :: Display for Reason {
10681033 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
10691034 match self {
1070- Reason :: ComputeInput ( ids) => write_split_ids ( f, "ComputeInput" , ids) ,
1071- Reason :: StorageInput ( ids) => write_split_ids ( f, "StorageInput" , ids) ,
1035+ Reason :: ComputeInput ( ids) => {
1036+ let formatted: Vec < _ > =
1037+ ids. iter ( ) . map ( |( c, g) | format ! ( "({}, {})" , c, g) ) . collect ( ) ;
1038+ write ! ( f, "Indexed inputs: [{}]" , formatted. join( ", " ) )
1039+ }
1040+ Reason :: StorageInput ( ids) => {
1041+ let formatted: Vec < _ > = ids. iter ( ) . map ( |g| format ! ( "{}" , g) ) . collect ( ) ;
1042+ write ! ( f, "Storage inputs: [{}]" , formatted. join( ", " ) )
1043+ }
10721044 Reason :: IsolationLevel ( level) => {
1073- write ! ( f, "IsolationLevel( {:?}) " , level)
1045+ write ! ( f, "Isolation level: {:?}" , level)
10741046 }
10751047 Reason :: RealTimeRecency => {
1076- write ! ( f, "RealTimeRecency " )
1048+ write ! ( f, "Real-time recency " )
10771049 }
10781050 Reason :: QueryAsOf => {
1079- write ! ( f, "QueryAsOf " )
1051+ write ! ( f, "Query's AS OF " )
10801052 }
10811053 }
10821054 }
10831055 }
10841056
1085- //TODO: This is a bit of a hack to make the debug output of constraints more readable.
1086- //We should probably have a more structured way to do this.
1087- fn write_split_ids < T : Debug > ( f : & mut fmt:: Formatter , label : & str , ids : & [ T ] ) -> fmt:: Result {
1088- let ( ids, rest) = if ids. len ( ) > 10 {
1089- ids. split_at ( 10 )
1090- } else {
1091- let rest: & [ T ] = & [ ] ;
1092- ( ids, rest)
1093- } ;
1094- if rest. is_empty ( ) {
1095- write ! ( f, "{}({:?})" , label, ids)
1096- } else {
1097- write ! ( f, "{}({:?}, ... {} more)" , label, ids, rest. len( ) )
1098- }
1099- }
1100-
11011057 /// Given an interval [read, write) of timestamp options,
11021058 /// this expresses a preference for either end of the spectrum.
11031059 pub enum Preference {
@@ -1109,12 +1065,12 @@ mod constraints {
11091065 ///
11101066 /// The preference only relates to immediate query inputs,
11111067 /// but it could be extended to transitive inputs as well.
1112- /// For example, one could imagine prefering the freshest
1068+ /// For example, one could imagine preferring the freshest
11131069 /// data known to be ingested into Materialize, under the
11141070 /// premise that those answers should soon become available,
11151071 /// and may be more fresh than the immediate inputs.
11161072 FreshestAvailable ,
1117- /// Prefer the least valid timeastamp .
1073+ /// Prefer the least valid timestamp .
11181074 ///
11191075 /// This is useful when one has no expressed freshness
11201076 /// constraints, and wants to minimally impact others.
0 commit comments