1use std::collections::BTreeMap;
13use std::time::Duration;
14
15use mz_repr::adt::interval::Interval;
16use mz_repr::bytes::ByteSize;
17use mz_repr::{CatalogItemId, RelationVersionSelector, strconv};
18use mz_sql_parser::ast::{
19 ClusterAlterOptionValue, ClusterScheduleOptionValue, ConnectionDefaultAwsPrivatelink, Expr,
20 Ident, KafkaBroker, NetworkPolicyRuleDefinition, RefreshOptionValue, ReplicaDefinition,
21};
22use mz_storage_types::connections::string_or_secret::StringOrSecret;
23use serde::{Deserialize, Serialize};
24
25use crate::ast::{AstInfo, UnresolvedItemName, Value, WithOptionValue};
26use crate::catalog::SessionCatalog;
27use crate::names::{ResolvedDataType, ResolvedItemName};
28use crate::plan::{Aug, PlanError, literal};
29
30pub trait TryFromValue<T>: Sized {
31 fn try_from_value(v: T) -> Result<Self, PlanError>;
32
33 fn try_into_value(self, catalog: &dyn SessionCatalog) -> Option<T>;
34
35 fn name() -> String;
36}
37
38pub trait ImpliedValue: Sized {
39 fn implied_value() -> Result<Self, PlanError>;
40}
41
42#[derive(Copy, Clone, Debug)]
43pub struct Secret(CatalogItemId);
44
45impl From<Secret> for CatalogItemId {
46 fn from(secret: Secret) -> Self {
47 secret.0
48 }
49}
50
51impl TryFromValue<WithOptionValue<Aug>> for Secret {
52 fn try_from_value(v: WithOptionValue<Aug>) -> Result<Self, PlanError> {
53 match StringOrSecret::try_from_value(v)? {
54 StringOrSecret::Secret(id) => Ok(Secret(id)),
55 _ => sql_bail!("must provide a secret value"),
56 }
57 }
58
59 fn try_into_value(self, catalog: &dyn SessionCatalog) -> Option<WithOptionValue<Aug>> {
60 let secret = catalog.get_item(&self.0);
61 let name = ResolvedItemName::Item {
62 id: self.0,
63 qualifiers: secret.name().qualifiers.clone(),
64 full_name: catalog.resolve_full_name(secret.name()),
65 print_id: false,
66 version: RelationVersionSelector::Latest,
67 };
68 Some(WithOptionValue::Secret(name))
69 }
70
71 fn name() -> String {
72 "secret".to_string()
73 }
74}
75
76impl ImpliedValue for Secret {
77 fn implied_value() -> Result<Self, PlanError> {
78 sql_bail!("must provide a secret value")
79 }
80}
81
82#[derive(Copy, Clone, Debug)]
83pub struct Object(CatalogItemId);
84
85impl From<Object> for CatalogItemId {
86 fn from(obj: Object) -> Self {
87 obj.0
88 }
89}
90
91impl From<&Object> for CatalogItemId {
92 fn from(obj: &Object) -> Self {
93 obj.0
94 }
95}
96
97impl TryFromValue<WithOptionValue<Aug>> for Object {
98 fn try_from_value(v: WithOptionValue<Aug>) -> Result<Self, PlanError> {
99 Ok(match v {
100 WithOptionValue::Item(ResolvedItemName::Item { id, .. }) => Object(id),
101 _ => sql_bail!("must provide an object"),
102 })
103 }
104
105 fn try_into_value(self, catalog: &dyn SessionCatalog) -> Option<WithOptionValue<Aug>> {
106 let item = catalog.get_item(&self.0);
107 let name = ResolvedItemName::Item {
108 id: self.0,
109 qualifiers: item.name().qualifiers.clone(),
110 full_name: catalog.resolve_full_name(item.name()),
111 print_id: false,
112 version: RelationVersionSelector::Latest,
114 };
115 Some(WithOptionValue::Item(name))
116 }
117
118 fn name() -> String {
119 "object reference".to_string()
120 }
121}
122
123impl ImpliedValue for Object {
124 fn implied_value() -> Result<Self, PlanError> {
125 sql_bail!("must provide an object")
126 }
127}
128
129impl TryFromValue<WithOptionValue<Aug>> for Ident {
130 fn try_from_value(v: WithOptionValue<Aug>) -> Result<Self, PlanError> {
131 Ok(match v {
132 WithOptionValue::UnresolvedItemName(UnresolvedItemName(mut inner))
133 if inner.len() == 1 =>
134 {
135 inner.remove(0)
136 }
137 WithOptionValue::Ident(inner) => inner,
138 _ => sql_bail!("must provide an unqualified identifier"),
139 })
140 }
141
142 fn try_into_value(self, _catalog: &dyn SessionCatalog) -> Option<WithOptionValue<Aug>> {
143 Some(WithOptionValue::Ident(self))
144 }
145
146 fn name() -> String {
147 "identifier".to_string()
148 }
149}
150
151impl ImpliedValue for Ident {
152 fn implied_value() -> Result<Self, PlanError> {
153 sql_bail!("must provide an identifier")
154 }
155}
156
157impl TryFromValue<WithOptionValue<Aug>> for Expr<Aug> {
158 fn try_from_value(v: WithOptionValue<Aug>) -> Result<Self, PlanError> {
159 Ok(match v {
160 WithOptionValue::Expr(e) => e,
161 _ => sql_bail!("must provide an expr"),
162 })
163 }
164
165 fn try_into_value(self, _catalog: &dyn SessionCatalog) -> Option<WithOptionValue<Aug>> {
166 Some(WithOptionValue::Expr(self))
167 }
168
169 fn name() -> String {
170 "expression".to_string()
171 }
172}
173
174impl ImpliedValue for Expr<Aug> {
175 fn implied_value() -> Result<Self, PlanError> {
176 sql_bail!("must provide an expression")
177 }
178}
179
180impl TryFromValue<WithOptionValue<Aug>> for UnresolvedItemName {
181 fn try_from_value(v: WithOptionValue<Aug>) -> Result<Self, PlanError> {
182 Ok(match v {
183 WithOptionValue::UnresolvedItemName(name) => name,
184 WithOptionValue::Ident(inner) => UnresolvedItemName(vec![inner]),
185 _ => sql_bail!("must provide an object name"),
186 })
187 }
188
189 fn try_into_value(self, _catalog: &dyn SessionCatalog) -> Option<WithOptionValue<Aug>> {
190 Some(WithOptionValue::UnresolvedItemName(self))
191 }
192
193 fn name() -> String {
194 "object name".to_string()
195 }
196}
197
198impl ImpliedValue for UnresolvedItemName {
199 fn implied_value() -> Result<Self, PlanError> {
200 sql_bail!("must provide an object name")
201 }
202}
203
204impl TryFromValue<WithOptionValue<Aug>> for ResolvedDataType {
205 fn try_from_value(v: WithOptionValue<Aug>) -> Result<Self, PlanError> {
206 Ok(match v {
207 WithOptionValue::DataType(ty) => ty,
208 _ => sql_bail!("must provide a data type"),
209 })
210 }
211
212 fn try_into_value(self, _catalog: &dyn SessionCatalog) -> Option<WithOptionValue<Aug>> {
213 Some(WithOptionValue::DataType(self))
214 }
215
216 fn name() -> String {
217 "data type".to_string()
218 }
219}
220
221impl ImpliedValue for ResolvedDataType {
222 fn implied_value() -> Result<Self, PlanError> {
223 sql_bail!("must provide a data type")
224 }
225}
226
227impl TryFromValue<WithOptionValue<Aug>> for StringOrSecret {
228 fn try_from_value(v: WithOptionValue<Aug>) -> Result<Self, PlanError> {
229 Ok(match v {
230 WithOptionValue::Secret(ResolvedItemName::Item { id, .. }) => {
231 StringOrSecret::Secret(id)
232 }
233 v => StringOrSecret::String(String::try_from_value(v)?),
234 })
235 }
236
237 fn try_into_value(self, catalog: &dyn SessionCatalog) -> Option<WithOptionValue<Aug>> {
238 Some(match self {
239 StringOrSecret::Secret(secret) => Secret(secret).try_into_value(catalog)?,
240 StringOrSecret::String(s) => s.try_into_value(catalog)?,
241 })
242 }
243
244 fn name() -> String {
245 "string or secret".to_string()
246 }
247}
248
249impl ImpliedValue for StringOrSecret {
250 fn implied_value() -> Result<Self, PlanError> {
251 sql_bail!("must provide a string or secret value")
252 }
253}
254
255impl TryFromValue<Value> for Duration {
256 fn try_from_value(v: Value) -> Result<Self, PlanError> {
257 let interval = Interval::try_from_value(v)?;
258 Ok(interval.duration()?)
259 }
260
261 fn try_into_value(self, catalog: &dyn SessionCatalog) -> Option<Value> {
262 let interval = Interval::from_duration(&self)
263 .expect("planning ensured that this is convertible back to Interval");
264 interval.try_into_value(catalog)
265 }
266
267 fn name() -> String {
268 "interval".to_string()
269 }
270}
271
272impl ImpliedValue for Duration {
273 fn implied_value() -> Result<Self, PlanError> {
274 sql_bail!("must provide an interval value")
275 }
276}
277
278impl TryFromValue<Value> for ByteSize {
279 fn try_from_value(v: Value) -> Result<Self, PlanError> {
280 match v {
281 Value::Number(value) | Value::String(value) => Ok(value
282 .parse::<ByteSize>()
283 .map_err(|e| sql_err!("invalid bytes value: {e}"))?),
284 _ => sql_bail!("cannot use value as bytes"),
285 }
286 }
287
288 fn try_into_value(self, _catalog: &dyn SessionCatalog) -> Option<Value> {
289 Some(Value::String(self.to_string()))
290 }
291
292 fn name() -> String {
293 "bytes".to_string()
294 }
295}
296
297impl ImpliedValue for ByteSize {
298 fn implied_value() -> Result<Self, PlanError> {
299 sql_bail!("must provide a value for bytes")
300 }
301}
302
303impl TryFromValue<Value> for Interval {
304 fn try_from_value(v: Value) -> Result<Self, PlanError> {
305 match v {
306 Value::Interval(value) => literal::plan_interval(&value),
307 Value::Number(value) | Value::String(value) => Ok(strconv::parse_interval(&value)?),
308 _ => sql_bail!("cannot use value as interval"),
309 }
310 }
311
312 fn try_into_value(self, _catalog: &dyn SessionCatalog) -> Option<Value> {
313 let interval_value = literal::unplan_interval(&self);
314 Some(Value::Interval(interval_value))
315 }
316
317 fn name() -> String {
318 "interval".to_string()
319 }
320}
321
322impl ImpliedValue for Interval {
323 fn implied_value() -> Result<Self, PlanError> {
324 sql_bail!("must provide an interval value")
325 }
326}
327
328#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
329pub struct OptionalString(pub Option<String>);
330
331impl TryFromValue<Value> for OptionalString {
332 fn try_from_value(v: Value) -> Result<Self, PlanError> {
333 Ok(match v {
334 Value::Null => Self(None),
335 v => Self(Some(String::try_from_value(v)?)),
336 })
337 }
338
339 fn try_into_value(self, catalog: &dyn SessionCatalog) -> Option<Value> {
340 Some(match self.0 {
341 None => Value::Null,
342 Some(s) => s.try_into_value(catalog)?,
343 })
344 }
345
346 fn name() -> String {
347 "optional string".to_string()
348 }
349}
350
351impl ImpliedValue for OptionalString {
352 fn implied_value() -> Result<Self, PlanError> {
353 sql_bail!("must provide a string value")
354 }
355}
356
357#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Hash, Deserialize)]
358pub struct OptionalDuration(pub Option<Duration>);
359
360impl From<Duration> for OptionalDuration {
361 fn from(i: Duration) -> OptionalDuration {
362 let inner = if i == Duration::ZERO { None } else { Some(i) };
364 OptionalDuration(inner)
365 }
366}
367
368impl TryFromValue<Value> for OptionalDuration {
369 fn try_from_value(v: Value) -> Result<Self, PlanError> {
370 Ok(match v {
371 Value::Null => OptionalDuration(None),
372 v => Duration::try_from_value(v)?.into(),
373 })
374 }
375
376 fn try_into_value(self, catalog: &dyn SessionCatalog) -> Option<Value> {
377 Some(match self.0 {
378 None => Value::Null,
379 Some(duration) => duration.try_into_value(catalog)?,
380 })
381 }
382
383 fn name() -> String {
384 "optional interval".to_string()
385 }
386}
387
388impl ImpliedValue for OptionalDuration {
389 fn implied_value() -> Result<Self, PlanError> {
390 sql_bail!("must provide an interval value")
391 }
392}
393
394impl TryFromValue<Value> for String {
395 fn try_from_value(v: Value) -> Result<Self, PlanError> {
396 match v {
397 Value::String(v) => Ok(v),
398 _ => sql_bail!("cannot use value as string"),
399 }
400 }
401
402 fn try_into_value(self, _catalog: &dyn SessionCatalog) -> Option<Value> {
403 Some(Value::String(self))
404 }
405
406 fn name() -> String {
407 "text".to_string()
408 }
409}
410
411impl ImpliedValue for String {
412 fn implied_value() -> Result<Self, PlanError> {
413 sql_bail!("must provide a string value")
414 }
415}
416
417impl TryFromValue<Value> for bool {
418 fn try_from_value(v: Value) -> Result<Self, PlanError> {
419 match v {
420 Value::Boolean(v) => Ok(v),
421 _ => sql_bail!("cannot use value as boolean"),
422 }
423 }
424
425 fn try_into_value(self, _catalog: &dyn SessionCatalog) -> Option<Value> {
426 Some(Value::Boolean(self))
427 }
428
429 fn name() -> String {
430 "bool".to_string()
431 }
432}
433
434impl ImpliedValue for bool {
435 fn implied_value() -> Result<Self, PlanError> {
436 Ok(true)
437 }
438}
439
440impl TryFromValue<Value> for f64 {
441 fn try_from_value(v: Value) -> Result<Self, PlanError> {
442 match v {
443 Value::Number(v) => v
444 .parse::<f64>()
445 .map_err(|e| sql_err!("invalid numeric value: {e}")),
446 _ => sql_bail!("cannot use value as number"),
447 }
448 }
449
450 fn try_into_value(self, _catalog: &dyn SessionCatalog) -> Option<Value> {
451 Some(Value::Number(self.to_string()))
452 }
453
454 fn name() -> String {
455 "float8".to_string()
456 }
457}
458
459impl ImpliedValue for f64 {
460 fn implied_value() -> Result<Self, PlanError> {
461 sql_bail!("must provide a float value")
462 }
463}
464
465impl TryFromValue<Value> for i32 {
466 fn try_from_value(v: Value) -> Result<Self, PlanError> {
467 match v {
468 Value::Number(v) => v
469 .parse::<i32>()
470 .map_err(|e| sql_err!("invalid numeric value: {e}")),
471 _ => sql_bail!("cannot use value as number"),
472 }
473 }
474
475 fn try_into_value(self, _catalog: &dyn SessionCatalog) -> Option<Value> {
476 Some(Value::Number(self.to_string()))
477 }
478
479 fn name() -> String {
480 "int".to_string()
481 }
482}
483
484impl ImpliedValue for i32 {
485 fn implied_value() -> Result<Self, PlanError> {
486 sql_bail!("must provide an integer value")
487 }
488}
489
490impl TryFromValue<Value> for i64 {
491 fn try_from_value(v: Value) -> Result<Self, PlanError> {
492 match v {
493 Value::Number(v) => v
494 .parse::<i64>()
495 .map_err(|e| sql_err!("invalid numeric value: {e}")),
496 _ => sql_bail!("cannot use value as number"),
497 }
498 }
499 fn try_into_value(self, _catalog: &dyn SessionCatalog) -> Option<Value> {
500 Some(Value::Number(self.to_string()))
501 }
502 fn name() -> String {
503 "int8".to_string()
504 }
505}
506
507impl ImpliedValue for i64 {
508 fn implied_value() -> Result<Self, PlanError> {
509 sql_bail!("must provide an integer value")
510 }
511}
512
513impl TryFromValue<Value> for u16 {
514 fn try_from_value(v: Value) -> Result<Self, PlanError> {
515 match v {
516 Value::Number(v) => v
517 .parse::<u16>()
518 .map_err(|e| sql_err!("invalid numeric value: {e}")),
519 _ => sql_bail!("cannot use value as number"),
520 }
521 }
522 fn try_into_value(self, _catalog: &dyn SessionCatalog) -> Option<Value> {
523 Some(Value::Number(self.to_string()))
524 }
525 fn name() -> String {
526 "uint2".to_string()
527 }
528}
529
530impl ImpliedValue for u16 {
531 fn implied_value() -> Result<Self, PlanError> {
532 sql_bail!("must provide an integer value")
533 }
534}
535
536impl TryFromValue<Value> for u32 {
537 fn try_from_value(v: Value) -> Result<Self, PlanError> {
538 match v {
539 Value::Number(v) => v
540 .parse::<u32>()
541 .map_err(|e| sql_err!("invalid numeric value: {e}")),
542 _ => sql_bail!("cannot use value as number"),
543 }
544 }
545 fn try_into_value(self, _catalog: &dyn SessionCatalog) -> Option<Value> {
546 Some(Value::Number(self.to_string()))
547 }
548 fn name() -> String {
549 "uint4".to_string()
550 }
551}
552
553impl ImpliedValue for u32 {
554 fn implied_value() -> Result<Self, PlanError> {
555 sql_bail!("must provide an integer value")
556 }
557}
558
559impl TryFromValue<Value> for u64 {
560 fn try_from_value(v: Value) -> Result<Self, PlanError> {
561 match v {
562 Value::Number(v) => v
563 .parse::<u64>()
564 .map_err(|e| sql_err!("invalid unsigned numeric value: {e}")),
565 _ => sql_bail!("cannot use value as number"),
566 }
567 }
568 fn try_into_value(self, _catalog: &dyn SessionCatalog) -> Option<Value> {
569 Some(Value::Number(self.to_string()))
570 }
571 fn name() -> String {
572 "uint8".to_string()
573 }
574}
575
576impl ImpliedValue for u64 {
577 fn implied_value() -> Result<Self, PlanError> {
578 sql_bail!("must provide an unsigned integer value")
579 }
580}
581
582impl<V: TryFromValue<WithOptionValue<Aug>>> TryFromValue<WithOptionValue<Aug>> for Vec<V> {
583 fn try_from_value(v: WithOptionValue<Aug>) -> Result<Self, PlanError> {
584 match v {
585 WithOptionValue::Sequence(a) => {
586 let mut out = Vec::with_capacity(a.len());
587 for i in a {
588 out.push(
589 V::try_from_value(i)
590 .map_err(|_| anyhow::anyhow!("cannot use value in array"))?,
591 )
592 }
593 Ok(out)
594 }
595 _ => sql_bail!("cannot use value as array"),
596 }
597 }
598
599 fn try_into_value(self, catalog: &dyn SessionCatalog) -> Option<WithOptionValue<Aug>> {
600 Some(WithOptionValue::Sequence(
601 self.into_iter()
602 .map(|v| v.try_into_value(catalog))
603 .collect::<Option<_>>()?,
604 ))
605 }
606
607 fn name() -> String {
608 format!("array of {}", V::name())
609 }
610}
611
612impl<V: ImpliedValue> ImpliedValue for Vec<V> {
613 fn implied_value() -> Result<Self, PlanError> {
614 sql_bail!("must provide an array value")
615 }
616}
617
618impl<T: AstInfo, V: TryFromValue<WithOptionValue<T>>> TryFromValue<WithOptionValue<T>>
619 for Option<V>
620{
621 fn try_from_value(v: WithOptionValue<T>) -> Result<Self, PlanError> {
622 Ok(Some(V::try_from_value(v)?))
623 }
624
625 fn try_into_value(self, catalog: &dyn SessionCatalog) -> Option<WithOptionValue<T>> {
626 match self {
627 Some(v) => v.try_into_value(catalog),
628 None => None,
629 }
630 }
631
632 fn name() -> String {
633 format!("optional {}", V::name())
634 }
635}
636
637impl<V: ImpliedValue> ImpliedValue for Option<V> {
638 fn implied_value() -> Result<Self, PlanError> {
639 Ok(Some(V::implied_value()?))
640 }
641}
642
643impl<V: TryFromValue<Value>, T: AstInfo + std::fmt::Debug> TryFromValue<WithOptionValue<T>> for V {
644 fn try_from_value(v: WithOptionValue<T>) -> Result<Self, PlanError> {
645 match v {
646 WithOptionValue::Value(v) => V::try_from_value(v),
647 WithOptionValue::UnresolvedItemName(UnresolvedItemName(mut inner))
648 if inner.len() == 1 =>
649 {
650 V::try_from_value(Value::String(inner.remove(0).into_string()))
651 }
652 WithOptionValue::Ident(v) => V::try_from_value(Value::String(v.into_string())),
653 WithOptionValue::RetainHistoryFor(v) => V::try_from_value(v),
654 WithOptionValue::Sequence(_)
655 | WithOptionValue::Map(_)
656 | WithOptionValue::Item(_)
657 | WithOptionValue::UnresolvedItemName(_)
658 | WithOptionValue::Secret(_)
659 | WithOptionValue::DataType(_)
660 | WithOptionValue::Expr(_)
661 | WithOptionValue::ClusterReplicas(_)
662 | WithOptionValue::ConnectionKafkaBroker(_)
663 | WithOptionValue::ConnectionAwsPrivatelink(_)
664 | WithOptionValue::ClusterAlterStrategy(_)
665 | WithOptionValue::Refresh(_)
666 | WithOptionValue::ClusterScheduleOptionValue(_)
667 | WithOptionValue::NetworkPolicyRules(_) => sql_bail!(
668 "incompatible value types: cannot convert {} to {}",
669 match v {
670 WithOptionValue::Value(_) => unreachable!(),
672 WithOptionValue::RetainHistoryFor(_) => unreachable!(),
673 WithOptionValue::ClusterAlterStrategy(_) => "cluster alter strategy",
674 WithOptionValue::Sequence(_) => "sequences",
675 WithOptionValue::Map(_) => "maps",
676 WithOptionValue::Item(_) => "object references",
677 WithOptionValue::UnresolvedItemName(_) => "object names",
678 WithOptionValue::Ident(_) => "identifiers",
679 WithOptionValue::Secret(_) => "secrets",
680 WithOptionValue::DataType(_) => "data types",
681 WithOptionValue::Expr(_) => "exprs",
682 WithOptionValue::ClusterReplicas(_) => "cluster replicas",
683 WithOptionValue::ConnectionKafkaBroker(_) => "connection kafka brokers",
684 WithOptionValue::ConnectionAwsPrivatelink(_) => "connection kafka brokers",
685 WithOptionValue::Refresh(_) => "refresh option values",
686 WithOptionValue::ClusterScheduleOptionValue(_) => "cluster schedule",
687 WithOptionValue::NetworkPolicyRules(_) => "network policy rules",
688 },
689 V::name()
690 ),
691 }
692 }
693
694 fn try_into_value(self, catalog: &dyn SessionCatalog) -> Option<WithOptionValue<T>> {
695 Some(WithOptionValue::Value(self.try_into_value(catalog)?))
696 }
697
698 fn name() -> String {
699 V::name()
700 }
701}
702
703impl<T, V: TryFromValue<T> + ImpliedValue> TryFromValue<Option<T>> for V {
704 fn try_from_value(v: Option<T>) -> Result<Self, PlanError> {
705 match v {
706 Some(v) => V::try_from_value(v),
707 None => V::implied_value(),
708 }
709 }
710
711 fn try_into_value(self, catalog: &dyn SessionCatalog) -> Option<Option<T>> {
712 Some(Some(self.try_into_value(catalog)?))
713 }
714
715 fn name() -> String {
716 V::name()
717 }
718}
719
720impl TryFromValue<WithOptionValue<Aug>> for Vec<ReplicaDefinition<Aug>> {
721 fn try_from_value(v: WithOptionValue<Aug>) -> Result<Self, PlanError> {
722 match v {
723 WithOptionValue::ClusterReplicas(replicas) => Ok(replicas),
724 _ => sql_bail!("cannot use value as cluster replicas"),
725 }
726 }
727
728 fn try_into_value(self, _catalog: &dyn SessionCatalog) -> Option<WithOptionValue<Aug>> {
729 Some(WithOptionValue::ClusterReplicas(self))
730 }
731
732 fn name() -> String {
733 "cluster replicas".to_string()
734 }
735}
736
737impl ImpliedValue for Vec<ReplicaDefinition<Aug>> {
738 fn implied_value() -> Result<Self, PlanError> {
739 sql_bail!("must provide a set of cluster replicas")
740 }
741}
742
743impl TryFromValue<WithOptionValue<Aug>> for Vec<KafkaBroker<Aug>> {
744 fn try_from_value(v: WithOptionValue<Aug>) -> Result<Self, PlanError> {
745 let mut out = vec![];
746 match v {
747 WithOptionValue::ConnectionKafkaBroker(broker) => {
748 out.push(broker);
749 }
750 WithOptionValue::Sequence(values) => {
751 for value in values {
752 out.extend(Self::try_from_value(value)?);
753 }
754 }
755 _ => sql_bail!("cannot use value as a kafka broker"),
756 }
757 Ok(out)
758 }
759
760 fn try_into_value(self, _catalog: &dyn SessionCatalog) -> Option<WithOptionValue<Aug>> {
761 Some(WithOptionValue::Sequence(
762 self.into_iter()
763 .map(WithOptionValue::ConnectionKafkaBroker)
764 .collect(),
765 ))
766 }
767
768 fn name() -> String {
769 "kafka broker".to_string()
770 }
771}
772
773impl ImpliedValue for Vec<KafkaBroker<Aug>> {
774 fn implied_value() -> Result<Self, PlanError> {
775 sql_bail!("must provide a kafka broker")
776 }
777}
778
779impl TryFromValue<WithOptionValue<Aug>> for RefreshOptionValue<Aug> {
780 fn try_from_value(v: WithOptionValue<Aug>) -> Result<Self, PlanError> {
781 if let WithOptionValue::Refresh(r) = v {
782 Ok(r)
783 } else {
784 sql_bail!("cannot use value `{}` for a refresh option", v)
785 }
786 }
787
788 fn try_into_value(self, _catalog: &dyn SessionCatalog) -> Option<WithOptionValue<Aug>> {
789 Some(WithOptionValue::Refresh(self))
790 }
791
792 fn name() -> String {
793 "refresh option value".to_string()
794 }
795}
796
797impl ImpliedValue for RefreshOptionValue<Aug> {
798 fn implied_value() -> Result<Self, PlanError> {
799 sql_bail!("must provide a refresh option value")
800 }
801}
802
803impl TryFromValue<WithOptionValue<Aug>> for ConnectionDefaultAwsPrivatelink<Aug> {
804 fn try_from_value(v: WithOptionValue<Aug>) -> Result<Self, PlanError> {
805 if let WithOptionValue::ConnectionAwsPrivatelink(r) = v {
806 Ok(r)
807 } else {
808 sql_bail!("cannot use value `{}` for a privatelink", v)
809 }
810 }
811
812 fn try_into_value(self, _catalog: &dyn SessionCatalog) -> Option<WithOptionValue<Aug>> {
813 Some(WithOptionValue::ConnectionAwsPrivatelink(self))
814 }
815
816 fn name() -> String {
817 "privatelink option value".to_string()
818 }
819}
820
821impl ImpliedValue for ConnectionDefaultAwsPrivatelink<Aug> {
822 fn implied_value() -> Result<Self, PlanError> {
823 sql_bail!("must provide a value")
824 }
825}
826
827impl ImpliedValue for ClusterScheduleOptionValue {
828 fn implied_value() -> Result<Self, PlanError> {
829 sql_bail!("must provide a cluster schedule option value")
830 }
831}
832
833impl ImpliedValue for ClusterAlterOptionValue<Aug> {
834 fn implied_value() -> Result<Self, PlanError> {
835 sql_bail!("must provide a value")
836 }
837}
838
839impl TryFromValue<WithOptionValue<Aug>> for ClusterScheduleOptionValue {
840 fn try_from_value(v: WithOptionValue<Aug>) -> Result<Self, PlanError> {
841 if let WithOptionValue::ClusterScheduleOptionValue(r) = v {
842 Ok(r)
843 } else {
844 sql_bail!("cannot use value `{}` for a cluster schedule", v)
845 }
846 }
847
848 fn try_into_value(self, _catalog: &dyn SessionCatalog) -> Option<WithOptionValue<Aug>> {
849 Some(WithOptionValue::ClusterScheduleOptionValue(self))
850 }
851
852 fn name() -> String {
853 "cluster schedule option value".to_string()
854 }
855}
856
857impl<V: ImpliedValue> ImpliedValue for BTreeMap<String, V> {
858 fn implied_value() -> Result<Self, PlanError> {
859 sql_bail!("must provide a map of key-value pairs")
860 }
861}
862
863impl<V: TryFromValue<WithOptionValue<Aug>>> TryFromValue<WithOptionValue<Aug>>
864 for BTreeMap<String, V>
865{
866 fn try_from_value(v: WithOptionValue<Aug>) -> Result<Self, PlanError> {
867 match v {
868 WithOptionValue::Map(a) => a
869 .into_iter()
870 .map(|(k, v)| Ok((k, V::try_from_value(v)?)))
871 .collect(),
872 _ => sql_bail!("cannot use value as map"),
873 }
874 }
875
876 fn try_into_value(self, catalog: &dyn SessionCatalog) -> Option<WithOptionValue<Aug>> {
877 Some(WithOptionValue::Map(
878 self.into_iter()
879 .map(|(k, v)| {
880 let v = v.try_into_value(catalog);
881 v.map(|v| (k, v))
882 })
883 .collect::<Option<_>>()?,
884 ))
885 }
886
887 fn name() -> String {
888 format!("map of string to {}", V::name())
889 }
890}
891
892impl TryFromValue<WithOptionValue<Aug>> for ClusterAlterOptionValue<Aug> {
893 fn try_from_value(v: WithOptionValue<Aug>) -> Result<Self, PlanError> {
894 if let WithOptionValue::ClusterAlterStrategy(r) = v {
895 Ok(r)
896 } else {
897 sql_bail!("cannot use value `{}` for a cluster alter strategy", v)
898 }
899 }
900
901 fn name() -> String {
902 "cluster alter strategyoption value".to_string()
903 }
904
905 fn try_into_value(self, _catalog: &dyn SessionCatalog) -> Option<WithOptionValue<Aug>> {
906 Some(WithOptionValue::ClusterAlterStrategy(self))
907 }
908}
909
910impl TryFromValue<WithOptionValue<Aug>> for Vec<NetworkPolicyRuleDefinition<Aug>> {
911 fn try_from_value(v: WithOptionValue<Aug>) -> Result<Self, PlanError> {
912 match v {
913 WithOptionValue::NetworkPolicyRules(rules) => Ok(rules),
914 _ => sql_bail!("cannot use value as cluster replicas"),
915 }
916 }
917
918 fn try_into_value(self, _catalog: &dyn SessionCatalog) -> Option<WithOptionValue<Aug>> {
919 Some(WithOptionValue::NetworkPolicyRules(self))
920 }
921
922 fn name() -> String {
923 "network policy rules".to_string()
924 }
925}
926
927impl ImpliedValue for Vec<NetworkPolicyRuleDefinition<Aug>> {
928 fn implied_value() -> Result<Self, PlanError> {
929 sql_bail!("must provide a set of network policy rules")
930 }
931}