sea_query/extension/postgres/func/json_table/mod.rs
1use crate::*;
2use std::borrow::Cow;
3
4mod builder;
5pub use builder::Builder;
6mod column;
7pub use column::Column;
8mod exists_column;
9pub use exists_column::ExistsColumn;
10mod nested;
11pub use nested::NestedPath;
12pub(super) mod types;
13pub use types::*;
14
15impl PgFunc {
16 /// Create a `JSON_TABLE` function builder. Postgres only.
17 ///
18 /// # Examples
19 ///
20 /// Basic usage with simple columns:
21 /// ```
22 /// use sea_query::extension::postgres::*;
23 /// use sea_query::{tests_cfg::*, *};
24 ///
25 /// let query = Query::select()
26 /// .from_function(
27 /// PgFunc::json_table(
28 /// Expr::val(r#"[{"name": "John", "age": 30}, {"name": "Jane", "age": 25}]"#),
29 /// "$[*]"
30 /// )
31 /// .for_ordinality("row_number")
32 /// .column(json_table::Column::new("name", "text").path("$.name"))
33 /// .column(json_table::Column::new("age", "int").path("$.age"))
34 /// .build(),
35 /// "people"
36 /// )
37 /// .column("*")
38 /// .to_owned();
39 ///
40 /// assert_eq!(
41 /// query.to_string(PostgresQueryBuilder),
42 /// r#"SELECT "*" FROM JSON_TABLE('[{"name": "John", "age": 30}, {"name": "Jane", "age": 25}]', '$[*]' COLUMNS (row_number FOR ORDINALITY, name "text" PATH '$.name', age "int" PATH '$.age')) AS "people""#
43 /// );
44 /// ```
45 ///
46 /// With PASSING parameters and error handling:
47 /// ```
48 /// use sea_query::extension::postgres::*;
49 /// use sea_query::{tests_cfg::*, *};
50 ///
51 /// let query = Query::select()
52 /// .from_function(
53 /// PgFunc::json_table(
54 /// Expr::val(r#"{"users": [{"id": 1, "name": "John"}, {"id": 2, "name": "Jane"}]}"#),
55 /// "$.users[*] ? (@.id > $min_id)"
56 /// )
57 /// .passing(0, "min_id")
58 /// .column(json_table::Column::new("user_id", "int").path("$.id").null_on_error())
59 /// .column(json_table::Column::new("user_name", "text").path("$.name").default_on_empty(Expr::val("Unknown")))
60 /// .error_on_error()
61 /// .build(),
62 /// "filtered_users"
63 /// )
64 /// .column("*")
65 /// .to_owned();
66 ///
67 /// assert_eq!(
68 /// query.to_string(PostgresQueryBuilder),
69 /// r#"SELECT "*" FROM JSON_TABLE('{"users": [{"id": 1, "name": "John"}, {"id": 2, "name": "Jane"}]}', '$.users[*] ? (@.id > $min_id)' PASSING 0 AS min_id COLUMNS (user_id "int" PATH '$.id' NULL ON ERROR, user_name "text" PATH '$.name' DEFAULT 'Unknown' ON EMPTY) ERROR ON ERROR) AS "filtered_users""#
70 /// );
71 /// ```
72 ///
73 /// With NESTED PATH:
74 /// ```
75 /// use sea_query::extension::postgres::*;
76 /// use sea_query::{tests_cfg::*, *};
77 ///
78 /// let query = Query::select()
79 /// .from_function(
80 /// PgFunc::json_table(
81 /// Expr::val(r#"{"users": [{"name": "John", "phones": ["123", "456"]}, {"name": "Jane", "phones": ["789"]}]}"#),
82 /// "$.users[*]"
83 /// )
84 /// .column(json_table::Column::new("user_name", "text").path("$.name"))
85 /// .nested(
86 /// json_table::NestedPath::new("$.phones[*]")
87 /// .column(json_table::Column::new("phone", "text").path("$")),
88 /// )
89 /// .build(),
90 /// "user_phones"
91 /// )
92 /// .column("*")
93 /// .to_owned();
94 ///
95 /// assert_eq!(
96 /// query.to_string(PostgresQueryBuilder),
97 /// r#"SELECT "*" FROM JSON_TABLE('{"users": [{"name": "John", "phones": ["123", "456"]}, {"name": "Jane", "phones": ["789"]}]}', '$.users[*]' COLUMNS (user_name "text" PATH '$.name', NESTED PATH '$.phones[*]' COLUMNS (phone "text" PATH '$'))) AS "user_phones""#
98 /// );
99 /// ```
100 pub fn json_table(
101 context_item: impl Into<Expr>,
102 path_expression: impl Into<Cow<'static, str>>,
103 ) -> Builder {
104 Builder {
105 context_item: context_item.into(),
106 path_expression: path_expression.into(),
107 as_json_path_name: None,
108 passing: Vec::new(),
109 columns: Vec::new(),
110 on_error: None,
111 }
112 }
113}