127 lines
5.1 KiB
Rust
127 lines
5.1 KiB
Rust
use super::*;
|
|
use pretty_assertions::assert_eq;
|
|
use sea_query::extension::postgres::{PgFunc, json_table as pg_json_table};
|
|
|
|
#[test]
|
|
fn json_table_basic_columns() {
|
|
let query = Query::select()
|
|
.from_function(
|
|
PgFunc::json_table(
|
|
Expr::val(r#"[{"name": "John", "age": 30}, {"name": "Jane", "age": 25}]"#),
|
|
"$[*]",
|
|
)
|
|
.for_ordinality("row_number")
|
|
.column(pg_json_table::Column::new("name", "text").path("$.name"))
|
|
.column(pg_json_table::Column::new("age", "int").path("$.age"))
|
|
.build(),
|
|
"people",
|
|
)
|
|
.column("*")
|
|
.to_owned();
|
|
|
|
assert_eq!(
|
|
query.to_string(PostgresQueryBuilder),
|
|
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""#
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn json_table_passing_and_error_handling() {
|
|
let query = Query::select()
|
|
.from_function(
|
|
PgFunc::json_table(
|
|
Expr::val(r#"{"users": [{"id": 1, "name": "John"}, {"id": 2, "name": "Jane"}]}"#),
|
|
"$.users[*] ? (@.id > $min_id)",
|
|
)
|
|
.passing(0, "min_id")
|
|
.column(
|
|
pg_json_table::Column::new("user_id", "int")
|
|
.path("$.id")
|
|
.null_on_error(),
|
|
)
|
|
.column(
|
|
pg_json_table::Column::new("user_name", "text")
|
|
.path("$.name")
|
|
.default_on_empty(Expr::val("Unknown")),
|
|
)
|
|
.error_on_error()
|
|
.build(),
|
|
"filtered_users",
|
|
)
|
|
.column("*")
|
|
.to_owned();
|
|
|
|
assert_eq!(
|
|
query.to_string(PostgresQueryBuilder),
|
|
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""#
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn json_table_nested_path() {
|
|
let query = Query::select()
|
|
.from_function(
|
|
PgFunc::json_table(
|
|
Expr::val(
|
|
r#"{"users": [{"name": "John", "phones": ["123", "456"]}, {"name": "Jane", "phones": ["789"]}]}"#,
|
|
),
|
|
"$.users[*]",
|
|
)
|
|
.column(pg_json_table::Column::new("user_name", "text").path("$.name"))
|
|
.nested(
|
|
pg_json_table::NestedPath::new("$.phones[*]")
|
|
.column(pg_json_table::Column::new("phone", "text").path("$")),
|
|
)
|
|
.build(),
|
|
"user_phones",
|
|
)
|
|
.column("*")
|
|
.to_owned();
|
|
|
|
assert_eq!(
|
|
query.to_string(PostgresQueryBuilder),
|
|
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""#
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn json_table_nested_path_recursion_and_siblings() {
|
|
let query = Query::select()
|
|
.from_function(
|
|
PgFunc::json_table(
|
|
Expr::cust(
|
|
r#"'{"favorites":[{"movies":[{"name":"One","director":"John Doe"}],"books":[{"name":"Mystery","authors":[{"name":"Brown Dan"}]}]}]}'::json"#,
|
|
),
|
|
"$.favorites[*]",
|
|
)
|
|
.for_ordinality("user_id")
|
|
.nested(
|
|
pg_json_table::NestedPath::new("$.movies[*]")
|
|
.for_ordinality("movie_id")
|
|
.column(pg_json_table::Column::new("mname", "text").path("$.name"))
|
|
.column(pg_json_table::Column::new("director", "text")),
|
|
)
|
|
.nested(
|
|
pg_json_table::NestedPath::new("$.books[*]")
|
|
.for_ordinality("book_id")
|
|
.column(pg_json_table::Column::new("bname", "text").path("$.name"))
|
|
.nested(
|
|
pg_json_table::NestedPath::new("$.authors[*]")
|
|
.for_ordinality("author_id")
|
|
.column(
|
|
pg_json_table::Column::new("author_name", "text").path("$.name"),
|
|
),
|
|
),
|
|
)
|
|
.build(),
|
|
"jt",
|
|
)
|
|
.column("*")
|
|
.to_owned();
|
|
|
|
assert_eq!(
|
|
query.to_string(PostgresQueryBuilder),
|
|
r#"SELECT "*" FROM JSON_TABLE('{"favorites":[{"movies":[{"name":"One","director":"John Doe"}],"books":[{"name":"Mystery","authors":[{"name":"Brown Dan"}]}]}]}'::json, '$.favorites[*]' COLUMNS (user_id FOR ORDINALITY, NESTED PATH '$.movies[*]' COLUMNS (movie_id FOR ORDINALITY, mname "text" PATH '$.name', director "text"), NESTED PATH '$.books[*]' COLUMNS (book_id FOR ORDINALITY, bname "text" PATH '$.name', NESTED PATH '$.authors[*]' COLUMNS (author_id FOR ORDINALITY, author_name "text" PATH '$.name')))) AS "jt""#
|
|
);
|
|
}
|