Skip to main content

mz_expr/explain/
json.rs

1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Use of this software is governed by the Business Source License
4// included in the LICENSE file.
5//
6// As of the Change Date specified in that file, in accordance with
7// the Business Source License, use of this software will be governed
8// by the Apache License, Version 2.0.
9
10//! `EXPLAIN AS JSON` support for structures defined in this crate.
11
12use mz_repr::explain::json::DisplayJson;
13
14use crate::explain::{
15    ExplainMultiPlan, ExplainSinglePlan, ExplainSource, PushdownInfo, SourceOperators,
16};
17
18impl<'a, T: 'a> DisplayJson for ExplainSinglePlan<'a, T>
19where
20    T: serde::Serialize,
21{
22    fn to_serde_value(&self) -> serde_json::Result<serde_json::Value> {
23        serde_json::to_value(self.plan.plan)
24    }
25}
26
27impl<'a, T: 'a, O> DisplayJson for ExplainMultiPlan<'a, T, O>
28where
29    T: serde::Serialize,
30    O: SourceOperators,
31{
32    fn to_serde_value(&self) -> serde_json::Result<serde_json::Value> {
33        let plans = self
34            .plans
35            .iter()
36            .map(|(id, plan)| {
37                // TODO: fix plans with Constants
38                serde_json::json!({
39                    "id": id,
40                    "plan": &plan.plan
41                })
42            })
43            .collect::<Vec<_>>();
44
45        let sources = self
46            .sources
47            .iter()
48            .map(
49                |ExplainSource {
50                     id,
51                     op,
52                     pushdown_info,
53                 }| {
54                    let mut json = serde_json::json!({
55                        "id": id,
56                        "op": op,
57                    });
58
59                    if let Some(PushdownInfo {
60                        pushdown,
61                        lower_bounds,
62                        upper_bounds,
63                    }) = pushdown_info
64                    {
65                        let object = json.as_object_mut().unwrap();
66                        object.insert("pushdown".to_owned(), serde_json::json!(pushdown));
67                        if !lower_bounds.is_empty() || !upper_bounds.is_empty() {
68                            object.insert(
69                                "pushdown_temporal".to_owned(),
70                                serde_json::json!({
71                                    "lower_bounds": lower_bounds,
72                                    "upper_bounds": upper_bounds,
73                                }),
74                            );
75                        }
76                    }
77
78                    json
79                },
80            )
81            .collect::<Vec<_>>();
82
83        let result = serde_json::json!({ "plans": plans, "sources": sources });
84
85        Ok(result)
86    }
87}