diff --git a/.github/workflows/e2e-tests.yaml b/.github/workflows/e2e-tests.yaml index 416ef6a28..6ac32ed48 100644 --- a/.github/workflows/e2e-tests.yaml +++ b/.github/workflows/e2e-tests.yaml @@ -69,9 +69,9 @@ jobs: ${{ github.workspace }}/ndc-postgres/result/bin/ndc-postgres run: | npm install - just start-postgres-dependencies start-apollo-subgraph + just start-postgres_v0_2-dependencies start-apollo-subgraph trap 'just stop-everything' EXIT - RUST_LOG=DEBUG ./crates/postgres/static/run-postgres-tests.sh '.*' "$NDC_POSTGRES_BINARY" "$ENGINE_BINARY" + RUST_LOG=DEBUG ./crates/postgres_v0_2/static/run-postgres-tests.sh '.*' "$NDC_POSTGRES_BINARY" "$ENGINE_BINARY" - name: Upload logs if: always() diff --git a/Cargo.lock b/Cargo.lock index de6262878..676f05286 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -164,6 +164,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.3.0" @@ -181,9 +187,9 @@ dependencies = [ "bitflags 1.3.2", "bytes", "futures-util", - "http", - "http-body", - "hyper", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.32", "itoa", "matchit", "memchr", @@ -195,7 +201,7 @@ dependencies = [ "serde_json", "serde_path_to_error", "serde_urlencoded", - "sync_wrapper", + "sync_wrapper 0.1.2", "tokio", "tower", "tower-layer", @@ -211,8 +217,8 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "mime", "rustversion", "tower-layer", @@ -229,8 +235,8 @@ dependencies = [ "axum-core", "bytes", "futures-util", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "mime", "pin-project-lite", "serde", @@ -248,10 +254,10 @@ checksum = "298f62fa902c2515c169ab0bfb56c593229f33faa01131215d58e3d4898e3aa9" dependencies = [ "axum", "bytes", - "http", - "http-body", - "hyper", - "reqwest", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.32", + "reqwest 0.11.27", "serde", "tokio", "tower", @@ -983,7 +989,26 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http", + "http 0.2.12", + "indexmap 2.7.1", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.2.0", "indexmap 2.7.1", "slab", "tokio", @@ -1073,6 +1098,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http-body" version = "0.4.6" @@ -1080,7 +1116,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.2.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http 1.2.0", + "http-body 1.0.1", "pin-project-lite", ] @@ -1118,9 +1177,9 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", - "http", - "http-body", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", "httparse", "httpdate", "itoa", @@ -1132,13 +1191,50 @@ dependencies = [ "want", ] +[[package]] +name = "hyper" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97818827ef4f364230e16705d4706e2897df2bb60617d6ca15d598025a3c481f" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2 0.4.7", + "http 1.2.0", + "http-body 1.0.1", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" +dependencies = [ + "futures-util", + "http 1.2.0", + "hyper 1.5.1", + "hyper-util", + "rustls 0.23.12", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.26.0", + "tower-service", +] + [[package]] name = "hyper-timeout" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ - "hyper", + "hyper 0.14.32", "pin-project-lite", "tokio", "tokio-io-timeout", @@ -1151,12 +1247,47 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper", + "hyper 0.14.32", "native-tls", "tokio", "tokio-native-tls", ] +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper 1.5.1", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.2.0", + "http-body 1.0.1", + "hyper 1.5.1", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + [[package]] name = "iana-time-zone" version = "0.1.60" @@ -1427,7 +1558,7 @@ dependencies = [ "parking_lot", "percent-encoding", "regex", - "reqwest", + "reqwest 0.11.27", "serde", "serde_json", "time", @@ -1630,8 +1761,8 @@ dependencies = [ [[package]] name = "ndc-models" -version = "0.1.6" -source = "git+https://github.com/hasura/ndc-spec.git?tag=v0.1.6#d1be19e9cdd86ac7b6ad003ff82b7e5b4e96b84f" +version = "0.2.0" +source = "git+https://github.com/hasura/ndc-spec.git?tag=v0.2.0-rc.2#2fad1c699df79890dbb3877d1035ffd8bd0abfc2" dependencies = [ "indexmap 2.7.1", "ref-cast", @@ -1705,17 +1836,16 @@ dependencies = [ [[package]] name = "ndc-sdk" -version = "0.4.0" -source = "git+https://github.com/hasura/ndc-sdk-rs.git?tag=v0.4.0#665509f7d3b47ce4f014fc23f817a3599ba13933" +version = "0.5.0" +source = "git+https://github.com/hasura/ndc-sdk-rs.git?rev=643b96b#643b96b8ee4c8b372b44433167ce2ac4de193332" dependencies = [ "async-trait", "axum", "axum-extra", - "bytes", "clap", - "http", - "mime", + "http 0.2.12", "ndc-models", + "ndc-sdk-core", "ndc-test", "opentelemetry", "opentelemetry-http", @@ -1724,8 +1854,8 @@ dependencies = [ "opentelemetry-zipkin", "opentelemetry_sdk", "prometheus", - "reqwest", - "serde", + "reqwest 0.11.27", + "semver", "serde_json", "thiserror 1.0.69", "tokio", @@ -1736,10 +1866,30 @@ dependencies = [ "url", ] +[[package]] +name = "ndc-sdk-core" +version = "0.5.0" +source = "git+https://github.com/hasura/ndc-sdk-rs.git?rev=643b96b#643b96b8ee4c8b372b44433167ce2ac4de193332" +dependencies = [ + "async-trait", + "axum", + "bytes", + "http 0.2.12", + "mime", + "ndc-models", + "ndc-test", + "prometheus", + "serde", + "serde_json", + "thiserror 1.0.69", + "tokio", + "tracing", +] + [[package]] name = "ndc-test" -version = "0.1.6" -source = "git+https://github.com/hasura/ndc-spec.git?tag=v0.1.6#d1be19e9cdd86ac7b6ad003ff82b7e5b4e96b84f" +version = "0.2.0" +source = "git+https://github.com/hasura/ndc-spec.git?tag=v0.2.0-rc.2#2fad1c699df79890dbb3877d1035ffd8bd0abfc2" dependencies = [ "async-trait", "clap", @@ -1747,14 +1897,12 @@ dependencies = [ "indexmap 2.7.1", "ndc-models", "rand 0.8.5", - "reqwest", + "reqwest 0.12.9", "semver", "serde", "serde_json", - "smol_str", "thiserror 1.0.69", "tokio", - "url", ] [[package]] @@ -1976,9 +2124,9 @@ checksum = "7690dc77bf776713848c4faa6501157469017eaf332baccd4eb1cea928743d94" dependencies = [ "async-trait", "bytes", - "http", + "http 0.2.12", "opentelemetry", - "reqwest", + "reqwest 0.11.27", ] [[package]] @@ -1989,14 +2137,14 @@ checksum = "1a016b8d9495c639af2145ac22387dcb88e44118e45320d9238fbf4e7889abcb" dependencies = [ "async-trait", "futures-core", - "http", + "http 0.2.12", "opentelemetry", "opentelemetry-http", "opentelemetry-proto", "opentelemetry-semantic-conventions", "opentelemetry_sdk", "prost", - "reqwest", + "reqwest 0.11.27", "thiserror 1.0.69", "tokio", "tonic", @@ -2028,13 +2176,13 @@ checksum = "d6943c09b1b7c17b403ae842b00f23e6d5fc6f5ec06cccb3f39aca97094a899a" dependencies = [ "async-trait", "futures-core", - "http", + "http 0.2.12", "once_cell", "opentelemetry", "opentelemetry-http", "opentelemetry-semantic-conventions", "opentelemetry_sdk", - "reqwest", + "reqwest 0.11.27", "serde", "serde_json", "thiserror 1.0.69", @@ -2466,11 +2614,11 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-tls", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.32", + "hyper-tls 0.5.0", "ipnet", "js-sys", "log", @@ -2484,8 +2632,8 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "sync_wrapper", - "system-configuration", + "sync_wrapper 0.1.2", + "system-configuration 0.5.1", "tokio", "tokio-native-tls", "tokio-util", @@ -2498,6 +2646,50 @@ dependencies = [ "winreg", ] +[[package]] +name = "reqwest" +version = "0.12.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" +dependencies = [ + "base64 0.22.1", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.4.7", + "http 1.2.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.5.1", + "hyper-rustls", + "hyper-tls 0.6.0", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "mime_guess", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile 2.1.3", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 1.0.2", + "system-configuration 0.6.1", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-registry", +] + [[package]] name = "ring" version = "0.17.12" @@ -3249,6 +3441,15 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + [[package]] name = "synstructure" version = "0.13.1" @@ -3268,7 +3469,18 @@ checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ "bitflags 1.3.2", "core-foundation", - "system-configuration-sys", + "system-configuration-sys 0.5.0", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "system-configuration-sys 0.6.0", ] [[package]] @@ -3281,6 +3493,16 @@ dependencies = [ "libc", ] +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tempfile" version = "3.18.0" @@ -3324,12 +3546,12 @@ dependencies = [ "axum", "axum-test-helper", "env_logger", - "hyper", + "hyper 0.14.32", "ndc-postgres", "ndc-postgres-configuration", "ndc-sdk", "ndc-test", - "reqwest", + "reqwest 0.12.9", "schemars", "serde", "serde_json", @@ -3506,6 +3728,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +dependencies = [ + "rustls 0.23.12", + "rustls-pki-types", + "tokio", +] + [[package]] name = "tokio-stream" version = "0.1.15" @@ -3542,10 +3775,10 @@ dependencies = [ "base64 0.21.7", "bytes", "flate2", - "h2", - "http", - "http-body", - "hyper", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.32", "hyper-timeout", "percent-encoding", "pin-project", @@ -3554,7 +3787,7 @@ dependencies = [ "rustls-pemfile 2.1.3", "rustls-pki-types", "tokio", - "tokio-rustls", + "tokio-rustls 0.25.0", "tokio-stream", "tower", "tower-layer", @@ -3592,8 +3825,8 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "http-range-header", "mime", "pin-project-lite", @@ -4052,6 +4285,36 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index d5113bc74..6bd958f0a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,9 +31,9 @@ similar_names = "allow" too_many_lines = "allow" [workspace.dependencies] -ndc-models = { git = "https://github.com/hasura/ndc-spec.git", tag = "v0.1.6" } -ndc-sdk = { git = "https://github.com/hasura/ndc-sdk-rs.git", tag = "v0.4.0" } -ndc-test = { git = "https://github.com/hasura/ndc-spec.git", tag = "v0.1.6" } +ndc-models = { git = "https://github.com/hasura/ndc-spec.git", tag = "v0.2.0-rc.2" } +ndc-sdk = { git = "https://github.com/hasura/ndc-sdk-rs.git", rev = "643b96b" } +ndc-test = { git = "https://github.com/hasura/ndc-spec.git", tag = "v0.2.0-rc.2" } anyhow = "1" async-trait = "0.1" @@ -53,7 +53,7 @@ nonempty = "0.10" percent-encoding = "2" prometheus = "0.13" ref-cast = "1" -reqwest = "0.11" +reqwest = "0.12" schemars = "0.8" serde = "1" serde_json = "1" @@ -61,7 +61,10 @@ serde_yaml = "0.9" similar-asserts = "1" smol_str = "0.1" sqlformat = "0.2" -sqlx = { version = "0.8", default-features = false, features = ["postgres", "derive"] } +sqlx = { version = "0.8", default-features = false, features = [ + "postgres", + "derive", +] } tempfile = "3" test-each = "0.2" thiserror = "2" diff --git a/benchmarks/component/benchmarks/select-order-by.js b/benchmarks/component/benchmarks/select-order-by.js index 376aae225..cdc35e0be 100644 --- a/benchmarks/component/benchmarks/select-order-by.js +++ b/benchmarks/component/benchmarks/select-order-by.js @@ -84,7 +84,7 @@ const data = { collection_relationships: { TrackAlbum: { column_mapping: { - AlbumId: "AlbumId", + AlbumId: ["AlbumId"], }, relationship_type: "object", source_collection_or_type: "Track", diff --git a/crates/configuration/src/version3/comparison.rs b/crates/configuration/src/version3/comparison.rs index bc41eaaf8..fbb6eae6e 100644 --- a/crates/configuration/src/version3/comparison.rs +++ b/crates/configuration/src/version3/comparison.rs @@ -29,22 +29,22 @@ impl ComparisonOperatorMapping { ComparisonOperatorMapping { operator_name: "<=".to_string(), exposed_name: "_lte".to_string(), - operator_kind: OperatorKind::Custom, + operator_kind: OperatorKind::LessThanOrEqual, }, ComparisonOperatorMapping { operator_name: ">".to_string(), exposed_name: "_gt".to_string(), - operator_kind: OperatorKind::Custom, + operator_kind: OperatorKind::GreaterThan, }, ComparisonOperatorMapping { operator_name: ">=".to_string(), exposed_name: "_gte".to_string(), - operator_kind: OperatorKind::Custom, + operator_kind: OperatorKind::GreaterThanOrEqual, }, ComparisonOperatorMapping { operator_name: "<".to_string(), exposed_name: "_lt".to_string(), - operator_kind: OperatorKind::Custom, + operator_kind: OperatorKind::LessThan, }, ComparisonOperatorMapping { operator_name: "<>".to_string(), diff --git a/crates/configuration/src/version3/metadata/database.rs b/crates/configuration/src/version3/metadata/database.rs index d3b3d4671..36097d6dd 100644 --- a/crates/configuration/src/version3/metadata/database.rs +++ b/crates/configuration/src/version3/metadata/database.rs @@ -76,6 +76,10 @@ pub struct ComparisonOperator { pub enum OperatorKind { Equal, In, + LessThan, + LessThanOrEqual, + GreaterThan, + GreaterThanOrEqual, Custom, } diff --git a/crates/configuration/src/version3/mod.rs b/crates/configuration/src/version3/mod.rs index 1dd7cc77b..b4c38492e 100644 --- a/crates/configuration/src/version3/mod.rs +++ b/crates/configuration/src/version3/mod.rs @@ -714,7 +714,11 @@ fn convert_scalar_types( .cloned() .unwrap_or(BTreeMap::new()), - type_representation: representations.0.get(&t).cloned(), + type_representation: representations + .0 + .get(&t) + .cloned() + .unwrap_or(query_engine_metadata::metadata::TypeRepresentation::Json), }, ) }) @@ -1020,6 +1024,16 @@ fn convert_operator_kind( match operator_kind { metadata::OperatorKind::Equal => query_engine_metadata::metadata::OperatorKind::Equal, metadata::OperatorKind::In => query_engine_metadata::metadata::OperatorKind::In, + metadata::OperatorKind::LessThan => query_engine_metadata::metadata::OperatorKind::LessThan, + metadata::OperatorKind::LessThanOrEqual => { + query_engine_metadata::metadata::OperatorKind::LessThanOrEqual + } + metadata::OperatorKind::GreaterThan => { + query_engine_metadata::metadata::OperatorKind::GreaterThan + } + metadata::OperatorKind::GreaterThanOrEqual => { + query_engine_metadata::metadata::OperatorKind::GreaterThanOrEqual + } metadata::OperatorKind::Custom => query_engine_metadata::metadata::OperatorKind::Custom, } } diff --git a/crates/configuration/src/version4/comparison.rs b/crates/configuration/src/version4/comparison.rs index 280c1722d..59359172a 100644 --- a/crates/configuration/src/version4/comparison.rs +++ b/crates/configuration/src/version4/comparison.rs @@ -29,22 +29,22 @@ impl ComparisonOperatorMapping { ComparisonOperatorMapping { operator_name: "<=".to_string(), exposed_name: "_lte".to_string(), - operator_kind: OperatorKind::Custom, + operator_kind: OperatorKind::LessThanOrEqual, }, ComparisonOperatorMapping { operator_name: ">".to_string(), exposed_name: "_gt".to_string(), - operator_kind: OperatorKind::Custom, + operator_kind: OperatorKind::GreaterThan, }, ComparisonOperatorMapping { operator_name: ">=".to_string(), exposed_name: "_gte".to_string(), - operator_kind: OperatorKind::Custom, + operator_kind: OperatorKind::GreaterThanOrEqual, }, ComparisonOperatorMapping { operator_name: "<".to_string(), exposed_name: "_lt".to_string(), - operator_kind: OperatorKind::Custom, + operator_kind: OperatorKind::LessThan, }, ComparisonOperatorMapping { operator_name: "<>".to_string(), diff --git a/crates/configuration/src/version4/metadata/database.rs b/crates/configuration/src/version4/metadata/database.rs index cfff6b60f..9bef17023 100644 --- a/crates/configuration/src/version4/metadata/database.rs +++ b/crates/configuration/src/version4/metadata/database.rs @@ -79,6 +79,10 @@ pub struct ComparisonOperator { pub enum OperatorKind { Equal, In, + LessThan, + LessThanOrEqual, + GreaterThan, + GreaterThanOrEqual, Custom, } diff --git a/crates/configuration/src/version4/to_runtime_configuration.rs b/crates/configuration/src/version4/to_runtime_configuration.rs index b4fa402db..9a893d19f 100644 --- a/crates/configuration/src/version4/to_runtime_configuration.rs +++ b/crates/configuration/src/version4/to_runtime_configuration.rs @@ -73,9 +73,10 @@ fn convert_scalar_types( .into_iter() .map(|(k, v)| (k, convert_comparison_operator(v))) .collect(), - type_representation: scalar_type - .type_representation - .map(convert_type_representation), + type_representation: scalar_type.type_representation.map_or( + query_engine_metadata::metadata::TypeRepresentation::Json, + convert_type_representation, + ), }, ) }) @@ -327,6 +328,16 @@ fn convert_operator_kind( match operator_kind { metadata::OperatorKind::Equal => query_engine_metadata::metadata::OperatorKind::Equal, metadata::OperatorKind::In => query_engine_metadata::metadata::OperatorKind::In, + metadata::OperatorKind::LessThan => query_engine_metadata::metadata::OperatorKind::LessThan, + metadata::OperatorKind::LessThanOrEqual => { + query_engine_metadata::metadata::OperatorKind::LessThanOrEqual + } + metadata::OperatorKind::GreaterThan => { + query_engine_metadata::metadata::OperatorKind::GreaterThan + } + metadata::OperatorKind::GreaterThanOrEqual => { + query_engine_metadata::metadata::OperatorKind::GreaterThanOrEqual + } metadata::OperatorKind::Custom => query_engine_metadata::metadata::OperatorKind::Custom, } } diff --git a/crates/configuration/src/version4/upgrade_from_v3.rs b/crates/configuration/src/version4/upgrade_from_v3.rs index 1bbe78f45..cf0d6febc 100644 --- a/crates/configuration/src/version4/upgrade_from_v3.rs +++ b/crates/configuration/src/version4/upgrade_from_v3.rs @@ -156,6 +156,14 @@ fn upgrade_operator_kind( match operator_kind { version3::metadata::OperatorKind::Equal => metadata::OperatorKind::Equal, version3::metadata::OperatorKind::In => metadata::OperatorKind::In, + version3::metadata::OperatorKind::LessThan => metadata::OperatorKind::LessThan, + version3::metadata::OperatorKind::LessThanOrEqual => { + metadata::OperatorKind::LessThanOrEqual + } + version3::metadata::OperatorKind::GreaterThan => metadata::OperatorKind::GreaterThan, + version3::metadata::OperatorKind::GreaterThanOrEqual => { + metadata::OperatorKind::GreaterThanOrEqual + } version3::metadata::OperatorKind::Custom => metadata::OperatorKind::Custom, } } diff --git a/crates/configuration/src/version5/comparison.rs b/crates/configuration/src/version5/comparison.rs index 280c1722d..59359172a 100644 --- a/crates/configuration/src/version5/comparison.rs +++ b/crates/configuration/src/version5/comparison.rs @@ -29,22 +29,22 @@ impl ComparisonOperatorMapping { ComparisonOperatorMapping { operator_name: "<=".to_string(), exposed_name: "_lte".to_string(), - operator_kind: OperatorKind::Custom, + operator_kind: OperatorKind::LessThanOrEqual, }, ComparisonOperatorMapping { operator_name: ">".to_string(), exposed_name: "_gt".to_string(), - operator_kind: OperatorKind::Custom, + operator_kind: OperatorKind::GreaterThan, }, ComparisonOperatorMapping { operator_name: ">=".to_string(), exposed_name: "_gte".to_string(), - operator_kind: OperatorKind::Custom, + operator_kind: OperatorKind::GreaterThanOrEqual, }, ComparisonOperatorMapping { operator_name: "<".to_string(), exposed_name: "_lt".to_string(), - operator_kind: OperatorKind::Custom, + operator_kind: OperatorKind::LessThan, }, ComparisonOperatorMapping { operator_name: "<>".to_string(), diff --git a/crates/configuration/src/version5/metadata/database.rs b/crates/configuration/src/version5/metadata/database.rs index ae77ca441..78522218f 100644 --- a/crates/configuration/src/version5/metadata/database.rs +++ b/crates/configuration/src/version5/metadata/database.rs @@ -85,6 +85,10 @@ pub struct ComparisonOperator { pub enum OperatorKind { Equal, In, + LessThan, + LessThanOrEqual, + GreaterThan, + GreaterThanOrEqual, Custom, } diff --git a/crates/configuration/src/version5/to_runtime_configuration.rs b/crates/configuration/src/version5/to_runtime_configuration.rs index 222f4364c..4a2c733f2 100644 --- a/crates/configuration/src/version5/to_runtime_configuration.rs +++ b/crates/configuration/src/version5/to_runtime_configuration.rs @@ -73,9 +73,10 @@ fn convert_scalar_types( .into_iter() .map(|(k, v)| (k, convert_comparison_operator(v))) .collect(), - type_representation: scalar_type - .type_representation - .map(convert_type_representation), + type_representation: scalar_type.type_representation.map_or( + query_engine_metadata::metadata::TypeRepresentation::Json, + convert_type_representation, + ), }, ) }) @@ -324,6 +325,16 @@ fn convert_operator_kind( match operator_kind { metadata::OperatorKind::Equal => query_engine_metadata::metadata::OperatorKind::Equal, metadata::OperatorKind::In => query_engine_metadata::metadata::OperatorKind::In, + metadata::OperatorKind::LessThan => query_engine_metadata::metadata::OperatorKind::LessThan, + metadata::OperatorKind::LessThanOrEqual => { + query_engine_metadata::metadata::OperatorKind::LessThanOrEqual + } + metadata::OperatorKind::GreaterThan => { + query_engine_metadata::metadata::OperatorKind::GreaterThan + } + metadata::OperatorKind::GreaterThanOrEqual => { + query_engine_metadata::metadata::OperatorKind::GreaterThanOrEqual + } metadata::OperatorKind::Custom => query_engine_metadata::metadata::OperatorKind::Custom, } } diff --git a/crates/configuration/src/version5/upgrade_from_v4.rs b/crates/configuration/src/version5/upgrade_from_v4.rs index 7e25c0c23..e841866d4 100644 --- a/crates/configuration/src/version5/upgrade_from_v4.rs +++ b/crates/configuration/src/version5/upgrade_from_v4.rs @@ -77,6 +77,14 @@ fn upgrade_operator_kind( match operator_kind { version4::metadata::OperatorKind::Equal => metadata::OperatorKind::Equal, version4::metadata::OperatorKind::In => metadata::OperatorKind::In, + version4::metadata::OperatorKind::LessThan => metadata::OperatorKind::LessThan, + version4::metadata::OperatorKind::LessThanOrEqual => { + metadata::OperatorKind::LessThanOrEqual + } + version4::metadata::OperatorKind::GreaterThan => metadata::OperatorKind::GreaterThan, + version4::metadata::OperatorKind::GreaterThanOrEqual => { + metadata::OperatorKind::GreaterThanOrEqual + } version4::metadata::OperatorKind::Custom => metadata::OperatorKind::Custom, } } diff --git a/crates/connectors/ndc-postgres/src/capabilities.rs b/crates/connectors/ndc-postgres/src/capabilities.rs index 91a42fa0b..78646439e 100644 --- a/crates/connectors/ndc-postgres/src/capabilities.rs +++ b/crates/connectors/ndc-postgres/src/capabilities.rs @@ -9,16 +9,25 @@ use ndc_sdk::models; pub fn get_capabilities() -> models::Capabilities { models::Capabilities { query: models::QueryCapabilities { - aggregates: Some(models::LeafCapability {}), + aggregates: Some(models::AggregateCapabilities { + filter_by: None, + group_by: None, + }), variables: Some(models::LeafCapability {}), explain: Some(models::LeafCapability {}), exists: models::ExistsCapabilities { nested_collections: Some(models::LeafCapability {}), + named_scopes: None, + unrelated: None, + nested_scalar_collections: None, }, nested_fields: models::NestedFieldCapabilities { - filter_by: Some(models::LeafCapability {}), + filter_by: Some(models::NestedFieldFilterByCapabilities { + nested_arrays: None, + }), order_by: Some(models::LeafCapability {}), - aggregates: None, + aggregates: Some(models::LeafCapability {}), + nested_collections: None, }, }, mutation: models::MutationCapabilities { @@ -28,6 +37,9 @@ pub fn get_capabilities() -> models::Capabilities { relationships: Some(models::RelationshipCapabilities { relation_comparisons: Some(models::LeafCapability {}), order_by_aggregate: Some(models::LeafCapability {}), + nested: Some(models::NestedRelationshipCapabilities { + array: Some(models::LeafCapability {}), + }), }), } } diff --git a/crates/connectors/ndc-postgres/src/connector.rs b/crates/connectors/ndc-postgres/src/connector.rs index 71672b541..93743458d 100644 --- a/crates/connectors/ndc-postgres/src/connector.rs +++ b/crates/connectors/ndc-postgres/src/connector.rs @@ -188,14 +188,14 @@ impl PostgresSetup { } #[async_trait] -impl ConnectorSetup for PostgresSetup { +impl ConnectorSetup for PostgresSetup { type Connector = Postgres; /// Validate the raw configuration provided by the user, /// returning a configuration error or a validated `Connector::Configuration`. async fn parse_configuration( &self, - configuration_dir: impl AsRef + Send, + configuration_dir: &Path, ) -> Result<::Configuration> { // Note that we don't log validation errors, because they are part of the normal business // operation of configuration validation, i.e. they don't represent an error condition that diff --git a/crates/connectors/ndc-postgres/src/schema/mod.rs b/crates/connectors/ndc-postgres/src/schema/mod.rs index dfcec3a75..e26c5eafa 100644 --- a/crates/connectors/ndc-postgres/src/schema/mod.rs +++ b/crates/connectors/ndc-postgres/src/schema/mod.rs @@ -13,7 +13,9 @@ use ndc_sdk::models; use helpers::*; use ndc_postgres_configuration as configuration; +use ndc_sdk::models::ScalarTypeName; use query_engine_metadata::metadata; +use query_engine_metadata::metadata::TypeRepresentation; use query_engine_translation::translation::helpers::Env; /// Get the connector's schema. @@ -30,25 +32,59 @@ pub fn get_schema( .iter() .map(|(scalar_type_name, scalar_type_info)| { let result = models::ScalarType { - representation: scalar_type_info - .type_representation - .as_ref() - .map(map_type_representation), + representation: map_type_representation(&scalar_type_info.type_representation), aggregate_functions: scalar_type_info .aggregate_functions .iter() .map(|(function_name, function_definition)| { + // convert the return type name into a scalar type name + // this is fine because scalar types and objects types share a namespaces + // if the type isn't scalar we simply won't get anything from metadata for that type + let scalar_return_type: ScalarTypeName = + function_definition.return_type.clone().into(); + // get the scalar representation for the return type + let result_type_representation = metadata + .scalar_types + .0 + .get(&scalar_return_type) + .map(|s| &s.type_representation); ( function_name.clone(), - models::AggregateFunctionDefinition { - result_type: models::Type::Nullable { - // It turns out that all aggregates defined for postgres - // (_except_ `COUNT`) will return `NULL` for an empty row set. - // Thus, we mark all aggregates as having a nullable return - // type. - underlying_type: Box::new(models::Type::Named { - name: function_definition.return_type.clone(), - }), + match (function_name.as_str(), result_type_representation.cloned()) { + // functions called `sum` that return either int64 or float64 can be marked with the meaning tag + // any other will simply be a custom sum function. eg. sum over intervals + ( + "sum", + Some( + TypeRepresentation::Float64 + | TypeRepresentation::Int64 + | TypeRepresentation::Int64AsString, + ), + ) => models::AggregateFunctionDefinition::Sum { + result_type: function_definition.return_type.clone().into(), + }, + // max/min are assumed to always be valid and return the type they aggregate on + ("max", _) => models::AggregateFunctionDefinition::Max, + ("min", _) => models::AggregateFunctionDefinition::Min, + // Mark AVG aggregations returning a f64 (float8) with the meaning tag + // The spec wants all averages to return a scalar represented as a f64 + // per the postgres spec, this shoudl be avg(f32) and avg(f64) + // avg over other types returns numeric (or interval) + ("avg", Some(TypeRepresentation::Float64)) => { + models::AggregateFunctionDefinition::Average { + result_type: function_definition.return_type.clone().into(), + } + } + (_, _) => models::AggregateFunctionDefinition::Custom { + result_type: models::Type::Nullable { + // It turns out that all aggregates defined for postgres + // (_except_ `COUNT`) will return `NULL` for an empty row set. + // Thus, we mark all aggregates as having a nullable return + // type. + underlying_type: Box::new(models::Type::Named { + name: function_definition.return_type.clone(), + }), + }, }, }, ) @@ -67,6 +103,18 @@ pub fn get_schema( metadata::OperatorKind::In => { models::ComparisonOperatorDefinition::In } + metadata::OperatorKind::LessThan => { + models::ComparisonOperatorDefinition::LessThan + } + metadata::OperatorKind::LessThanOrEqual => { + models::ComparisonOperatorDefinition::LessThanOrEqual + } + metadata::OperatorKind::GreaterThan => { + models::ComparisonOperatorDefinition::GreaterThan + } + metadata::OperatorKind::GreaterThanOrEqual => { + models::ComparisonOperatorDefinition::GreaterThanOrEqual + } metadata::OperatorKind::Custom => { models::ComparisonOperatorDefinition::Custom { argument_type: models::Type::Named { @@ -119,42 +167,6 @@ pub fn get_schema( }, ) .collect(), - foreign_keys: table - .foreign_relations - .0 - .iter() - .map( - |( - constraint_name, - metadata::ForeignRelation { - foreign_schema, - foreign_table, - column_mapping, - }, - )| { - ( - constraint_name.clone(), - models::ForeignKeyConstraint { - foreign_collection: (*collections_by_identifier - .get(&( - // the foreign schema used to be implied, so if it is not - // provided, we need to default back to the originating - // table's schema - foreign_schema.as_ref().unwrap_or(&table.schema_name), - foreign_table, - )) - .unwrap_or_else(|| { - panic!( - "Unknown foreign table: {foreign_schema:?}.{foreign_table:?}" - ) - })) - .into(), - column_mapping: column_mapping.clone(), - }, - ) - }, - ) - .collect(), }) .collect(); @@ -181,7 +193,6 @@ pub fn get_schema( .collect(), collection_type: name.as_str().into(), uniqueness_constraints: BTreeMap::new(), - foreign_keys: BTreeMap::new(), }) .collect(); @@ -209,6 +220,42 @@ pub fn get_schema( ) }) .collect(), + foreign_keys: table + .foreign_relations + .0 + .iter() + .map( + |( + constraint_name, + metadata::ForeignRelation { + foreign_schema, + foreign_table, + column_mapping, + }, + )| { + ( + constraint_name.clone(), + models::ForeignKeyConstraint { + foreign_collection: (*collections_by_identifier + .get(&( + // the foreign schema used to be implied, so if it is not + // provided, we need to default back to the originating + // table's schema + foreign_schema.as_ref().unwrap_or(&table.schema_name), + foreign_table, + )) + .unwrap_or_else(|| { + panic!( + "Unknown foreign table: {foreign_schema:?}.{foreign_table:?}" + ) + })) + .into(), + column_mapping: column_mapping.clone().into_iter().map(|(left_col, right_col)| (left_col, vec![right_col])).collect(), + }, + ) + }, + ) + .collect(), }; (collection_name.as_str().into(), object_type) }) @@ -236,6 +283,7 @@ pub fn get_schema( ) }) .collect(), + foreign_keys: BTreeMap::new(), }; (nq_name.as_str().into(), object_type) }) @@ -263,6 +311,7 @@ pub fn get_schema( ) }) .collect(), + foreign_keys: BTreeMap::new(), }; (nq_name.as_str().into(), object_type) }) @@ -291,6 +340,7 @@ pub fn get_schema( ) }) .collect(), + foreign_keys: BTreeMap::new(), }; (ctype_name.as_str().into(), object_type) }) @@ -351,12 +401,32 @@ pub fn get_schema( procedures.extend(generated_procedures); object_types.extend(more_object_types); + // If int8 doesn't exist anywhere else in the schema, we need to add it here. However, a user + // can't filter or aggregate based on the result of a cout aggregation, so we don't need to add + // any aggregate functions or comparison operators. However, if int8 exists elsewhere in the + // schema and has already been added, it will also already contain these functions and + // operators. + scalar_types + .entry("int8".into()) + .or_insert(models::ScalarType { + representation: models::TypeRepresentation::Int64, + aggregate_functions: BTreeMap::new(), + comparison_operators: BTreeMap::new(), + }); + Ok(models::SchemaResponse { collections, procedures, functions: vec![], object_types, scalar_types, + capabilities: Some(models::CapabilitySchemaInfo { + query: Some(models::QueryCapabilitiesSchemaInfo { + aggregates: Some(models::AggregateCapabilitiesSchemaInfo { + count_scalar_type: "int8".to_string(), + }), + }), + }), }) } diff --git a/crates/connectors/ndc-postgres/src/schema/mutation/helpers.rs b/crates/connectors/ndc-postgres/src/schema/mutation/helpers.rs index a3d15b76a..6f2784736 100644 --- a/crates/connectors/ndc-postgres/src/schema/mutation/helpers.rs +++ b/crates/connectors/ndc-postgres/src/schema/mutation/helpers.rs @@ -33,7 +33,7 @@ pub fn make_procedure_type( scalar_types .entry("int4".into()) .or_insert(models::ScalarType { - representation: Some(models::TypeRepresentation::Int32), + representation: models::TypeRepresentation::Int32, aggregate_functions: BTreeMap::new(), comparison_operators: BTreeMap::new(), }); @@ -65,6 +65,7 @@ pub fn make_procedure_type( models::ObjectType { description: Some(format!("Responses from the '{name}' procedure")), fields, + foreign_keys: BTreeMap::new(), }, ); @@ -102,6 +103,7 @@ pub fn make_insert_objects_type( models::ObjectType { description: None, fields, + foreign_keys: BTreeMap::new(), } } @@ -135,6 +137,7 @@ pub fn make_update_column_type( "Update the '{column_name}' column in the '{collection_name}' collection" )), fields, + foreign_keys: BTreeMap::new(), }, )) } diff --git a/crates/connectors/ndc-postgres/src/schema/mutation/v2.rs b/crates/connectors/ndc-postgres/src/schema/mutation/v2.rs index c04f8365f..e7435bb60 100644 --- a/crates/connectors/ndc-postgres/src/schema/mutation/v2.rs +++ b/crates/connectors/ndc-postgres/src/schema/mutation/v2.rs @@ -155,6 +155,7 @@ pub fn update_to_procedure( update_by_key.collection_name )), fields, + foreign_keys: BTreeMap::new(), }, ); diff --git a/crates/query-engine/metadata/src/metadata/database.rs b/crates/query-engine/metadata/src/metadata/database.rs index 21e07de38..33298e9a1 100644 --- a/crates/query-engine/metadata/src/metadata/database.rs +++ b/crates/query-engine/metadata/src/metadata/database.rs @@ -30,7 +30,7 @@ pub struct ScalarType { pub description: Option, pub aggregate_functions: BTreeMap, pub comparison_operators: BTreeMap, - pub type_representation: Option, + pub type_representation: TypeRepresentation, } /// Map of all known composite types. @@ -77,6 +77,10 @@ pub struct ComparisonOperator { pub enum OperatorKind { Equal, In, + LessThan, + LessThanOrEqual, + GreaterThan, + GreaterThanOrEqual, Custom, } diff --git a/crates/query-engine/sql/src/sql/ast.rs b/crates/query-engine/sql/src/sql/ast.rs index 871ed4d5d..310ad2fbf 100644 --- a/crates/query-engine/sql/src/sql/ast.rs +++ b/crates/query-engine/sql/src/sql/ast.rs @@ -338,11 +338,11 @@ pub enum Function { } /// COUNT clause -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq)] pub enum CountType { Star, - Simple(ColumnReference), - Distinct(ColumnReference), + Simple(Box), + Distinct(Box), } /// Value diff --git a/crates/query-engine/translation/src/translation/error.rs b/crates/query-engine/translation/src/translation/error.rs index 29f2307bf..8c2d11ece 100644 --- a/crates/query-engine/translation/src/translation/error.rs +++ b/crates/query-engine/translation/src/translation/error.rs @@ -12,6 +12,10 @@ pub enum Error { ColumnNotFoundInCollection(models::FieldName, models::CollectionName), RelationshipNotFound(models::RelationshipName), ArgumentNotFound(models::ArgumentName), + UnexpectedArgumentValue { + expected: String, + got: String, + }, OperatorNotFound { operator_name: models::ComparisonOperatorName, type_name: models::ScalarTypeName, @@ -54,18 +58,46 @@ pub enum Error { field_name: models::FieldName, actual_type: Type, }, + MutationVersionNotSet, + MissingAggregateFunctionForScalar { + scalar: models::ScalarTypeName, + function: models::AggregateFunctionName, + }, + ScopeOutOfBounds { + current_collection_name: String, + tables_in_scope_names: Vec, + scope: usize, + }, } /// Capabilities we don't currently support. #[derive(Debug, Clone)] pub enum UnsupportedCapabilities { FieldArguments, + NestedRelationships, + NestedCollectionFields, + NestedArrays, + ArrayComparison, + NestedScalarCollection, + FilterByAggregate, } impl std::fmt::Display for UnsupportedCapabilities { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { UnsupportedCapabilities::FieldArguments => write!(f, "Field arguments"), + UnsupportedCapabilities::NestedRelationships => write!(f, "Nested relationships"), + UnsupportedCapabilities::NestedCollectionFields => { + write!(f, "Nested collection fields") + } + UnsupportedCapabilities::NestedArrays => { + write!(f, "Nested arrays") + } + UnsupportedCapabilities::ArrayComparison => write!(f, "Array Comparison"), + UnsupportedCapabilities::NestedScalarCollection => { + write!(f, "Nested Scalar Collection") + } + UnsupportedCapabilities::FilterByAggregate => write!(f, "Filter By Aggregate"), } } } @@ -93,6 +125,12 @@ impl std::fmt::Display for Error { Error::ArgumentNotFound(argument) => { write!(f, "Argument '{argument}' not found.") } + Error::UnexpectedArgumentValue { expected, got } => { + write!( + f, + "Unexpected argument value, expected {expected}, got {got}" + ) + } Error::OperatorNotFound { operator_name, type_name, @@ -199,6 +237,31 @@ impl std::fmt::Display for Error { "Nested field '{field_name}' not of array type. Actual type: {actual_type:?}" ) } + Error::MutationVersionNotSet => write!(f, "Mutation version not set"), + Error::MissingAggregateFunctionForScalar { scalar, function } => write!( + f, + "Missing single column aggregate function {function:?} for scalar type {scalar:?}" + ), + Error::ScopeOutOfBounds { + current_collection_name, + tables_in_scope_names, + scope, + } => { + write!( + f, + "Scope {scope} out of bounds. Current collection is {current_collection_name}. Collections in scope: [" + )?; + let mut first = true; + for collection in tables_in_scope_names { + if first { + first = false; + } else { + write!(f, ", ")?; + } + write!(f, "{collection}")?; + } + write!(f, "].") + } } } } diff --git a/crates/query-engine/translation/src/translation/helpers.rs b/crates/query-engine/translation/src/translation/helpers.rs index f5f8aec07..72af034e8 100644 --- a/crates/query-engine/translation/src/translation/helpers.rs +++ b/crates/query-engine/translation/src/translation/helpers.rs @@ -1,6 +1,6 @@ //! Helpers for processing requests and building SQL. -use std::collections::BTreeMap; +use std::collections::{BTreeMap, VecDeque}; use ndc_models as models; @@ -47,16 +47,68 @@ pub struct NativeQueryInfo { pub alias: sql::ast::TableAlias, } -/// For the root table in the query, and for the current table we are processing, +/// For the current table we are processing, and all ancestor table up to the closest Query, /// We'd like to track what is their reference in the query (the name we can use to address them, /// an alias we generate), and what is their name in the metadata (so we can get /// their information such as which columns are available for that table). #[derive(Debug, Clone, PartialEq, Eq)] -pub struct RootAndCurrentTables { - /// The root (top-most) table in the query. - pub root_table: TableSourceAndReference, +pub struct TableScope { /// The current table we are processing. - pub current_table: TableSourceAndReference, + current_table: TableSourceAndReference, + /// Tables in scope. Index 0 corresponds to scope 1, which is the table immediately above the current table in the exists chain. + tables_in_scope: VecDeque, +} + +impl TableScope { + /// Create a scope from a Query. There will be no tables available through scopes + pub fn new(current_table: TableSourceAndReference) -> Self { + Self { + current_table, + tables_in_scope: VecDeque::new(), + } + } + /// Create a scope from an exists expression or path. The ancestor tables up until the closest query will stay in scope + #[must_use] + pub fn new_from_scope(&self, current_table: TableSourceAndReference) -> Self { + let TableScope { + current_table: parent_table, + tables_in_scope, + } = self; + let mut tables_in_scope = tables_in_scope.clone(); + tables_in_scope.push_front(parent_table.clone()); + Self { + current_table, + tables_in_scope, + } + } + /// Get the table source and reference for the current table + pub fn current_table(&self) -> &TableSourceAndReference { + &self.current_table + } + /// Get the table source and reference for a table in scope. + /// The scope is an index, where 0 is the current table, 1 is the parent, and so on + /// Errors if the scope is out of bounds + pub fn scoped_table(&self, scope: &Option) -> Result<&TableSourceAndReference, Error> { + if let Some(scope) = scope { + if *scope > 0 && *scope <= self.tables_in_scope.len() { + Ok(&self.tables_in_scope[scope - 1]) + } else if *scope == 0 { + Ok(&self.current_table) + } else { + Err(Error::ScopeOutOfBounds { + current_collection_name: self.current_table.source.name_for_alias(), + tables_in_scope_names: self + .tables_in_scope + .iter() + .map(|c| c.source.name_for_alias()) + .collect(), + scope: *scope, + }) + } + } else { + Ok(&self.current_table) + } + } } /// For a table in the query, We'd like to track what is its reference in the query @@ -424,7 +476,7 @@ impl<'request> Env<'request> { .scalar_types .0 .get(scalar_type) - .and_then(|t| t.type_representation.as_ref()) + .map(|t| &t.type_representation) } /// Try to get the variables table reference. This will fail if no variables were passed diff --git a/crates/query-engine/translation/src/translation/mutation/translate.rs b/crates/query-engine/translation/src/translation/mutation/translate.rs index 240925f74..bb62d272d 100644 --- a/crates/query-engine/translation/src/translation/mutation/translate.rs +++ b/crates/query-engine/translation/src/translation/mutation/translate.rs @@ -74,6 +74,7 @@ fn translate_mutation( offset: None, order_by: None, predicate: None, + groups: None, }; let (return_collection, cte_expr, check_constraint_alias) = @@ -217,6 +218,7 @@ fn translate_native_query( offset: None, order_by: None, predicate: None, + groups: None, }; // process inner query and get the SELECTs for the 'rows' and 'aggregates' fields. @@ -316,8 +318,20 @@ pub fn parse_procedure_fields( .to_string(), ))? } + ndc_models::NestedField::Collection(_) => { + Err(Error::UnexpectedStructure( + "nested field collection in array in 'returning' clause" + .to_string(), + ))? + } } } + ndc_models::NestedField::Collection(_) => { + Err(Error::UnexpectedStructure( + "nested field collection array in 'returning' clause" + .to_string(), + ))? + } }, None => returning, }; @@ -338,6 +352,9 @@ pub fn parse_procedure_fields( Some(models::NestedField::Array(_)) => { Err(Error::NotImplementedYet("nested array fields".to_string())) } + Some(models::NestedField::Collection(_)) => Err(Error::NotImplementedYet( + "nested field collection".to_string(), + )), None => Err(Error::NoProcedureResultFieldsRequested)?, } } @@ -357,7 +374,7 @@ fn translate_mutation_expr( Error, > { match env.mutations_version { - None => todo!(), + None => Err(Error::MutationVersionNotSet), Some(metadata::mutations::MutationsVersion::V1) => { v1::translate(env, state, procedure_name, arguments) } diff --git a/crates/query-engine/translation/src/translation/mutation/v1/insert.rs b/crates/query-engine/translation/src/translation/mutation/v1/insert.rs index d65cd4bd6..ceb2af567 100644 --- a/crates/query-engine/translation/src/translation/mutation/v1/insert.rs +++ b/crates/query-engine/translation/src/translation/mutation/v1/insert.rs @@ -69,7 +69,18 @@ pub fn translate( )); } } - _ => todo!(), + _ => Err(Error::UnexpectedArgumentValue { + expected: "Object".into(), + got: match object { + serde_json::Value::Null => "Null", + serde_json::Value::Bool(_) => "Bool", + serde_json::Value::Number(_) => "Number", + serde_json::Value::String(_) => "String", + serde_json::Value::Array(_) => "Array", + serde_json::Value::Object(_) => "Object", + } + .into(), + })?, }; check_columns(&mutation.columns, &columns, &mutation.collection_name)?; diff --git a/crates/query-engine/translation/src/translation/mutation/v2/delete.rs b/crates/query-engine/translation/src/translation/mutation/v2/delete.rs index 602f27b9a..2e5e309b5 100644 --- a/crates/query-engine/translation/src/translation/mutation/v2/delete.rs +++ b/crates/query-engine/translation/src/translation/mutation/v2/delete.rs @@ -146,10 +146,7 @@ pub fn translate( let predicate_expression = filtering::translate( env, state, - &helpers::RootAndCurrentTables { - root_table: table_name_and_reference.clone(), - current_table: table_name_and_reference, - }, + &helpers::TableScope::new(table_name_and_reference), &predicate, )?; diff --git a/crates/query-engine/translation/src/translation/mutation/v2/insert.rs b/crates/query-engine/translation/src/translation/mutation/v2/insert.rs index dfaa956bd..87622983b 100644 --- a/crates/query-engine/translation/src/translation/mutation/v2/insert.rs +++ b/crates/query-engine/translation/src/translation/mutation/v2/insert.rs @@ -232,10 +232,7 @@ pub fn translate( let predicate_expression = filtering::translate( env, state, - &helpers::RootAndCurrentTables { - root_table: table_name_and_reference.clone(), - current_table: table_name_and_reference, - }, + &helpers::TableScope::new(table_name_and_reference), &predicate, )?; diff --git a/crates/query-engine/translation/src/translation/mutation/v2/update.rs b/crates/query-engine/translation/src/translation/mutation/v2/update.rs index 0224b930e..72dcee847 100644 --- a/crates/query-engine/translation/src/translation/mutation/v2/update.rs +++ b/crates/query-engine/translation/src/translation/mutation/v2/update.rs @@ -151,10 +151,7 @@ pub fn translate( }) .collect::, Error>>()?; - let root_and_current_tables = helpers::RootAndCurrentTables { - root_table: table_name_and_reference.clone(), - current_table: table_name_and_reference, - }; + let root_and_current_tables = helpers::TableScope::new(table_name_and_reference); // Build the `pre_constraint` argument boolean expression. let pre_predicate = diff --git a/crates/query-engine/translation/src/translation/query/aggregates.rs b/crates/query-engine/translation/src/translation/query/aggregates.rs index 2885628d4..9e736d446 100644 --- a/crates/query-engine/translation/src/translation/query/aggregates.rs +++ b/crates/query-engine/translation/src/translation/query/aggregates.rs @@ -4,7 +4,7 @@ use indexmap::IndexMap; use ndc_models as models; -use crate::translation::error::Error; +use crate::translation::{error::Error, helpers::wrap_in_field_path}; use query_engine_sql::sql; /// Translate any aggregates we should include in the query into our SQL AST. @@ -19,38 +19,61 @@ pub fn translate( models::Aggregate::ColumnCount { column, distinct, - field_path: _, + field_path, + arguments: _, } => { let count_column_alias = sql::helpers::make_column_alias(column.to_string()); - if *distinct { - sql::ast::Expression::Count(sql::ast::CountType::Distinct( + + let column = wrap_in_field_path( + &field_path.into(), + sql::ast::Expression::ColumnReference( sql::ast::ColumnReference::AliasedColumn { table: table.clone(), column: count_column_alias, }, - )) + ), + ); + + if *distinct { + sql::ast::Expression::Count(sql::ast::CountType::Distinct(Box::new(column))) } else { - sql::ast::Expression::Count(sql::ast::CountType::Simple( - sql::ast::ColumnReference::AliasedColumn { - table: table.clone(), - column: count_column_alias, - }, - )) + sql::ast::Expression::Count(sql::ast::CountType::Simple(Box::new(column))) } } models::Aggregate::SingleColumn { column, function, - field_path: _, - } => sql::ast::Expression::FunctionCall { - function: sql::ast::Function::Unknown(function.to_string()), - args: vec![sql::ast::Expression::ColumnReference( - sql::ast::ColumnReference::AliasedColumn { - table: table.clone(), - column: sql::helpers::make_column_alias(column.to_string()), - }, - )], - }, + field_path, + arguments: _, + } => { + let column = wrap_in_field_path( + &field_path.into(), + sql::ast::Expression::ColumnReference( + sql::ast::ColumnReference::AliasedColumn { + table: table.clone(), + column: sql::helpers::make_column_alias(column.to_string()), + }, + ), + ); + let aggregate_function_call_expression = sql::ast::Expression::FunctionCall { + function: sql::ast::Function::Unknown(function.to_string()), + args: vec![column], + }; + // postgres SUM aggregate returns null if no input rows are provided + // however, the ndc spec requires that SUM aggregates over no input rows return 0 + // we achieve this with COALESCE, falling back to 0 if the aggregate expression returns null + if function.as_str() == "sum" { + sql::ast::Expression::FunctionCall { + function: sql::ast::Function::Coalesce, + args: vec![ + aggregate_function_call_expression, + sql::ast::Expression::Value(sql::ast::Value::Int4(0)), + ], + } + } else { + aggregate_function_call_expression + } + } models::Aggregate::StarCount {} => { sql::ast::Expression::Count(sql::ast::CountType::Star) } diff --git a/crates/query-engine/translation/src/translation/query/fields.rs b/crates/query-engine/translation/src/translation/query/fields.rs index 8282f7d6d..332dd1df8 100644 --- a/crates/query-engine/translation/src/translation/query/fields.rs +++ b/crates/query-engine/translation/src/translation/query/fields.rs @@ -279,8 +279,14 @@ fn translate_nested_field( fields, )) } + ndc_models::NestedField::Collection(_) => Err(Error::CapabilityNotSupported( + UnsupportedCapabilities::NestedCollectionFields, + )), } } + ndc_models::NestedField::Collection(_) => Err(Error::CapabilityNotSupported( + UnsupportedCapabilities::NestedCollectionFields, + )), }?; // The recursive call to the next layer of fields diff --git a/crates/query-engine/translation/src/translation/query/filtering.rs b/crates/query-engine/translation/src/translation/query/filtering.rs index 73b1e3763..6c648393c 100644 --- a/crates/query-engine/translation/src/translation/query/filtering.rs +++ b/crates/query-engine/translation/src/translation/query/filtering.rs @@ -13,7 +13,7 @@ use super::variables; use crate::translation::error::Error; use crate::translation::error::UnsupportedCapabilities; use crate::translation::helpers::{ - wrap_in_field_path, ColumnInfo, CompositeTypeInfo, Env, FieldPath, RootAndCurrentTables, State, + wrap_in_field_path, ColumnInfo, CompositeTypeInfo, Env, FieldPath, State, TableScope, TableSource, TableSourceAndReference, }; use query_engine_metadata::metadata::database; @@ -24,12 +24,12 @@ use std::collections::VecDeque; pub fn translate( env: &Env, state: &mut State, - root_and_current_tables: &RootAndCurrentTables, + current_table_scope: &TableScope, predicate: &models::Expression, ) -> Result { // Fetch the filter expression and the relevant joins. let (filter_expression, joins) = - translate_expression_with_joins(env, state, root_and_current_tables, predicate)?; + translate_expression_with_joins(env, state, current_table_scope, predicate)?; let mut joins = VecDeque::from(joins); let filter = match joins.pop_front() { @@ -54,7 +54,7 @@ pub fn translate( pub fn translate_expression_with_joins( env: &Env, state: &mut State, - root_and_current_tables: &RootAndCurrentTables, + current_table_scope: &TableScope, predicate: &models::Expression, ) -> Result<(sql::ast::Expression, Vec), Error> { match predicate { @@ -62,9 +62,7 @@ pub fn translate_expression_with_joins( let mut acc_joins = vec![]; let and_exprs = expressions .iter() - .map(|expr| { - translate_expression_with_joins(env, state, root_and_current_tables, expr) - }) + .map(|expr| translate_expression_with_joins(env, state, current_table_scope, expr)) .try_fold( sql::ast::Expression::Value(sql::ast::Value::Bool(true)), |acc, expr| { @@ -82,9 +80,7 @@ pub fn translate_expression_with_joins( let mut acc_joins = vec![]; let or_exprs = expressions .iter() - .map(|expr| { - translate_expression_with_joins(env, state, root_and_current_tables, expr) - }) + .map(|expr| translate_expression_with_joins(env, state, current_table_scope, expr)) .try_fold( sql::ast::Expression::Value(sql::ast::Value::Bool(false)), |acc, expr| { @@ -100,7 +96,7 @@ pub fn translate_expression_with_joins( } models::Expression::Not { expression } => { let (expr, joins) = - translate_expression_with_joins(env, state, root_and_current_tables, expression)?; + translate_expression_with_joins(env, state, current_table_scope, expression)?; Ok((sql::ast::Expression::Not(Box::new(expr)), joins)) } models::Expression::BinaryComparisonOperator { @@ -108,22 +104,39 @@ pub fn translate_expression_with_joins( operator, value, } => { - let left_typ = get_comparison_target_type(env, root_and_current_tables, column)?; + let left_typ = get_comparison_target_type(env, current_table_scope, column)?; let op = env.lookup_comparison_operator(&left_typ, operator)?; if op.operator_kind == metadata::OperatorKind::In { let mut joins = vec![]; let (left, left_joins) = - translate_comparison_target(env, state, root_and_current_tables, column)?; + translate_comparison_target(env, state, current_table_scope, column)?; joins.extend(left_joins); match value { - models::ComparisonValue::Column { column } => { - let (right, right_joins) = translate_comparison_target( - env, - state, - root_and_current_tables, - column, - )?; + models::ComparisonValue::Column { + path, + name, + arguments: _, + field_path, + scope, + } => { + let scoped_table = current_table_scope.scoped_table(scope)?; + let (table_ref, right_joins) = + translate_comparison_pathelements(env, state, scoped_table, path)?; + + let collection_info = env.lookup_fields_info(&table_ref.source)?; + let ColumnInfo { name, .. } = collection_info.lookup_column(name)?; + + let right = wrap_in_field_path( + &field_path.into(), + sql::ast::Expression::ColumnReference( + sql::ast::ColumnReference::TableColumn { + table: table_ref.reference.clone(), + name, + }, + ), + ); + joins.extend(right_joins); let right = vec![make_unnest_subquery(state, right)]; @@ -149,7 +162,7 @@ pub fn translate_expression_with_joins( let (right, right_joins) = translate_comparison_value( env, state, - root_and_current_tables, + current_table_scope, &models::ComparisonValue::Scalar { value: value.clone(), }, @@ -179,7 +192,7 @@ pub fn translate_expression_with_joins( let (right, right_joins) = translate_comparison_value( env, state, - root_and_current_tables, + current_table_scope, value, &array_type, )?; @@ -200,13 +213,13 @@ pub fn translate_expression_with_joins( } else { let mut joins = vec![]; let (left, left_joins) = - translate_comparison_target(env, state, root_and_current_tables, column)?; + translate_comparison_target(env, state, current_table_scope, column)?; joins.extend(left_joins); let (right, right_joins) = translate_comparison_value( env, state, - root_and_current_tables, + current_table_scope, value, &database::Type::ScalarType(op.argument_type.clone()), )?; @@ -242,7 +255,7 @@ pub fn translate_expression_with_joins( translate_exists_in_collection( env, state, - root_and_current_tables, + current_table_scope, in_collection.clone(), predicate, )?, @@ -252,7 +265,7 @@ pub fn translate_expression_with_joins( models::Expression::UnaryComparisonOperator { column, operator } => match operator { models::UnaryComparisonOperator::IsNull => { let (value, joins) = - translate_comparison_target(env, state, root_and_current_tables, column)?; + translate_comparison_target(env, state, current_table_scope, column)?; Ok(( sql::ast::Expression::UnaryOperation { @@ -263,6 +276,9 @@ pub fn translate_expression_with_joins( )) } }, + models::Expression::ArrayComparison { .. } => Err(Error::CapabilityNotSupported( + UnsupportedCapabilities::ArrayComparison, + )), } } @@ -308,11 +324,10 @@ pub fn translate_expression_with_joins( fn translate_comparison_pathelements( env: &Env, state: &mut State, - root_and_current_tables: &RootAndCurrentTables, + current_table: &TableSourceAndReference, path: &[models::PathElement], ) -> Result<(TableSourceAndReference, Vec), Error> { let mut joins = vec![]; - let RootAndCurrentTables { current_table, .. } = root_and_current_tables; let final_ref = path.iter().try_fold( current_table.clone(), @@ -321,6 +336,7 @@ fn translate_comparison_pathelements( relationship, predicate, arguments, + field_path: _, }| { // get the relationship table let relationship_name = &relationship; @@ -352,20 +368,16 @@ fn translate_comparison_pathelements( select.select_list = sql::ast::SelectList::SelectStar; - let new_root_and_current_tables = RootAndCurrentTables { - root_table: root_and_current_tables.root_table.clone(), - current_table: TableSourceAndReference { - reference: table.reference.clone(), - source: table.source.clone(), - }, - }; + // for the purposes of named scopes, PathElement functions as a root, much like Query + let new_current_table_scope = TableScope::new(table.clone()); + // relationship-specfic filter let (rel_cond, rel_joins) = match predicate { None => (sql::helpers::true_expr(), vec![]), Some(predicate) => translate_expression_with_joins( env, state, - &new_root_and_current_tables, + &new_current_table_scope, predicate, )?, }; @@ -390,7 +402,7 @@ fn translate_comparison_pathelements( }, )); - Ok(new_root_and_current_tables.current_table) + Ok(table) }, )?; @@ -416,7 +428,6 @@ fn translate_comparison_pathelements( reference, source: final_ref.source, }, - // create a join from the select. // We use a full outer join so even if one of the sides does not contain rows, // We can still select values. // See a more elaborated explanation: https://github.com/hasura/ndc-postgres/pull/463#discussion_r1601884534 @@ -434,18 +445,17 @@ fn translate_comparison_pathelements( /// translate a comparison target. fn translate_comparison_target( env: &Env, - state: &mut State, - root_and_current_tables: &RootAndCurrentTables, + _state: &mut State, + current_table_scope: &TableScope, column: &models::ComparisonTarget, ) -> Result<(sql::ast::Expression, Vec), Error> { match column { models::ComparisonTarget::Column { name, - path, field_path, + arguments: _, } => { - let (table_ref, joins) = - translate_comparison_pathelements(env, state, root_and_current_tables, path)?; + let (table_ref, joins) = (current_table_scope.current_table().clone(), vec![]); // get the unrelated table information from the metadata. let collection_info = env.lookup_fields_info(&table_ref.source)?; @@ -462,42 +472,48 @@ fn translate_comparison_target( joins, )) } + ndc_models::ComparisonTarget::Aggregate { .. } => Err(Error::CapabilityNotSupported( + UnsupportedCapabilities::FilterByAggregate, + )), + } +} - // Compare a column from the root table. - models::ComparisonTarget::RootCollectionColumn { name, field_path } => { - let RootAndCurrentTables { root_table, .. } = root_and_current_tables; - // get the unrelated table information from the metadata. - let collection_info = env.lookup_fields_info(&root_table.source)?; +/// translate a comparison value. +fn translate_comparison_value( + env: &Env, + state: &mut State, + current_table_scope: &TableScope, + value: &models::ComparisonValue, + typ: &database::Type, +) -> Result<(sql::ast::Expression, Vec), Error> { + match value { + models::ComparisonValue::Column { + path, + name, + arguments: _, + field_path, + scope, + } => { + let table_source_and_reference = current_table_scope.scoped_table(scope)?; - // find the requested column in the tables columns. + let (table_ref, joins) = + translate_comparison_pathelements(env, state, table_source_and_reference, path)?; + + // get the unrelated table information from the metadata. + let collection_info = env.lookup_fields_info(&table_ref.source)?; let ColumnInfo { name, .. } = collection_info.lookup_column(name)?; Ok(( wrap_in_field_path( &field_path.into(), sql::ast::Expression::ColumnReference(sql::ast::ColumnReference::TableColumn { - table: root_table.reference.clone(), + table: table_ref.reference.clone(), name, }), ), - vec![], + joins, )) } - } -} - -/// translate a comparison value. -fn translate_comparison_value( - env: &Env, - state: &mut State, - root_and_current_tables: &RootAndCurrentTables, - value: &models::ComparisonValue, - typ: &database::Type, -) -> Result<(sql::ast::Expression, Vec), Error> { - match value { - models::ComparisonValue::Column { column } => { - translate_comparison_target(env, state, root_and_current_tables, column) - } models::ComparisonValue::Scalar { value: json_value } => { Ok((values::translate(env, state, json_value, typ)?, vec![])) } @@ -514,7 +530,7 @@ fn translate_comparison_value( pub fn translate_exists_in_collection( env: &Env, state: &mut State, - root_and_current_tables: &RootAndCurrentTables, + current_table_scope: &TableScope, in_collection: models::ExistsInCollection, predicate: &models::Expression, ) -> Result { @@ -546,20 +562,10 @@ pub fn translate_exists_in_collection( let mut select = sql::helpers::simple_select(select_cols); select.from = Some(from_clause); - let new_root_and_current_tables = RootAndCurrentTables { - root_table: root_and_current_tables.root_table.clone(), - current_table: TableSourceAndReference { - reference: table.reference, - source: table.source, - }, - }; + let new_current_table_scope = current_table_scope.new_from_scope(table); - let (expr, expr_joins) = translate_expression_with_joins( - env, - state, - &new_root_and_current_tables, - predicate, - )?; + let (expr, expr_joins) = + translate_expression_with_joins(env, state, &new_current_table_scope, predicate)?; select.where_ = sql::ast::Where(expr); select.joins = expr_joins; @@ -575,6 +581,7 @@ pub fn translate_exists_in_collection( models::ExistsInCollection::Related { relationship, arguments, + field_path: _, } => { // get the relationship table let relationship = env.lookup_relationship(&relationship)?; @@ -607,26 +614,16 @@ pub fn translate_exists_in_collection( let mut select = sql::helpers::simple_select(select_cols); select.from = Some(from_clause); - let new_root_and_current_tables = RootAndCurrentTables { - root_table: root_and_current_tables.root_table.clone(), - current_table: TableSourceAndReference { - reference: table.reference.clone(), - source: table.source, - }, - }; + let new_current_table_scope = current_table_scope.new_from_scope(table.clone()); // exists condition - let (exists_cond, exists_joins) = translate_expression_with_joins( - env, - state, - &new_root_and_current_tables, - predicate, - )?; + let (exists_cond, exists_joins) = + translate_expression_with_joins(env, state, &new_current_table_scope, predicate)?; // relationship where clause let cond = relationships::translate_column_mapping( env, - &root_and_current_tables.current_table, + current_table_scope.current_table(), &table.reference, exists_cond, relationship, @@ -652,7 +649,7 @@ pub fn translate_exists_in_collection( UnsupportedCapabilities::FieldArguments, ))?; } - let table = &root_and_current_tables.current_table; + let table = current_table_scope.current_table(); // Get the table information from the metadata. let collection_fields_info = env.lookup_fields_info(&table.source)?; @@ -718,21 +715,15 @@ pub fn translate_exists_in_collection( // Define a new root and current table structure pointing the current table // at the nested field. - let new_root_and_current_tables = RootAndCurrentTables { - root_table: root_and_current_tables.root_table.clone(), - current_table: TableSourceAndReference { + let new_current_table_scope = + current_table_scope.new_from_scope(TableSourceAndReference { reference: sql::ast::TableReference::AliasedTable(alias), source, - }, - }; + }); // Translate the predicate inside the exists. - let (exists_cond, exists_joins) = translate_expression_with_joins( - env, - state, - &new_root_and_current_tables, - predicate, - )?; + let (exists_cond, exists_joins) = + translate_expression_with_joins(env, state, &new_current_table_scope, predicate)?; // Construct the `where exists` expression. Ok(sql::helpers::where_exists_select( @@ -741,54 +732,99 @@ pub fn translate_exists_in_collection( sql::ast::Where(exists_cond), )) } + ndc_models::ExistsInCollection::NestedScalarCollection { + column_name: _, + arguments: _, + field_path: _, + } => Err(Error::CapabilityNotSupported( + UnsupportedCapabilities::NestedScalarCollection, + )), } } /// Extract the scalar type of a comparison target fn get_comparison_target_type( env: &Env, - root_and_current_tables: &RootAndCurrentTables, + current_table_scope: &TableScope, column: &models::ComparisonTarget, ) -> Result { match column { - models::ComparisonTarget::RootCollectionColumn { name, field_path } => { - let column = env - .lookup_fields_info(&root_and_current_tables.root_table.source)? - .lookup_column(name)?; - - let mut field_path = match field_path { - None => VecDeque::new(), - Some(field_path) => field_path.iter().collect(), - }; - get_column_scalar_type_name(env, &column.r#type, &mut field_path) - } + // models::ComparisonTarget::RootCollectionColumn { name, field_path } => { + // let column = env + // .lookup_fields_info(&root_and_current_tables.root_table.source)? + // .lookup_column(name)?; + + // let mut field_path = match field_path { + // None => VecDeque::new(), + // Some(field_path) => field_path.iter().collect(), + // }; + // get_column_scalar_type_name(env, &column.r#type, &mut field_path) + // } models::ComparisonTarget::Column { name, - path, field_path, + arguments: _, } => { let mut field_path = match field_path { None => VecDeque::new(), Some(field_path) => field_path.iter().collect(), }; - match path.last() { - None => { - let column = env - .lookup_fields_info(&root_and_current_tables.current_table.source)? - .lookup_column(name)?; + let column = env + .lookup_fields_info(¤t_table_scope.current_table().source)? + .lookup_column(name)?; - get_column_scalar_type_name(env, &column.r#type, &mut field_path) + get_column_scalar_type_name(env, &column.r#type, &mut field_path) + } + ndc_models::ComparisonTarget::Aggregate { path, aggregate } => { + match aggregate { + ndc_models::Aggregate::StarCount {} | ndc_models::Aggregate::ColumnCount { .. } => { + Ok("int8".into()) } - Some(last) => { - let column = env - .lookup_fields_info(&TableSource::Collection( - env.lookup_relationship(&last.relationship)? - .target_collection - .clone(), - ))? - .lookup_column(name)?; - - get_column_scalar_type_name(env, &column.r#type, &mut field_path) + ndc_models::Aggregate::SingleColumn { + column, + arguments: _, + field_path, + function, + } => { + // figure out column type, then get type for that aggregate from metadata + let mut field_path = match field_path { + None => VecDeque::new(), + Some(field_path) => field_path.iter().collect(), + }; + + let scalar_type_name = match path.last() { + None => { + let column = env + .lookup_fields_info(¤t_table_scope.current_table().source)? + .lookup_column(column)?; + + get_column_scalar_type_name(env, &column.r#type, &mut field_path)? + } + Some(last) => { + let column = env + .lookup_fields_info(&TableSource::Collection( + env.lookup_relationship(&last.relationship)? + .target_collection + .clone(), + ))? + .lookup_column(column)?; + + get_column_scalar_type_name(env, &column.r#type, &mut field_path)? + } + }; + + let scalar_type = env.metadata.scalar_types.0.get(&scalar_type_name); + + let aggregate_function = scalar_type + .ok_or(Error::ScalarTypeNotFound(scalar_type_name.clone()))? + .aggregate_functions + .get(function) + .ok_or(Error::MissingAggregateFunctionForScalar { + scalar: scalar_type_name, + function: function.to_owned(), + })?; + + Ok(aggregate_function.return_type.clone().into()) } } } diff --git a/crates/query-engine/translation/src/translation/query/relationships.rs b/crates/query-engine/translation/src/translation/query/relationships.rs index eab8c54b7..0e9eb08d4 100644 --- a/crates/query-engine/translation/src/translation/query/relationships.rs +++ b/crates/query-engine/translation/src/translation/query/relationships.rs @@ -5,7 +5,7 @@ use std::collections::BTreeMap; use ndc_models as models; use super::root; -use crate::translation::error::Error; +use crate::translation::error::{Error, UnsupportedCapabilities}; use crate::translation::helpers::{Env, State, TableSourceAndReference}; use query_engine_sql::sql; @@ -99,6 +99,14 @@ pub fn translate_column_mapping( .iter() .map(|(source_col, target_col)| { let source_column_info = table_info.lookup_column(source_col)?; + // target_col contains at least one element, the column being referenced + // if nested relationships are supported, it additionally contains the path to navigate to the related column + // we currently don't support nested relationships, so erring out if the pattern does not match + let [target_col] = target_col.as_slice() else { + return Err(Error::CapabilityNotSupported( + UnsupportedCapabilities::NestedRelationships, + )); + }; let target_column_info = target_collection_info.lookup_column(target_col)?; Ok(sql::ast::Expression::BinaryOperation { left: Box::new(sql::ast::Expression::ColumnReference( diff --git a/crates/query-engine/translation/src/translation/query/root.rs b/crates/query-engine/translation/src/translation/query/root.rs index 807c31e0f..779897e36 100644 --- a/crates/query-engine/translation/src/translation/query/root.rs +++ b/crates/query-engine/translation/src/translation/query/root.rs @@ -14,7 +14,7 @@ use super::sorting; use crate::translation::error::Error; use crate::translation::helpers::TableSource; use crate::translation::helpers::{ - CollectionInfo, Env, RootAndCurrentTables, State, TableSourceAndReference, + CollectionInfo, Env, State, TableScope, TableSourceAndReference, }; use query_engine_sql::sql; @@ -180,10 +180,7 @@ fn translate_rows( reference: sql::ast::TableReference::AliasedTable(alias.clone()), }; - let root_and_current_table = RootAndCurrentTables { - root_table: current_table.clone(), - current_table: current_table.clone(), - }; + let current_table_scope = TableScope::new(current_table.clone()); let from_clause = sql::ast::From::Select { select: Box::new(subquery_select), @@ -225,7 +222,7 @@ fn translate_rows( // if order by crosses a relationship, the order by clause and resulting joins are created at this level // the limit clause is also applied here let (order_by, order_by_joins) = - sorting::translate(env, state, &root_and_current_table, query.order_by.as_ref())?; + sorting::translate(env, state, ¤t_table_scope, query.order_by.as_ref())?; fields_select.order_by = order_by; fields_select.joins.extend(order_by_joins); @@ -239,7 +236,7 @@ fn translate_rows( // if we aren't ordering across a relationship, we expect joins to be empty, and the order by and limit to be applied in the subquery // however, we must repeat the order by clause, else ordering may not be guaranteed after joins let (order_by, _order_by_joins) = - sorting::translate(env, state, &root_and_current_table, query.order_by.as_ref())?; + sorting::translate(env, state, ¤t_table_scope, query.order_by.as_ref())?; fields_select.order_by = order_by; } @@ -257,10 +254,7 @@ fn rows_subquery( let (current_table, from_clause) = make_reference_and_from_clause(env, state, make_from)?; // the root table and the current table are the same at this point - let subquery_root_and_current_table = RootAndCurrentTables { - root_table: current_table.clone(), - current_table: current_table.clone(), - }; + let subquery_table_scope = TableScope::new(current_table.clone()); // we want to put the where clause, including any required joins, in a subquery that is applied before any joins used to navigate relationships // this improves performance on cockroachdb @@ -272,19 +266,15 @@ fn rows_subquery( state, join_predicate, query, - &subquery_root_and_current_table, + &subquery_table_scope, )?; // unless there is an order by clause that traverses relationships, we can put the order by clause and limit in the subquery if !order_by_crosses_relationships(query) { // translate order_by // we expect order_by_joins to be empty, because we're not traversing any relationship - let (order_by, _order_by_joins) = sorting::translate( - env, - state, - &subquery_root_and_current_table, - query.order_by.as_ref(), - )?; + let (order_by, _order_by_joins) = + sorting::translate(env, state, &subquery_table_scope, query.order_by.as_ref())?; subquery_select.order_by = order_by; // Add the limit. subquery_select.limit = sql::ast::Limit { @@ -301,12 +291,12 @@ fn translate_where_with_join_predicate( state: &mut State, join_predicate: Option<&JoinPredicate<'_, '_>>, query: &models::Query, - root_and_current_table: &RootAndCurrentTables, + current_table_scope: &TableScope, ) -> Result { // translate where let filter = match &query.predicate { None => Ok(sql::helpers::true_expr()), - Some(predicate) => filtering::translate(env, state, root_and_current_table, predicate), + Some(predicate) => filtering::translate(env, state, current_table_scope, predicate), }?; // Apply a join predicate if we want one. @@ -318,7 +308,7 @@ fn translate_where_with_join_predicate( sql::ast::Where(relationships::translate_column_mapping( env, join_predicate.join_with, - &root_and_current_table.current_table.reference, + ¤t_table_scope.current_table().reference, filter, // AND with the existing filter. join_predicate.relationship, )?) @@ -335,8 +325,7 @@ fn order_by_crosses_relationships(query: &models::Query) -> bool { .iter() .any(|element| match &element.target { ndc_models::OrderByTarget::Column { path, .. } - | ndc_models::OrderByTarget::SingleColumnAggregate { path, .. } - | ndc_models::OrderByTarget::StarCountAggregate { path } => !path.is_empty(), + | ndc_models::OrderByTarget::Aggregate { path, .. } => !path.is_empty(), }) }) } @@ -354,29 +343,37 @@ pub fn translate_query_part( query: &models::Query, select: &mut sql::ast::Select, ) -> Result<(), Error> { - // the root table and the current table are the same at this point - let root_and_current_tables = RootAndCurrentTables { - root_table: current_table.clone(), - current_table: current_table.clone(), - }; + let current_table_scope = TableScope::new(current_table.clone()); // translate order_by - let (order_by, order_by_joins) = sorting::translate( - env, - state, - &root_and_current_tables, - query.order_by.as_ref(), - )?; + let (order_by, order_by_joins) = + sorting::translate(env, state, ¤t_table_scope, query.order_by.as_ref())?; select.joins.extend(order_by_joins); - select.where_ = translate_where_with_join_predicate( - env, - state, - join_predicate, - query, - &root_and_current_tables, - )?; + // translate where + let filter = match &query.predicate { + None => Ok(sql::helpers::true_expr()), + Some(predicate) => filtering::translate(env, state, ¤t_table_scope, predicate), + }?; + + // Apply a join predicate if we want one. + match join_predicate { + // Only apply the existing filter. + None => { + select.where_ = sql::ast::Where(filter); + } + Some(join_predicate) => { + // Apply the join predicate. + select.where_ = sql::ast::Where(relationships::translate_column_mapping( + env, + join_predicate.join_with, + ¤t_table.reference, + filter, // AND with the existing filter. + join_predicate.relationship, + )?); + } + } select.order_by = order_by; diff --git a/crates/query-engine/translation/src/translation/query/sorting.rs b/crates/query-engine/translation/src/translation/query/sorting.rs index 32e4cd7b2..512282472 100644 --- a/crates/query-engine/translation/src/translation/query/sorting.rs +++ b/crates/query-engine/translation/src/translation/query/sorting.rs @@ -10,7 +10,7 @@ use super::relationships; use super::root; use crate::translation::error::Error; use crate::translation::helpers::{ - wrap_in_field_path, Env, FieldPath, FieldsInfo, RootAndCurrentTables, State, TableSource, + wrap_in_field_path, Env, FieldPath, FieldsInfo, State, TableScope, TableSource, TableSourceAndReference, }; use query_engine_sql::sql; @@ -22,7 +22,7 @@ use query_engine_sql::sql; pub fn translate( env: &Env, state: &mut State, - root_and_current_tables: &RootAndCurrentTables, + current_table_scope: &TableScope, order_by: Option<&models::OrderBy>, ) -> Result<(sql::ast::OrderBy, Vec), Error> { let mut joins: Vec = vec![]; @@ -40,7 +40,7 @@ pub fn translate( translate_order_by_target_group( env, state, - root_and_current_tables, + current_table_scope, element_group, &mut joins, ) @@ -97,11 +97,15 @@ struct Column(models::FieldName); /// An aggregate operation to select from a table used in an order by. #[derive(Debug)] enum Aggregate { - CountStar, + StarCount, SingleColumn { column: models::FieldName, function: models::AggregateFunctionName, }, + ColumnCount { + column: models::FieldName, + distinct: bool, + }, } impl OrderByElementGroup<'_> { @@ -143,6 +147,7 @@ fn group_elements(elements: &[models::OrderByElement]) -> Vec Vec column_element_groups.insert( hash_path(path), ( @@ -165,27 +171,54 @@ fn group_elements(elements: &[models::OrderByElement]) -> Vec aggregate_element_groups.insert( - hash_path(path), - (i, path, element.order_direction, Aggregate::CountStar), - ), - models::OrderByTarget::SingleColumnAggregate { - path, - column, - function, - field_path: _, - } => aggregate_element_groups.insert( - hash_path(path), - ( - i, - path, - element.order_direction, - Aggregate::SingleColumn { - column: column.clone(), - function: function.clone(), - }, + models::OrderByTarget::Aggregate { path, aggregate } => match aggregate { + models::Aggregate::ColumnCount { + column, + arguments: _, + field_path, + distinct, + } => aggregate_element_groups.insert( + hash_path(path), + ( + i, + path, + field_path.into(), + element.order_direction, + Aggregate::ColumnCount { + column: column.clone(), + distinct: *distinct, + }, + ), ), - ), + models::Aggregate::SingleColumn { + column, + arguments: _, + function, + field_path, + } => aggregate_element_groups.insert( + hash_path(path), + ( + i, + path, + field_path.into(), + element.order_direction, + Aggregate::SingleColumn { + column: column.clone(), + function: function.clone(), + }, + ), + ), + models::Aggregate::StarCount {} => aggregate_element_groups.insert( + hash_path(path), + ( + i, + path, + (&None).into(), + element.order_direction, + Aggregate::StarCount, + ), + ), + }, } } @@ -214,7 +247,7 @@ fn group_elements(elements: &[models::OrderByElement]) -> Vec Vec, ) -> Result, Error> { - let column_or_relationship_select = build_select_and_joins_for_order_by_group( - env, - state, - root_and_current_tables, - element_group, - )?; + let column_or_relationship_select = + build_select_and_joins_for_order_by_group(env, state, current_table_scope, element_group)?; match column_or_relationship_select { // The column is from the source table, we just need to query it directly. @@ -270,8 +299,8 @@ fn translate_order_by_target_group( ColumnsOrSelect::Select { columns, select } => { // Give it a nice unique alias. let table_alias = state.make_order_by_table_alias( - root_and_current_tables - .current_table + current_table_scope + .current_table() .source .name_for_alias() .as_str(), @@ -348,7 +377,7 @@ enum ColumnsOrSelect { fn build_select_and_joins_for_order_by_group( env: &Env, state: &mut State, - root_and_current_tables: &RootAndCurrentTables, + current_table_scope: &TableScope, element_group: &OrderByElementGroup, ) -> Result { // We want to build a select query where "Track" is the root table, and "Artist"."Name" @@ -382,26 +411,22 @@ fn build_select_and_joins_for_order_by_group( } OrderByElementGroup::Columns { .. } => { // If the path is empty, we don't need to build a query, just return the columns. - let table = - env.lookup_fields_info(&root_and_current_tables.current_table.source)?; - let columns = translate_targets( - &table, - &root_and_current_tables.current_table, - element_group, - )? - .into_iter() - .map(|column| { - ( - column.index, - column.direction, - column.field_path, - sql::ast::ColumnReference::AliasedColumn { - table: root_and_current_tables.current_table.reference.clone(), - column: column.alias, - }, - ) - }) - .collect(); + let table = env.lookup_fields_info(¤t_table_scope.current_table().source)?; + let columns = + translate_targets(&table, current_table_scope.current_table(), element_group)? + .into_iter() + .map(|column| { + ( + column.index, + column.direction, + column.field_path, + sql::ast::ColumnReference::AliasedColumn { + table: current_table_scope.current_table().reference.clone(), + column: column.alias, + }, + ) + }) + .collect(); Ok(ColumnsOrSelect::Columns(columns)) } } @@ -415,7 +440,7 @@ fn build_select_and_joins_for_order_by_group( // from the next join, we need to select these. let (last_table, cols) = path.iter().enumerate().try_fold( ( - root_and_current_tables.current_table.clone(), + current_table_scope.current_table().clone(), // this is a dummy value that will be ignored, since we only care about returning // the columns from the last table. PathElementSelectColumns::RelationshipColumns(vec![]), @@ -423,7 +448,6 @@ fn build_select_and_joins_for_order_by_group( |(last_table, _), (index, path_element)| { process_path_element_for_order_by_targets( (env, state), - root_and_current_tables, element_group, &mut joins, (last_table, (index, path_element)), @@ -454,9 +478,23 @@ fn build_select_and_joins_for_order_by_group( // apply an aggregate function if needed. match &select_expr.aggregate { None => column, - Some(function) => sql::ast::Expression::FunctionCall { - function: function.clone(), - args: vec![column], + Some(aggregate) => match aggregate { + OrderByAggregate::Function { function } => { + sql::ast::Expression::FunctionCall { + function: function.clone(), + args: vec![column], + } + } + OrderByAggregate::StarCount | OrderByAggregate::Count => { + sql::ast::Expression::Count( + sql::ast::CountType::Simple(Box::new(column)), + ) + } + OrderByAggregate::CountDistinct => { + sql::ast::Expression::Count( + sql::ast::CountType::Distinct(Box::new(column)), + ) + } }, } }) @@ -532,8 +570,16 @@ struct OrderBySelectExpression { field_path: FieldPath, alias: sql::ast::ColumnAlias, expression: sql::ast::Expression, - aggregate: Option, + aggregate: Option, +} + +enum OrderByAggregate { + Function { function: sql::ast::Function }, + StarCount, + Count, + CountDistinct, } + /// An expression selected from an intermediate relationship table. struct OrderByRelationshipColumn { alias: sql::ast::ColumnAlias, @@ -546,7 +592,6 @@ struct OrderByRelationshipColumn { /// from the next join, we need to select these. fn process_path_element_for_order_by_targets( (env, state): (&Env, &mut State), - root_and_current_tables: &RootAndCurrentTables, element_group: &OrderByElementGroup, // to get the information about this path element we need to select from the relevant table // and join with the previous table. We add a new join to this list of joins. @@ -622,10 +667,7 @@ fn process_path_element_for_order_by_targets( let select = select_for_path_element( env, state, - &RootAndCurrentTables { - root_table: root_and_current_tables.root_table.clone(), - current_table: last_table, - }, + &last_table, relationship, path_element.predicate.as_deref(), sql::ast::SelectList::SelectList(select_cols.aliases_and_expressions()), @@ -689,7 +731,7 @@ fn translate_targets( .iter() .map(|element| { match &element.element { - Aggregate::CountStar => { + Aggregate::StarCount => { let column_alias = sql::helpers::make_column_alias("count".to_string()); Ok(OrderBySelectExpression { index: element.index, @@ -698,7 +740,7 @@ fn translate_targets( // Aggregates do not have a field path. field_path: (&None).into(), expression: sql::ast::Expression::Value(sql::ast::Value::Int4(1)), - aggregate: Some(sql::ast::Function::Unknown("COUNT".to_string())), + aggregate: Some(OrderByAggregate::StarCount), }) } Aggregate::SingleColumn { column, function } => { @@ -720,7 +762,33 @@ fn translate_targets( column: selected_column_alias, }, ), - aggregate: Some(sql::ast::Function::Unknown(function.to_string())), + aggregate: Some(OrderByAggregate::Function { + function: sql::ast::Function::Unknown(function.to_string()), + }), + }) + } + Aggregate::ColumnCount { column, distinct } => { + let selected_column = target_collection.lookup_column(column)?; + let selected_column_alias = + sql::helpers::make_column_alias(selected_column.name.0); + + Ok(OrderBySelectExpression { + index: element.index, + direction: element.direction, + alias: selected_column_alias.clone(), + // Aggregates do not have a field path. + field_path: (&None).into(), + expression: sql::ast::Expression::ColumnReference( + sql::ast::ColumnReference::AliasedColumn { + table: table.reference.clone(), + column: selected_column_alias, + }, + ), + aggregate: Some(if *distinct { + OrderByAggregate::CountDistinct + } else { + OrderByAggregate::Count + }), }) } } @@ -760,7 +828,7 @@ fn from_clause_for_path_element( fn select_for_path_element( env: &Env, state: &mut State, - root_and_current_tables: &RootAndCurrentTables, + current_table: &TableSourceAndReference, relationship: &models::Relationship, predicate: Option<&models::Expression>, select_list: sql::ast::SelectList, @@ -771,16 +839,14 @@ fn select_for_path_element( select.select_list = select_list; select.from = Some(from_clause); - let predicate_tables = RootAndCurrentTables { - root_table: root_and_current_tables.root_table.clone(), - current_table: join_table, - }; + // path elements get a fresh scope each, and cannot use named scopes to access other tables in the path + let predicate_tables = TableScope::new(join_table); // generate a condition for this join. let join_condition = relationships::translate_column_mapping( env, - &root_and_current_tables.current_table, - &predicate_tables.current_table.reference, + current_table, + &predicate_tables.current_table().reference, sql::helpers::empty_where(), relationship, )?; diff --git a/crates/query-engine/translation/tests/goldenfiles/dup_array_relationship/request.json b/crates/query-engine/translation/tests/goldenfiles/dup_array_relationship/request.json index 4fa7b4d17..6d74fa7e3 100644 --- a/crates/query-engine/translation/tests/goldenfiles/dup_array_relationship/request.json +++ b/crates/query-engine/translation/tests/goldenfiles/dup_array_relationship/request.json @@ -38,7 +38,7 @@ "collection_relationships": { "ArtistAlbums": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album", diff --git a/crates/query-engine/translation/tests/goldenfiles/mutations/v2_insert_return_object_relationship/configuration.json b/crates/query-engine/translation/tests/goldenfiles/mutations/v2_insert_return_object_relationship/configuration.json new file mode 100644 index 000000000..4ddcc6077 --- /dev/null +++ b/crates/query-engine/translation/tests/goldenfiles/mutations/v2_insert_return_object_relationship/configuration.json @@ -0,0 +1,377 @@ +{ + "version": "5", + "$schema": "../../../../../../../static/configuration.schema.json", + "connectionSettings": { + "connectionUri": { + "variable": "CONNECTION_URI" + }, + "poolSettings": { + "maxConnections": 50, + "poolTimeout": 30, + "idleTimeout": 180, + "checkConnectionAfterIdle": 60, + "connectionLifetime": 600 + }, + "isolationLevel": "ReadCommitted" + }, + "metadata": { + "tables": { + "Album": { + "schemaName": "public", + "tableName": "Album", + "columns": { + "AlbumId": { + "name": "AlbumId", + "type": { + "scalarType": "int4" + }, + "nullable": "nullable", + "description": null + }, + "ArtistId": { + "name": "ArtistId", + "type": { + "scalarType": "int4" + }, + "nullable": "nullable", + "description": null + }, + "Title": { + "name": "Title", + "type": { + "scalarType": "varchar" + }, + "nullable": "nullable", + "description": null + } + }, + "uniquenessConstraints": {}, + "foreignRelations": {}, + "description": null + }, + "Artist": { + "schemaName": "public", + "tableName": "Artist", + "columns": { + "ArtistId": { + "name": "ArtistId", + "type": { + "scalarType": "int4" + }, + "nullable": "nullable", + "description": null + }, + "Name": { + "name": "Name", + "type": { + "scalarType": "varchar" + }, + "nullable": "nullable", + "description": null + } + }, + "uniquenessConstraints": {}, + "foreignRelations": {}, + "description": null + } + }, + "types": { + "scalar": { + "int4": { + "typeName": "int4", + "schemaName": "pg_catalog", + "description": null, + "aggregateFunctions": {}, + "comparisonOperators": {}, + "typeRepresentation": "int32" + }, + "varchar": { + "typeName": "varchar", + "schemaName": "pg_catalog", + "description": null, + "aggregateFunctions": {}, + "comparisonOperators": {}, + "typeRepresentation": "string" + } + }, + "composite": {} + }, + "nativeOperations": { + "queries": {}, + "mutations": {} + } + }, + "introspectionOptions": { + "excludedSchemas": [ + "information_schema", + "pg_catalog", + "tiger", + "crdb_internal", + "columnar", + "columnar_internal" + ], + "unqualifiedSchemasForTables": ["public"], + "unqualifiedSchemasForTypesAndProcedures": [ + "public", + "pg_catalog", + "tiger" + ], + "comparisonOperatorMapping": [ + { + "operatorName": "=", + "exposedName": "_eq", + "operatorKind": "equal" + }, + { + "operatorName": "<=", + "exposedName": "_lte", + "operatorKind": "custom" + }, + { + "operatorName": ">", + "exposedName": "_gt", + "operatorKind": "custom" + }, + { + "operatorName": ">=", + "exposedName": "_gte", + "operatorKind": "custom" + }, + { + "operatorName": "<", + "exposedName": "_lt", + "operatorKind": "custom" + }, + { + "operatorName": "<>", + "exposedName": "_neq", + "operatorKind": "custom" + }, + { + "operatorName": "!=", + "exposedName": "_neq", + "operatorKind": "custom" + }, + { + "operatorName": "LIKE", + "exposedName": "_like", + "operatorKind": "custom" + }, + { + "operatorName": "NOT LIKE", + "exposedName": "_nlike", + "operatorKind": "custom" + }, + { + "operatorName": "ILIKE", + "exposedName": "_ilike", + "operatorKind": "custom" + }, + { + "operatorName": "NOT ILIKE", + "exposedName": "_nilike", + "operatorKind": "custom" + }, + { + "operatorName": "SIMILAR TO", + "exposedName": "_similar", + "operatorKind": "custom" + }, + { + "operatorName": "NOT SIMILAR TO", + "exposedName": "_nsimilar", + "operatorKind": "custom" + }, + { + "operatorName": "~~", + "exposedName": "_like", + "operatorKind": "custom" + }, + { + "operatorName": "!~~", + "exposedName": "_nlike", + "operatorKind": "custom" + }, + { + "operatorName": "~~*", + "exposedName": "_ilike", + "operatorKind": "custom" + }, + { + "operatorName": "!~~*", + "exposedName": "_nilike", + "operatorKind": "custom" + }, + { + "operatorName": "~", + "exposedName": "_regex", + "operatorKind": "custom" + }, + { + "operatorName": "!~", + "exposedName": "_nregex", + "operatorKind": "custom" + }, + { + "operatorName": "~*", + "exposedName": "_iregex", + "operatorKind": "custom" + }, + { + "operatorName": "!~*", + "exposedName": "_niregex", + "operatorKind": "custom" + } + ], + "introspectPrefixFunctionComparisonOperators": [ + "box_above", + "box_below", + "box_contain", + "box_contain_pt", + "box_contained", + "box_left", + "box_overabove", + "box_overbelow", + "box_overlap", + "box_overleft", + "box_overright", + "box_right", + "box_same", + "circle_above", + "circle_below", + "circle_contain", + "circle_contain_pt", + "circle_contained", + "circle_left", + "circle_overabove", + "circle_overbelow", + "circle_overlap", + "circle_overleft", + "circle_overright", + "circle_right", + "circle_same", + "contains_2d", + "equals", + "geography_overlaps", + "geometry_above", + "geometry_below", + "geometry_contained_3d", + "geometry_contains", + "geometry_contains_3d", + "geometry_contains_nd", + "geometry_left", + "geometry_overabove", + "geometry_overbelow", + "geometry_overlaps", + "geometry_overlaps_3d", + "geometry_overlaps_nd", + "geometry_overleft", + "geometry_overright", + "geometry_right", + "geometry_same", + "geometry_same_3d", + "geometry_same_nd", + "geometry_within", + "geometry_within_nd", + "inet_same_family", + "inter_lb", + "inter_sb", + "inter_sl", + "is_contained_2d", + "ishorizontal", + "isparallel", + "isperp", + "isvertical", + "jsonb_contained", + "jsonb_contains", + "jsonb_exists", + "jsonb_path_exists_opr", + "jsonb_path_match_opr", + "line_intersect", + "line_parallel", + "line_perp", + "lseg_intersect", + "lseg_parallel", + "lseg_perp", + "network_overlap", + "network_sub", + "network_sup", + "on_pb", + "on_pl", + "on_ppath", + "on_ps", + "on_sb", + "on_sl", + "overlaps_2d", + "path_contain_pt", + "path_inter", + "point_above", + "point_below", + "point_horiz", + "point_left", + "point_right", + "point_vert", + "poly_above", + "poly_below", + "poly_contain", + "poly_contain_pt", + "poly_contained", + "poly_left", + "poly_overabove", + "poly_overbelow", + "poly_overlap", + "poly_overleft", + "poly_overright", + "poly_right", + "poly_same", + "pt_contained_poly", + "st_3dintersects", + "st_contains", + "st_containsproperly", + "st_coveredby", + "st_covers", + "st_crosses", + "st_disjoint", + "st_equals", + "st_intersects", + "st_isvalid", + "st_orderingequals", + "st_overlaps", + "st_relatematch", + "st_touches", + "st_within", + "starts_with", + "ts_match_qv", + "ts_match_tq", + "ts_match_tt", + "ts_match_vq", + "tsq_mcontained", + "tsq_mcontains", + "xmlexists", + "xmlvalidate", + "xpath_exists" + ], + "typeRepresentations": { + "bit": "string", + "bool": "boolean", + "bpchar": "string", + "char": "string", + "date": "date", + "float4": "float32", + "float8": "float64", + "int2": "int16", + "int4": "int32", + "int8": "int64AsString", + "numeric": "bigDecimalAsString", + "text": "string", + "time": "time", + "timestamp": "timestamp", + "timestamptz": "timestamptz", + "timetz": "timetz", + "uuid": "uUID", + "varchar": "string" + } + }, + "mutationsVersion": "v2", + "mutationsPrefix": null +} diff --git a/crates/query-engine/translation/tests/goldenfiles/mutations/v2_insert_return_object_relationship/request.json b/crates/query-engine/translation/tests/goldenfiles/mutations/v2_insert_return_object_relationship/request.json new file mode 100644 index 000000000..0c4166d87 --- /dev/null +++ b/crates/query-engine/translation/tests/goldenfiles/mutations/v2_insert_return_object_relationship/request.json @@ -0,0 +1,70 @@ +{ + "$schema": "../../../../../../../static/mutation.schema.json", + "operations": [ + { + "type": "procedure", + "name": "v2_insert_Album", + "arguments": { + "objects": [ + { + "ArtistId": 276, + "AlbumId": 348, + "Title": "Lake Mannion" + } + ], + "post_check": { + "type": "or", + "expressions": [] + } + }, + "fields": { + "type": "object", + "fields": { + "affected_rows": { + "column": "affected_rows", + "type": "column" + }, + "returning": { + "type": "column", + "column": "returning", + "fields": { + "type": "array", + "fields": { + "type": "object", + "fields": { + "Title": { + "type": "column", + "column": "Title" + }, + "Artist": { + "type": "relationship", + "arguments": {}, + "relationship": "Album_Artist", + "query": { + "fields": { + "Name": { + "type": "column", + "column": "Name" + } + } + } + } + } + } + } + } + } + } + } + ], + "collection_relationships": { + "Album_Artist": { + "arguments": {}, + "column_mapping": { + "ArtistId": ["ArtistId"] + }, + "relationship_type": "object", + "target_collection": "Artist" + } + } +} diff --git a/crates/query-engine/translation/tests/goldenfiles/native_queries/select_artist_with_album_by_title/request.json b/crates/query-engine/translation/tests/goldenfiles/native_queries/select_artist_with_album_by_title/request.json index c9b5dd3cf..2a06aa885 100644 --- a/crates/query-engine/translation/tests/goldenfiles/native_queries/select_artist_with_album_by_title/request.json +++ b/crates/query-engine/translation/tests/goldenfiles/native_queries/select_artist_with_album_by_title/request.json @@ -45,7 +45,7 @@ "collection_relationships": { "Albums": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "album_by_title", diff --git a/crates/query-engine/translation/tests/goldenfiles/native_queries/select_artist_with_album_by_title_relationship_arguments/request.json b/crates/query-engine/translation/tests/goldenfiles/native_queries/select_artist_with_album_by_title_relationship_arguments/request.json index b94ce2f5b..4b6f0512b 100644 --- a/crates/query-engine/translation/tests/goldenfiles/native_queries/select_artist_with_album_by_title_relationship_arguments/request.json +++ b/crates/query-engine/translation/tests/goldenfiles/native_queries/select_artist_with_album_by_title_relationship_arguments/request.json @@ -57,7 +57,7 @@ "collection_relationships": { "Albums": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "album_by_title", diff --git a/crates/query-engine/translation/tests/goldenfiles/nested_aggregates/request.json b/crates/query-engine/translation/tests/goldenfiles/nested_aggregates/request.json index e08bf0303..33c8ad81d 100644 --- a/crates/query-engine/translation/tests/goldenfiles/nested_aggregates/request.json +++ b/crates/query-engine/translation/tests/goldenfiles/nested_aggregates/request.json @@ -35,7 +35,7 @@ "collection_relationships": { "ArtistToAlbums": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album", diff --git a/crates/query-engine/translation/tests/goldenfiles/nested_array_relationships/request.json b/crates/query-engine/translation/tests/goldenfiles/nested_array_relationships/request.json index 2235da7da..c1d37ce07 100644 --- a/crates/query-engine/translation/tests/goldenfiles/nested_array_relationships/request.json +++ b/crates/query-engine/translation/tests/goldenfiles/nested_array_relationships/request.json @@ -32,7 +32,7 @@ "collection_relationships": { "ArtistAlbums": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album", @@ -40,7 +40,7 @@ }, "AlbumTracks": { "column_mapping": { - "AlbumId": "AlbumId" + "AlbumId": ["AlbumId"] }, "relationship_type": "array", "target_collection": "Track", diff --git a/crates/query-engine/translation/tests/goldenfiles/nested_recursive_relationship/request.json b/crates/query-engine/translation/tests/goldenfiles/nested_recursive_relationship/request.json index 69545d9ac..a97cc560b 100644 --- a/crates/query-engine/translation/tests/goldenfiles/nested_recursive_relationship/request.json +++ b/crates/query-engine/translation/tests/goldenfiles/nested_recursive_relationship/request.json @@ -32,7 +32,7 @@ "collection_relationships": { "ArtistAlbums": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album", @@ -40,7 +40,7 @@ }, "AlbumArtist": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "object", "target_collection": "Artist", diff --git a/crates/query-engine/translation/tests/goldenfiles/select_composite_column_nested_field_count/configuration.json b/crates/query-engine/translation/tests/goldenfiles/select_composite_column_nested_field_count/configuration.json new file mode 100644 index 000000000..423a3bd98 --- /dev/null +++ b/crates/query-engine/translation/tests/goldenfiles/select_composite_column_nested_field_count/configuration.json @@ -0,0 +1,415 @@ +{ + "version": "5", + "$schema": "../../../../../../static/configuration.schema.json", + "connectionSettings": { + "connectionUri": { + "variable": "CONNECTION_URI" + }, + "poolSettings": { + "maxConnections": 50, + "poolTimeout": 30, + "idleTimeout": 180, + "checkConnectionAfterIdle": 60, + "connectionLifetime": 600 + }, + "isolationLevel": "ReadCommitted" + }, + "metadata": { + "tables": { + "persons": { + "schemaName": "public", + "tableName": "persons", + "columns": { + "id": { + "name": "id", + "type": { + "scalarType": "int4" + }, + "nullable": "nullable", + "description": null + }, + "person": { + "name": "person", + "type": { + "compositeType": "person" + }, + "nullable": "nullable", + "description": null + } + }, + "uniquenessConstraints": {}, + "foreignRelations": {}, + "description": null + } + }, + "types": { + "scalar": { + "text": { + "typeName": "text", + "schemaName": "pg_catalog", + "description": null, + "aggregateFunctions": {}, + "comparisonOperators": {}, + "typeRepresentation": "string" + }, + "int4": { + "typeName": "int4", + "schemaName": "pg_catalog", + "description": null, + "aggregateFunctions": {}, + "comparisonOperators": {}, + "typeRepresentation": "int32" + } + }, + "composite": { + "person": { + "typeName": "person", + "schemaName": "public", + "fields": { + "address": { + "fieldName": "address", + "type": { + "compositeType": "person_address" + }, + "description": null + }, + "name": { + "fieldName": "name", + "type": { + "compositeType": "person_name" + }, + "description": null + }, + "age": { + "fieldName": "age", + "type": { + "scalarType": "int4" + }, + "description": null + } + }, + "description": null + }, + "person_address": { + "typeName": "person_address", + "schemaName": "public", + "fields": { + "address_line_1": { + "fieldName": "address_line_1", + "type": { + "scalarType": "text" + }, + "description": null + }, + "address_line_2": { + "fieldName": "address_line_2", + "type": { + "scalarType": "text" + }, + "description": null + } + }, + "description": null + }, + "person_name": { + "typeName": "person_name", + "schemaName": "public", + "fields": { + "first_name": { + "fieldName": "first_name", + "type": { + "scalarType": "text" + }, + "description": null + }, + "last_name": { + "fieldName": "last_name", + "type": { + "scalarType": "text" + }, + "description": null + } + }, + "description": null + } + } + }, + "nativeOperations": { + "queries": {}, + "mutations": {} + } + }, + "introspectionOptions": { + "excludedSchemas": [ + "information_schema", + "pg_catalog", + "tiger", + "crdb_internal", + "columnar", + "columnar_internal" + ], + "unqualifiedSchemasForTables": ["public"], + "unqualifiedSchemasForTypesAndProcedures": [ + "public", + "pg_catalog", + "tiger" + ], + "comparisonOperatorMapping": [ + { + "operatorName": "=", + "exposedName": "_eq", + "operatorKind": "equal" + }, + { + "operatorName": "<=", + "exposedName": "_lte", + "operatorKind": "custom" + }, + { + "operatorName": ">", + "exposedName": "_gt", + "operatorKind": "custom" + }, + { + "operatorName": ">=", + "exposedName": "_gte", + "operatorKind": "custom" + }, + { + "operatorName": "<", + "exposedName": "_lt", + "operatorKind": "custom" + }, + { + "operatorName": "<>", + "exposedName": "_neq", + "operatorKind": "custom" + }, + { + "operatorName": "!=", + "exposedName": "_neq", + "operatorKind": "custom" + }, + { + "operatorName": "LIKE", + "exposedName": "_like", + "operatorKind": "custom" + }, + { + "operatorName": "NOT LIKE", + "exposedName": "_nlike", + "operatorKind": "custom" + }, + { + "operatorName": "ILIKE", + "exposedName": "_ilike", + "operatorKind": "custom" + }, + { + "operatorName": "NOT ILIKE", + "exposedName": "_nilike", + "operatorKind": "custom" + }, + { + "operatorName": "SIMILAR TO", + "exposedName": "_similar", + "operatorKind": "custom" + }, + { + "operatorName": "NOT SIMILAR TO", + "exposedName": "_nsimilar", + "operatorKind": "custom" + }, + { + "operatorName": "~~", + "exposedName": "_like", + "operatorKind": "custom" + }, + { + "operatorName": "!~~", + "exposedName": "_nlike", + "operatorKind": "custom" + }, + { + "operatorName": "~~*", + "exposedName": "_ilike", + "operatorKind": "custom" + }, + { + "operatorName": "!~~*", + "exposedName": "_nilike", + "operatorKind": "custom" + }, + { + "operatorName": "~", + "exposedName": "_regex", + "operatorKind": "custom" + }, + { + "operatorName": "!~", + "exposedName": "_nregex", + "operatorKind": "custom" + }, + { + "operatorName": "~*", + "exposedName": "_iregex", + "operatorKind": "custom" + }, + { + "operatorName": "!~*", + "exposedName": "_niregex", + "operatorKind": "custom" + } + ], + "introspectPrefixFunctionComparisonOperators": [ + "box_above", + "box_below", + "box_contain", + "box_contain_pt", + "box_contained", + "box_left", + "box_overabove", + "box_overbelow", + "box_overlap", + "box_overleft", + "box_overright", + "box_right", + "box_same", + "circle_above", + "circle_below", + "circle_contain", + "circle_contain_pt", + "circle_contained", + "circle_left", + "circle_overabove", + "circle_overbelow", + "circle_overlap", + "circle_overleft", + "circle_overright", + "circle_right", + "circle_same", + "contains_2d", + "equals", + "geography_overlaps", + "geometry_above", + "geometry_below", + "geometry_contained_3d", + "geometry_contains", + "geometry_contains_3d", + "geometry_contains_nd", + "geometry_left", + "geometry_overabove", + "geometry_overbelow", + "geometry_overlaps", + "geometry_overlaps_3d", + "geometry_overlaps_nd", + "geometry_overleft", + "geometry_overright", + "geometry_right", + "geometry_same", + "geometry_same_3d", + "geometry_same_nd", + "geometry_within", + "geometry_within_nd", + "inet_same_family", + "inter_lb", + "inter_sb", + "inter_sl", + "is_contained_2d", + "ishorizontal", + "isparallel", + "isperp", + "isvertical", + "jsonb_contained", + "jsonb_contains", + "jsonb_exists", + "jsonb_path_exists_opr", + "jsonb_path_match_opr", + "line_intersect", + "line_parallel", + "line_perp", + "lseg_intersect", + "lseg_parallel", + "lseg_perp", + "network_overlap", + "network_sub", + "network_sup", + "on_pb", + "on_pl", + "on_ppath", + "on_ps", + "on_sb", + "on_sl", + "overlaps_2d", + "path_contain_pt", + "path_inter", + "point_above", + "point_below", + "point_horiz", + "point_left", + "point_right", + "point_vert", + "poly_above", + "poly_below", + "poly_contain", + "poly_contain_pt", + "poly_contained", + "poly_left", + "poly_overabove", + "poly_overbelow", + "poly_overlap", + "poly_overleft", + "poly_overright", + "poly_right", + "poly_same", + "pt_contained_poly", + "st_3dintersects", + "st_contains", + "st_containsproperly", + "st_coveredby", + "st_covers", + "st_crosses", + "st_disjoint", + "st_equals", + "st_intersects", + "st_isvalid", + "st_orderingequals", + "st_overlaps", + "st_relatematch", + "st_touches", + "st_within", + "starts_with", + "ts_match_qv", + "ts_match_tq", + "ts_match_tt", + "ts_match_vq", + "tsq_mcontained", + "tsq_mcontains", + "xmlexists", + "xmlvalidate", + "xpath_exists" + ], + "typeRepresentations": { + "bit": "string", + "bool": "boolean", + "bpchar": "string", + "char": "string", + "date": "date", + "float4": "float32", + "float8": "float64", + "int2": "int16", + "int4": "int32", + "int8": "int64AsString", + "numeric": "bigDecimalAsString", + "text": "string", + "time": "time", + "timestamp": "timestamp", + "timestamptz": "timestamptz", + "timetz": "timetz", + "uuid": "uUID", + "varchar": "string" + } + }, + "mutationsVersion": null, + "mutationsPrefix": "" +} diff --git a/crates/query-engine/translation/tests/goldenfiles/select_composite_column_nested_field_count/request.json b/crates/query-engine/translation/tests/goldenfiles/select_composite_column_nested_field_count/request.json new file mode 100644 index 000000000..8b1d7c967 --- /dev/null +++ b/crates/query-engine/translation/tests/goldenfiles/select_composite_column_nested_field_count/request.json @@ -0,0 +1,16 @@ +{ + "$schema": "../../../../../../static/query.schema.json", + "collection": "persons", + "query": { + "aggregates": { + "different ages": { + "type": "column_count", + "column": "person", + "field_path": ["age"], + "distinct": true + } + } + }, + "arguments": {}, + "collection_relationships": {} +} diff --git a/crates/query-engine/translation/tests/goldenfiles/select_track_order_by_artist_id_and_album_title/request.json b/crates/query-engine/translation/tests/goldenfiles/select_track_order_by_artist_id_and_album_title/request.json index a43079eec..8c77a605c 100644 --- a/crates/query-engine/translation/tests/goldenfiles/select_track_order_by_artist_id_and_album_title/request.json +++ b/crates/query-engine/translation/tests/goldenfiles/select_track_order_by_artist_id_and_album_title/request.json @@ -61,7 +61,7 @@ "collection_relationships": { "TrackAlbum": { "column_mapping": { - "AlbumId": "AlbumId" + "AlbumId": ["AlbumId"] }, "relationship_type": "object", "target_collection": "Album", diff --git a/crates/query-engine/translation/tests/goldenfiles/select_where_album_id_equals_self_nested_object_relationship/request.json b/crates/query-engine/translation/tests/goldenfiles/select_where_album_id_equals_self_nested_object_relationship/request.json index d83b9cb89..2c389351a 100644 --- a/crates/query-engine/translation/tests/goldenfiles/select_where_album_id_equals_self_nested_object_relationship/request.json +++ b/crates/query-engine/translation/tests/goldenfiles/select_where_album_id_equals_self_nested_object_relationship/request.json @@ -61,88 +61,65 @@ }, "limit": 5, "predicate": { - "type": "binary_comparison_operator", - "column": { - "type": "column", - "name": "AlbumId", - "path": [ + "type": "exists", + "in_collection": { + "type": "related", + "arguments": {}, + "relationship": "TrackToAlbum" + }, + "predicate": { + "type": "and", + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { + "type": "column", + "name": "Title", + "path": [] + }, + "operator": "_eq", + "value": { + "type": "scalar", + "value": "The album title (1)" + } + }, { - "relationship": "TrackToAlbum", - "arguments": {}, - "predicate": { - "type": "and", - "expressions": [ + "type": "binary_comparison_operator", + "column": { + "type": "column", + "name": "AlbumId" + }, + "operator": "_gt", + "value": { + "type": "column", + "name": "ArtistId", + "path": [ { - "type": "binary_comparison_operator", - "column": { - "type": "column", - "name": "Title", - "path": [] - }, - "operator": "_eq", - "value": { - "type": "scalar", - "value": "The album title (1)" + "relationship": "AlbumToArtist", + "arguments": {}, + "predicate": { + "type": "and", + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { + "type": "column", + "name": "Name", + "path": [] + }, + "operator": "_eq", + "value": { + "type": "scalar", + "value": "The Artist name" + } + } + ] } } ] } } ] - }, - "operator": "_gt", - "value": { - "type": "column", - "column": { - "type": "column", - "name": "ArtistId", - "path": [ - { - "relationship": "TrackToAlbum", - "arguments": {}, - "predicate": { - "type": "and", - "expressions": [ - { - "type": "binary_comparison_operator", - "column": { - "type": "column", - "name": "Title", - "path": [] - }, - "operator": "_eq", - "value": { - "type": "scalar", - "value": "The album title (2)" - } - } - ] - } - }, - { - "relationship": "AlbumToArtist", - "arguments": {}, - "predicate": { - "type": "and", - "expressions": [ - { - "type": "binary_comparison_operator", - "column": { - "type": "column", - "name": "Name", - "path": [] - }, - "operator": "_eq", - "value": { - "type": "scalar", - "value": "The Artist name" - } - } - ] - } - } - ] - } } } }, @@ -150,7 +127,7 @@ "collection_relationships": { "TrackToAlbum": { "column_mapping": { - "AlbumId": "AlbumId" + "AlbumId": ["AlbumId"] }, "relationship_type": "object", "target_collection": "Album", @@ -158,7 +135,7 @@ }, "AlbumToArtist": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "object", "target_collection": "Artist", diff --git a/crates/query-engine/translation/tests/goldenfiles/select_where_array_relationship/request.json b/crates/query-engine/translation/tests/goldenfiles/select_where_array_relationship/request.json index 4b737e0ba..63dfcb334 100644 --- a/crates/query-engine/translation/tests/goldenfiles/select_where_array_relationship/request.json +++ b/crates/query-engine/translation/tests/goldenfiles/select_where_array_relationship/request.json @@ -36,25 +36,23 @@ } }, "predicate": { - "type": "binary_comparison_operator", - "column": { - "type": "column", - "name": "Title", - "path": [ - { - "relationship": "Artist_Albums", - "arguments": {}, - "predicate": { - "type": "and", - "expressions": [] - } - } - ] + "type": "exists", + "in_collection": { + "type": "related", + "relationship": "Artist_Albums", + "arguments": {} }, - "operator": "_like", - "value": { - "type": "scalar", - "value": "Supernatural" + "predicate": { + "type": "binary_comparison_operator", + "column": { + "type": "column", + "name": "Title" + }, + "operator": "_like", + "value": { + "type": "scalar", + "value": "Supernatural" + } } }, "order_by": { @@ -75,7 +73,7 @@ "Artist_Albums": { "arguments": {}, "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album" diff --git a/crates/query-engine/translation/tests/goldenfiles/select_where_related_exists/request.json b/crates/query-engine/translation/tests/goldenfiles/select_where_related_exists/request.json index 888192006..63587dd84 100644 --- a/crates/query-engine/translation/tests/goldenfiles/select_where_related_exists/request.json +++ b/crates/query-engine/translation/tests/goldenfiles/select_where_related_exists/request.json @@ -50,7 +50,7 @@ "artist_albums": { "arguments": {}, "column_mapping": { - "id": "artist_id" + "id": ["artist_id"] }, "relationship_type": "array", "target_collection": "album" diff --git a/crates/query-engine/translation/tests/goldenfiles/select_where_unrelated_exists/request.json b/crates/query-engine/translation/tests/goldenfiles/select_where_unrelated_exists/request.json index e1c2c67d4..bcfb43199 100644 --- a/crates/query-engine/translation/tests/goldenfiles/select_where_unrelated_exists/request.json +++ b/crates/query-engine/translation/tests/goldenfiles/select_where_unrelated_exists/request.json @@ -35,17 +35,15 @@ { "type": "binary_comparison_operator", "column": { - "type": "root_collection_column", - "name": "artist_id" + "type": "column", + "name": "id" }, "operator": "_eq", "value": { "type": "column", - "column": { - "type": "column", - "name": "id", - "path": [] - } + "name": "artist_id", + "path": [], + "scope": 1 } } ] diff --git a/crates/query-engine/translation/tests/goldenfiles/simple_array_relationship/request.json b/crates/query-engine/translation/tests/goldenfiles/simple_array_relationship/request.json index 862c3ce32..1aad35926 100644 --- a/crates/query-engine/translation/tests/goldenfiles/simple_array_relationship/request.json +++ b/crates/query-engine/translation/tests/goldenfiles/simple_array_relationship/request.json @@ -24,7 +24,7 @@ "collection_relationships": { "Albums": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album", diff --git a/crates/query-engine/translation/tests/goldenfiles/simple_object_relationship/request.json b/crates/query-engine/translation/tests/goldenfiles/simple_object_relationship/request.json index 3951f8930..42b6d8172 100644 --- a/crates/query-engine/translation/tests/goldenfiles/simple_object_relationship/request.json +++ b/crates/query-engine/translation/tests/goldenfiles/simple_object_relationship/request.json @@ -24,7 +24,7 @@ "collection_relationships": { "AlbumArtist": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "object", "target_collection": "Artist", diff --git a/crates/query-engine/translation/tests/goldenfiles/sorting_by_nested_relationship_column/request.json b/crates/query-engine/translation/tests/goldenfiles/sorting_by_nested_relationship_column/request.json index 3d654d5df..588bac076 100644 --- a/crates/query-engine/translation/tests/goldenfiles/sorting_by_nested_relationship_column/request.json +++ b/crates/query-engine/translation/tests/goldenfiles/sorting_by_nested_relationship_column/request.json @@ -37,7 +37,7 @@ "collection_relationships": { "AlbumArtist": { "column_mapping": { - "artist_id": "artist_id" + "artist_id": ["artist_id"] }, "relationship_type": "object", "target_collection": "artist", @@ -45,7 +45,7 @@ }, "TrackAlbum": { "column_mapping": { - "album_id": "album_id" + "album_id": ["album_id"] }, "relationship_type": "object", "target_collection": "album", diff --git a/crates/query-engine/translation/tests/goldenfiles/sorting_by_nested_relationship_column_with_predicate/request.json b/crates/query-engine/translation/tests/goldenfiles/sorting_by_nested_relationship_column_with_predicate/request.json index f73bbeeb7..6f61d99cf 100644 --- a/crates/query-engine/translation/tests/goldenfiles/sorting_by_nested_relationship_column_with_predicate/request.json +++ b/crates/query-engine/translation/tests/goldenfiles/sorting_by_nested_relationship_column_with_predicate/request.json @@ -55,7 +55,7 @@ "collection_relationships": { "AlbumArtist": { "column_mapping": { - "artist_id": "artist_id" + "artist_id": ["artist_id"] }, "relationship_type": "object", "target_collection": "artist", @@ -63,7 +63,7 @@ }, "TrackAlbum": { "column_mapping": { - "album_id": "album_id" + "album_id": ["album_id"] }, "relationship_type": "object", "target_collection": "album", diff --git a/crates/query-engine/translation/tests/goldenfiles/sorting_by_nested_relationship_count/request.json b/crates/query-engine/translation/tests/goldenfiles/sorting_by_nested_relationship_count/request.json index 06a0a0041..c6bfc529f 100644 --- a/crates/query-engine/translation/tests/goldenfiles/sorting_by_nested_relationship_count/request.json +++ b/crates/query-engine/translation/tests/goldenfiles/sorting_by_nested_relationship_count/request.json @@ -13,16 +13,19 @@ "elements": [ { "target": { - "type": "single_column_aggregate", - "column": "AlbumId", - "function": "count", + "type": "aggregate", "path": [ { "relationship": "ArtistAlbum", "arguments": {}, "predicate": null } - ] + ], + "aggregate": { + "type": "single_column", + "column": "AlbumId", + "function": "count" + } }, "order_direction": "desc" } @@ -34,7 +37,7 @@ "collection_relationships": { "ArtistAlbum": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album", diff --git a/crates/query-engine/translation/tests/goldenfiles/sorting_by_no_relationship_aggregate/request.json b/crates/query-engine/translation/tests/goldenfiles/sorting_by_no_relationship_aggregate/request.json index 1570c39a9..33c95a642 100644 --- a/crates/query-engine/translation/tests/goldenfiles/sorting_by_no_relationship_aggregate/request.json +++ b/crates/query-engine/translation/tests/goldenfiles/sorting_by_no_relationship_aggregate/request.json @@ -13,10 +13,13 @@ "elements": [ { "target": { - "type": "single_column_aggregate", - "column": "TopRadioChartPlacement", - "function": "impossible", - "path": [] + "type": "aggregate", + "path": [], + "aggregate": { + "type": "single_column", + "column": "TopRadioChartPlacement", + "function": "impossible" + } }, "order_direction": "desc" } diff --git a/crates/query-engine/translation/tests/goldenfiles/sorting_by_recursive_relationship_column/request.json b/crates/query-engine/translation/tests/goldenfiles/sorting_by_recursive_relationship_column/request.json index 7bd6c9733..d6a9b7180 100644 --- a/crates/query-engine/translation/tests/goldenfiles/sorting_by_recursive_relationship_column/request.json +++ b/crates/query-engine/translation/tests/goldenfiles/sorting_by_recursive_relationship_column/request.json @@ -37,7 +37,7 @@ "collection_relationships": { "CompanyCEO": { "column_mapping": { - "CEOId": "PersonId" + "CEOId": ["PersonId"] }, "relationship_type": "object", "target_collection": "Person", @@ -45,7 +45,7 @@ }, "PersonParent": { "column_mapping": { - "ParentId": "PersonId" + "ParentId": ["PersonId"] }, "relationship_type": "object", "target_collection": "Person", diff --git a/crates/query-engine/translation/tests/goldenfiles/sorting_by_relationship_column/request.json b/crates/query-engine/translation/tests/goldenfiles/sorting_by_relationship_column/request.json index 8d2712a92..a09fda8e8 100644 --- a/crates/query-engine/translation/tests/goldenfiles/sorting_by_relationship_column/request.json +++ b/crates/query-engine/translation/tests/goldenfiles/sorting_by_relationship_column/request.json @@ -34,7 +34,7 @@ "collection_relationships": { "AlbumArtist": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "object", "target_collection": "Artist", diff --git a/crates/query-engine/translation/tests/goldenfiles/sorting_by_relationship_column_with_true_predicate/request.json b/crates/query-engine/translation/tests/goldenfiles/sorting_by_relationship_column_with_true_predicate/request.json index b8f4b5e56..4c6b0dd13 100644 --- a/crates/query-engine/translation/tests/goldenfiles/sorting_by_relationship_column_with_true_predicate/request.json +++ b/crates/query-engine/translation/tests/goldenfiles/sorting_by_relationship_column_with_true_predicate/request.json @@ -37,7 +37,7 @@ "collection_relationships": { "AlbumArtist": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "object", "target_collection": "Artist", diff --git a/crates/query-engine/translation/tests/goldenfiles/sorting_by_relationship_count/request.json b/crates/query-engine/translation/tests/goldenfiles/sorting_by_relationship_count/request.json index 01d84bc3e..a273bc5b7 100644 --- a/crates/query-engine/translation/tests/goldenfiles/sorting_by_relationship_count/request.json +++ b/crates/query-engine/translation/tests/goldenfiles/sorting_by_relationship_count/request.json @@ -15,14 +15,17 @@ { "order_direction": "desc", "target": { - "type": "star_count_aggregate", + "type": "aggregate", "path": [ { "relationship": "ArtistAlbums", "arguments": {}, "predicate": null } - ] + ], + "aggregate": { + "type": "star_count" + } } } ] @@ -32,7 +35,7 @@ "collection_relationships": { "ArtistAlbums": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album", diff --git a/crates/query-engine/translation/tests/goldenfiles/sorting_by_relationship_count_with_predicate/request.json b/crates/query-engine/translation/tests/goldenfiles/sorting_by_relationship_count_with_predicate/request.json index 18dc787af..766bb1cd0 100644 --- a/crates/query-engine/translation/tests/goldenfiles/sorting_by_relationship_count_with_predicate/request.json +++ b/crates/query-engine/translation/tests/goldenfiles/sorting_by_relationship_count_with_predicate/request.json @@ -15,7 +15,7 @@ { "order_direction": "desc", "target": { - "type": "star_count_aggregate", + "type": "aggregate", "path": [ { "relationship": "ArtistAlbums", @@ -47,7 +47,10 @@ ] } } - ] + ], + "aggregate": { + "type": "star_count" + } } }, { @@ -65,7 +68,7 @@ "collection_relationships": { "ArtistAlbums": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album", @@ -73,7 +76,7 @@ }, "AlbumTracks": { "column_mapping": { - "AlbumId": "album_id" + "AlbumId": ["album_id"] }, "relationship_type": "array", "target_collection": "track", diff --git a/crates/query-engine/translation/tests/goldenfiles/very_nested_recursive_relationship/request.json b/crates/query-engine/translation/tests/goldenfiles/very_nested_recursive_relationship/request.json index 56ab79045..caaf2a1d2 100644 --- a/crates/query-engine/translation/tests/goldenfiles/very_nested_recursive_relationship/request.json +++ b/crates/query-engine/translation/tests/goldenfiles/very_nested_recursive_relationship/request.json @@ -56,7 +56,7 @@ "collection_relationships": { "ArtistAlbums": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album", @@ -64,7 +64,7 @@ }, "AlbumArtist": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "object", "target_collection": "Artist", diff --git a/crates/query-engine/translation/tests/snapshots/tests__aggregate_limit_offset_order_by.snap b/crates/query-engine/translation/tests/snapshots/tests__aggregate_limit_offset_order_by.snap index 1cb0b8135..517fb6bfb 100644 --- a/crates/query-engine/translation/tests/snapshots/tests__aggregate_limit_offset_order_by.snap +++ b/crates/query-engine/translation/tests/snapshots/tests__aggregate_limit_offset_order_by.snap @@ -23,7 +23,7 @@ FROM COUNT("%3_Invoice"."InvoiceId") AS "InvoiceId_count", min("%3_Invoice"."Total") AS "Total__min", max("%3_Invoice"."Total") AS "Total__max", - sum("%3_Invoice"."Total") AS "Total__sum", + coalesce(sum("%3_Invoice"."Total"), 0) AS "Total__sum", stddev("%3_Invoice"."Total") AS "Total__stddev", COUNT(*) AS "count_all" FROM diff --git a/crates/query-engine/translation/tests/snapshots/tests__it_select_where_unrelated_exists.snap b/crates/query-engine/translation/tests/snapshots/tests__it_select_where_unrelated_exists.snap index 03d725dc4..bc8324f3c 100644 --- a/crates/query-engine/translation/tests/snapshots/tests__it_select_where_unrelated_exists.snap +++ b/crates/query-engine/translation/tests/snapshots/tests__it_select_where_unrelated_exists.snap @@ -33,7 +33,7 @@ FROM ( "%1_artist"."Name" = cast($1 as "pg_catalog"."varchar") ) - AND ("%0_album"."ArtistId" = "%1_artist"."ArtistId") + AND ("%1_artist"."ArtistId" = "%0_album"."ArtistId") ) ) ) AS "%2_album" diff --git a/crates/query-engine/translation/tests/snapshots/tests__mutations__v2_insert_return_object_relationship.snap b/crates/query-engine/translation/tests/snapshots/tests__mutations__v2_insert_return_object_relationship.snap new file mode 100644 index 000000000..c7b0ce1b3 --- /dev/null +++ b/crates/query-engine/translation/tests/snapshots/tests__mutations__v2_insert_return_object_relationship.snap @@ -0,0 +1,99 @@ +--- +source: crates/query-engine/translation/tests/tests.rs +expression: result +--- +BEGIN +ISOLATION LEVEL READ COMMITTED READ WRITE; + +WITH "%0_generated_mutation" AS ( + INSERT INTO + "public"."Album"("AlbumId", "ArtistId", "Title") + VALUES + (348, 276, cast($1 as "pg_catalog"."varchar")) RETURNING *, + false AS "%check__constraint" +) +SELECT + ( + SELECT + json_build_object( + 'result', + row_to_json("%10_universe"), + 'type', + $2 + ) AS "universe" + FROM + ( + SELECT + * + FROM + ( + SELECT + coalesce(json_agg(row_to_json("%11_returning")), '[]') AS "returning" + FROM + ( + SELECT + "%2_Album"."Title" AS "Title", + "%3_RELATIONSHIP_Artist"."Artist" AS "Artist" + FROM + ( + SELECT + "%1_Album".* + FROM + "%0_generated_mutation" AS "%1_Album" + ) AS "%2_Album" + LEFT OUTER JOIN LATERAL ( + SELECT + row_to_json("%3_RELATIONSHIP_Artist") AS "Artist" + FROM + ( + SELECT + * + FROM + ( + SELECT + coalesce(json_agg(row_to_json("%6_rows")), '[]') AS "rows" + FROM + ( + SELECT + "%5_Artist"."Name" AS "Name" + FROM + ( + SELECT + "%4_Artist".* + FROM + "public"."Artist" AS "%4_Artist" + WHERE + ("%2_Album"."ArtistId" = "%4_Artist"."ArtistId") + ) AS "%5_Artist" + ) AS "%6_rows" + ) AS "%6_rows" + ) AS "%3_RELATIONSHIP_Artist" + ) AS "%3_RELATIONSHIP_Artist" ON ('true') + ) AS "%11_returning" + ) AS "%11_returning" + CROSS JOIN ( + SELECT + COUNT(*) AS "affected_rows" + FROM + ( + SELECT + "%8_Album".* + FROM + "%0_generated_mutation" AS "%8_Album" + ) AS "%9_Album" + ) AS "%12_aggregates" + ) AS "%10_universe" + ) AS "%results", + ( + SELECT + coalesce( + bool_and("%13_v2_insert_Album"."%check__constraint"), + true + ) AS "%check__constraint" + FROM + "%0_generated_mutation" AS "%13_v2_insert_Album" + ) AS "%check__constraint"; + +COMMIT; + +[[(1, String("Lake Mannion")), (2, String("procedure"))]] diff --git a/crates/query-engine/translation/tests/snapshots/tests__select_composite_column_nested_field_count.snap b/crates/query-engine/translation/tests/snapshots/tests__select_composite_column_nested_field_count.snap new file mode 100644 index 000000000..5802cf467 --- /dev/null +++ b/crates/query-engine/translation/tests/snapshots/tests__select_composite_column_nested_field_count.snap @@ -0,0 +1,30 @@ +--- +source: crates/query-engine/translation/tests/tests.rs +expression: result +--- +SELECT + coalesce(json_agg(row_to_json("%4_universe")), '[]') AS "universe" +FROM + ( + SELECT + * + FROM + ( + SELECT + coalesce(row_to_json("%6_aggregates"), '[]') AS "aggregates" + FROM + ( + SELECT + COUNT(DISTINCT ("%3_persons"."person")."age") AS "different ages" + FROM + ( + SELECT + "%2_persons".* + FROM + "public"."persons" AS "%2_persons" + ) AS "%3_persons" + ) AS "%6_aggregates" + ) AS "%6_aggregates" + ) AS "%4_universe"; + +{} diff --git a/crates/query-engine/translation/tests/snapshots/tests__select_where_album_id_equals_self_nested_object_relationship.snap b/crates/query-engine/translation/tests/snapshots/tests__select_where_album_id_equals_self_nested_object_relationship.snap index 5de034e60..88f54507b 100644 --- a/crates/query-engine/translation/tests/snapshots/tests__select_where_album_id_equals_self_nested_object_relationship.snap +++ b/crates/query-engine/translation/tests/snapshots/tests__select_where_album_id_equals_self_nested_object_relationship.snap @@ -3,7 +3,7 @@ source: crates/query-engine/translation/tests/tests.rs expression: result --- SELECT - coalesce(json_agg(row_to_json("%17_universe")), '[]') AS "universe" + coalesce(json_agg(row_to_json("%15_universe")), '[]') AS "universe" FROM ( SELECT @@ -11,13 +11,13 @@ FROM FROM ( SELECT - coalesce(json_agg(row_to_json("%18_rows")), '[]') AS "rows" + coalesce(json_agg(row_to_json("%16_rows")), '[]') AS "rows" FROM ( SELECT - "%6_Track"."Name" AS "track", - "%6_Track"."AlbumId" AS "AlbumId", - "%7_RELATIONSHIP_Album"."Album" AS "Album" + "%4_Track"."Name" AS "track", + "%4_Track"."AlbumId" AS "AlbumId", + "%5_RELATIONSHIP_Album"."Album" AS "Album" FROM ( SELECT @@ -27,76 +27,50 @@ FROM WHERE EXISTS ( SELECT - 1 + 1 AS "one" FROM - ( - SELECT - "%1_BOOLEXP_Album".* - FROM - ( - SELECT - * - FROM - "public"."Album" AS "%1_BOOLEXP_Album" - WHERE - ( - ( - "%1_BOOLEXP_Album"."Title" = cast($1 as "pg_catalog"."varchar") - ) - AND ( - "%0_Track"."AlbumId" = "%1_BOOLEXP_Album"."AlbumId" - ) - ) - ) AS "%1_BOOLEXP_Album" - ) AS "%2_BOOLEXP_Album" FULL + "public"."Album" AS "%1_Album" FULL OUTER JOIN LATERAL ( SELECT - "%4_BOOLEXP_Artist".* + "%2_BOOLEXP_Artist".* FROM ( SELECT * FROM - "public"."Album" AS "%3_BOOLEXP_Album" - WHERE - ( - ( - "%3_BOOLEXP_Album"."Title" = cast($2 as "pg_catalog"."varchar") - ) - AND ( - "%0_Track"."AlbumId" = "%3_BOOLEXP_Album"."AlbumId" - ) - ) - ) AS "%3_BOOLEXP_Album" - INNER JOIN LATERAL ( - SELECT - * - FROM - "public"."Artist" AS "%4_BOOLEXP_Artist" + "public"."Artist" AS "%2_BOOLEXP_Artist" WHERE ( ( - "%4_BOOLEXP_Artist"."Name" = cast($3 as "pg_catalog"."varchar") + "%2_BOOLEXP_Artist"."Name" = cast($1 as "pg_catalog"."varchar") ) AND ( - "%3_BOOLEXP_Album"."ArtistId" = "%4_BOOLEXP_Artist"."ArtistId" + "%1_Album"."ArtistId" = "%2_BOOLEXP_Artist"."ArtistId" ) ) - ) AS "%4_BOOLEXP_Artist" ON ('true') - ) AS "%5_BOOLEXP_Artist" ON ('true') + ) AS "%2_BOOLEXP_Artist" + ) AS "%3_BOOLEXP_Artist" ON ('true') WHERE ( - "%2_BOOLEXP_Album"."AlbumId" > "%5_BOOLEXP_Artist"."ArtistId" + ( + ( + "%1_Album"."Title" = cast($2 as "pg_catalog"."varchar") + ) + AND ( + "%1_Album"."AlbumId" > "%3_BOOLEXP_Artist"."ArtistId" + ) + ) + AND ("%0_Track"."AlbumId" = "%1_Album"."AlbumId") ) ) ORDER BY "%0_Track"."TrackId" ASC LIMIT 5 - ) AS "%6_Track" + ) AS "%4_Track" LEFT OUTER JOIN LATERAL ( SELECT - row_to_json("%7_RELATIONSHIP_Album") AS "Album" + row_to_json("%5_RELATIONSHIP_Album") AS "Album" FROM ( SELECT @@ -104,24 +78,24 @@ FROM FROM ( SELECT - coalesce(json_agg(row_to_json("%15_rows")), '[]') AS "rows" + coalesce(json_agg(row_to_json("%13_rows")), '[]') AS "rows" FROM ( SELECT - "%9_Album"."Title" AS "album", - "%10_RELATIONSHIP_Artist"."Artist" AS "Artist" + "%7_Album"."Title" AS "album", + "%8_RELATIONSHIP_Artist"."Artist" AS "Artist" FROM ( SELECT - "%8_Album".* + "%6_Album".* FROM - "public"."Album" AS "%8_Album" + "public"."Album" AS "%6_Album" WHERE - ("%6_Track"."AlbumId" = "%8_Album"."AlbumId") - ) AS "%9_Album" + ("%4_Track"."AlbumId" = "%6_Album"."AlbumId") + ) AS "%7_Album" LEFT OUTER JOIN LATERAL ( SELECT - row_to_json("%10_RELATIONSHIP_Artist") AS "Artist" + row_to_json("%8_RELATIONSHIP_Artist") AS "Artist" FROM ( SELECT @@ -129,43 +103,40 @@ FROM FROM ( SELECT - coalesce(json_agg(row_to_json("%13_rows")), '[]') AS "rows" + coalesce(json_agg(row_to_json("%11_rows")), '[]') AS "rows" FROM ( SELECT - "%12_Artist"."Name" AS "artist", - "%12_Artist"."ArtistId" AS "ArtistId" + "%10_Artist"."Name" AS "artist", + "%10_Artist"."ArtistId" AS "ArtistId" FROM ( SELECT - "%11_Artist".* + "%9_Artist".* FROM - "public"."Artist" AS "%11_Artist" + "public"."Artist" AS "%9_Artist" WHERE - ("%9_Album"."ArtistId" = "%11_Artist"."ArtistId") - ) AS "%12_Artist" - ) AS "%13_rows" - ) AS "%13_rows" - ) AS "%10_RELATIONSHIP_Artist" - ) AS "%10_RELATIONSHIP_Artist" ON ('true') - ) AS "%15_rows" - ) AS "%15_rows" - ) AS "%7_RELATIONSHIP_Album" - ) AS "%7_RELATIONSHIP_Album" ON ('true') + ("%7_Album"."ArtistId" = "%9_Artist"."ArtistId") + ) AS "%10_Artist" + ) AS "%11_rows" + ) AS "%11_rows" + ) AS "%8_RELATIONSHIP_Artist" + ) AS "%8_RELATIONSHIP_Artist" ON ('true') + ) AS "%13_rows" + ) AS "%13_rows" + ) AS "%5_RELATIONSHIP_Album" + ) AS "%5_RELATIONSHIP_Album" ON ('true') ORDER BY - "%6_Track"."TrackId" ASC - ) AS "%18_rows" - ) AS "%18_rows" - ) AS "%17_universe"; + "%4_Track"."TrackId" ASC + ) AS "%16_rows" + ) AS "%16_rows" + ) AS "%15_universe"; { 1: String( - "The album title (1)", + "The Artist name", ), 2: String( - "The album title (2)", - ), - 3: String( - "The Artist name", + "The album title (1)", ), } diff --git a/crates/query-engine/translation/tests/snapshots/tests__select_where_array_relationship.snap b/crates/query-engine/translation/tests/snapshots/tests__select_where_array_relationship.snap index 24c281f62..ebe757c4a 100644 --- a/crates/query-engine/translation/tests/snapshots/tests__select_where_array_relationship.snap +++ b/crates/query-engine/translation/tests/snapshots/tests__select_where_array_relationship.snap @@ -3,7 +3,7 @@ source: crates/query-engine/translation/tests/tests.rs expression: result --- SELECT - coalesce(json_agg(row_to_json("%9_universe")), '[]') AS "universe" + coalesce(json_agg(row_to_json("%8_universe")), '[]') AS "universe" FROM ( SELECT @@ -11,12 +11,12 @@ FROM FROM ( SELECT - coalesce(json_agg(row_to_json("%10_rows")), '[]') AS "rows" + coalesce(json_agg(row_to_json("%9_rows")), '[]') AS "rows" FROM ( SELECT - "%3_Artist"."Name" AS "title", - "%4_RELATIONSHIP_albums"."albums" AS "albums" + "%2_Artist"."Name" AS "title", + "%3_RELATIONSHIP_albums"."albums" AS "albums" FROM ( SELECT @@ -26,34 +26,23 @@ FROM WHERE EXISTS ( SELECT - 1 + 1 AS "one" FROM - ( - SELECT - "%1_BOOLEXP_Album".* - FROM - ( - SELECT - * - FROM - "public"."Album" AS "%1_BOOLEXP_Album" - WHERE - ( - "%0_Artist"."ArtistId" = "%1_BOOLEXP_Album"."ArtistId" - ) - ) AS "%1_BOOLEXP_Album" - ) AS "%2_BOOLEXP_Album" + "public"."Album" AS "%1_Album" WHERE ( - "%2_BOOLEXP_Album"."Title" LIKE cast($1 as "pg_catalog"."varchar") + ( + "%1_Album"."Title" LIKE cast($1 as "pg_catalog"."varchar") + ) + AND ("%0_Artist"."ArtistId" = "%1_Album"."ArtistId") ) ) ORDER BY "%0_Artist"."ArtistId" ASC - ) AS "%3_Artist" + ) AS "%2_Artist" LEFT OUTER JOIN LATERAL ( SELECT - row_to_json("%4_RELATIONSHIP_albums") AS "albums" + row_to_json("%3_RELATIONSHIP_albums") AS "albums" FROM ( SELECT @@ -61,33 +50,33 @@ FROM FROM ( SELECT - coalesce(json_agg(row_to_json("%7_rows")), '[]') AS "rows" + coalesce(json_agg(row_to_json("%6_rows")), '[]') AS "rows" FROM ( SELECT - "%6_Album"."Title" AS "title" + "%5_Album"."Title" AS "title" FROM ( SELECT - "%5_Album".* + "%4_Album".* FROM - "public"."Album" AS "%5_Album" + "public"."Album" AS "%4_Album" WHERE - ("%3_Artist"."ArtistId" = "%5_Album"."ArtistId") + ("%2_Artist"."ArtistId" = "%4_Album"."ArtistId") ORDER BY - "%5_Album"."AlbumId" ASC - ) AS "%6_Album" + "%4_Album"."AlbumId" ASC + ) AS "%5_Album" ORDER BY - "%6_Album"."AlbumId" ASC - ) AS "%7_rows" - ) AS "%7_rows" - ) AS "%4_RELATIONSHIP_albums" - ) AS "%4_RELATIONSHIP_albums" ON ('true') + "%5_Album"."AlbumId" ASC + ) AS "%6_rows" + ) AS "%6_rows" + ) AS "%3_RELATIONSHIP_albums" + ) AS "%3_RELATIONSHIP_albums" ON ('true') ORDER BY - "%3_Artist"."ArtistId" ASC - ) AS "%10_rows" - ) AS "%10_rows" - ) AS "%9_universe"; + "%2_Artist"."ArtistId" ASC + ) AS "%9_rows" + ) AS "%9_rows" + ) AS "%8_universe"; { 1: String( diff --git a/crates/query-engine/translation/tests/tests.rs b/crates/query-engine/translation/tests/tests.rs index 204730350..0e02b72b2 100644 --- a/crates/query-engine/translation/tests/tests.rs +++ b/crates/query-engine/translation/tests/tests.rs @@ -54,6 +54,14 @@ async fn select_composite_column_complex() { insta::assert_snapshot!(result); } +#[tokio::test] +async fn select_composite_column_nested_field_count() { + let result = common::test_translation("select_composite_column_nested_field_count") + .await + .unwrap(); + insta::assert_snapshot!(result); +} + #[tokio::test] async fn select_composite_variable_simple() { let result = common::test_translation("select_composite_variable_simple") @@ -439,4 +447,15 @@ mod mutations { .unwrap(); insta::assert_snapshot!(result); } + + #[tokio::test] + async fn v2_insert_return_object_relationship() { + let result = common::test_mutation_translation( + IsolationLevel::default(), + "v2_insert_return_object_relationship", + ) + .await + .unwrap(); + insta::assert_snapshot!(result); + } } diff --git a/crates/tests/databases-tests/src/citus/snapshots/databases_tests__citus__schema_tests__schema_test__get_schema.snap b/crates/tests/databases-tests/src/citus/snapshots/databases_tests__citus__schema_tests__schema_test__get_schema.snap index 0ba1d78b5..792dbe602 100644 --- a/crates/tests/databases-tests/src/citus/snapshots/databases_tests__citus__schema_tests__schema_test__get_schema.snap +++ b/crates/tests/databases-tests/src/citus/snapshots/databases_tests__citus__schema_tests__schema_test__get_schema.snap @@ -1,6 +1,7 @@ --- source: crates/tests/databases-tests/src/citus/schema_tests.rs expression: result +snapshot_kind: text --- { "scalar_types": { @@ -10,22 +11,10 @@ expression: result }, "aggregate_functions": { "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "text" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "text" - } - } + "type": "min" } }, "comparison_operators": { @@ -148,6 +137,7 @@ expression: result }, "aggregate_functions": { "bool_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -157,6 +147,7 @@ expression: result } }, "bool_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -166,6 +157,7 @@ expression: result } }, "every": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -231,22 +223,10 @@ expression: result }, "aggregate_functions": { "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "card_suit" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "card_suit" - } - } + "type": "min" } }, "comparison_operators": { @@ -299,22 +279,10 @@ expression: result }, "aggregate_functions": { "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "text" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "text" - } - } + "type": "min" } }, "comparison_operators": { @@ -437,22 +405,10 @@ expression: result }, "aggregate_functions": { "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "date" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "date" - } - } + "type": "min" } }, "comparison_operators": { @@ -505,6 +461,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -514,6 +471,7 @@ expression: result } }, "bit_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -523,6 +481,7 @@ expression: result } }, "bit_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -532,6 +491,7 @@ expression: result } }, "bit_xor": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -541,24 +501,13 @@ expression: result } }, "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int4" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int4" - } - } + "type": "min" }, "stddev": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -568,6 +517,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -577,6 +527,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -586,15 +537,11 @@ expression: result } }, "sum": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int8" - } - } + "type": "sum", + "result_type": "int8" }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -604,6 +551,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -613,6 +561,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -672,33 +621,17 @@ expression: result }, "aggregate_functions": { "avg": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float8" - } - } + "type": "average", + "result_type": "float8" }, "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float4" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float4" - } - } + "type": "min" }, "stddev": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -708,6 +641,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -717,6 +651,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -726,6 +661,7 @@ expression: result } }, "sum": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -735,6 +671,7 @@ expression: result } }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -744,6 +681,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -753,6 +691,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -812,33 +751,17 @@ expression: result }, "aggregate_functions": { "avg": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float8" - } - } + "type": "average", + "result_type": "float8" }, "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float8" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float8" - } - } + "type": "min" }, "stddev": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -848,6 +771,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -857,6 +781,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -866,15 +791,11 @@ expression: result } }, "sum": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float8" - } - } + "type": "sum", + "result_type": "float8" }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -884,6 +805,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -893,6 +815,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -952,6 +875,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -961,6 +885,7 @@ expression: result } }, "bit_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -970,6 +895,7 @@ expression: result } }, "bit_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -979,6 +905,7 @@ expression: result } }, "bit_xor": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -988,24 +915,13 @@ expression: result } }, "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int2" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int2" - } - } + "type": "min" }, "stddev": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1015,6 +931,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1024,6 +941,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1033,15 +951,11 @@ expression: result } }, "sum": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int8" - } - } + "type": "sum", + "result_type": "int8" }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1051,6 +965,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1060,6 +975,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1119,6 +1035,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1128,6 +1045,7 @@ expression: result } }, "bit_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1137,6 +1055,7 @@ expression: result } }, "bit_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1146,6 +1065,7 @@ expression: result } }, "bit_xor": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1155,24 +1075,13 @@ expression: result } }, "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int4" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int4" - } - } + "type": "min" }, "stddev": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1182,6 +1091,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1191,6 +1101,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1200,15 +1111,11 @@ expression: result } }, "sum": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int8" - } - } + "type": "sum", + "result_type": "int8" }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1218,6 +1125,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1227,6 +1135,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1286,6 +1195,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1295,6 +1205,7 @@ expression: result } }, "bit_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1304,6 +1215,7 @@ expression: result } }, "bit_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1313,6 +1225,7 @@ expression: result } }, "bit_xor": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1322,24 +1235,13 @@ expression: result } }, "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int8" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int8" - } - } + "type": "min" }, "stddev": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1349,6 +1251,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1358,6 +1261,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1367,6 +1271,7 @@ expression: result } }, "sum": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1376,6 +1281,7 @@ expression: result } }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1385,6 +1291,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1394,6 +1301,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1448,8 +1356,12 @@ expression: result } }, "interval": { + "representation": { + "type": "json" + }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1459,24 +1371,13 @@ expression: result } }, "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "interval" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "interval" - } - } + "type": "min" }, "sum": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1536,6 +1437,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1545,24 +1447,13 @@ expression: result } }, "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "numeric" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "numeric" - } - } + "type": "min" }, "stddev": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1572,6 +1463,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1581,6 +1473,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1590,6 +1483,7 @@ expression: result } }, "sum": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1599,6 +1493,7 @@ expression: result } }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1608,6 +1503,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1617,6 +1513,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1676,22 +1573,10 @@ expression: result }, "aggregate_functions": { "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "text" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "text" - } - } + "type": "min" } }, "comparison_operators": { @@ -1814,6 +1699,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1823,24 +1709,13 @@ expression: result } }, "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "time" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "time" - } - } + "type": "min" }, "sum": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1900,22 +1775,10 @@ expression: result }, "aggregate_functions": { "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "timestamp" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "timestamp" - } - } + "type": "min" } }, "comparison_operators": { @@ -1968,22 +1831,10 @@ expression: result }, "aggregate_functions": { "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "timestamptz" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "timestamptz" - } - } + "type": "min" } }, "comparison_operators": { @@ -2036,22 +1887,10 @@ expression: result }, "aggregate_functions": { "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "timetz" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "timetz" - } - } + "type": "min" } }, "comparison_operators": { @@ -2153,22 +1992,10 @@ expression: result }, "aggregate_functions": { "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "text" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "text" - } - } + "type": "min" } }, "comparison_operators": { @@ -2311,6 +2138,16 @@ expression: result "name": "varchar" } } + }, + "foreign_keys": { + "FK_AlbumArtistId": { + "column_mapping": { + "ArtistId": [ + "ArtistId" + ] + }, + "foreign_collection": "Artist" + } } }, "Artist": { @@ -2333,7 +2170,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "Customer": { "description": "The record of all customers", @@ -2446,6 +2284,16 @@ expression: result } } } + }, + "foreign_keys": { + "FK_CustomerSupportRepId": { + "column_mapping": { + "SupportRepId": [ + "EmployeeId" + ] + }, + "foreign_collection": "Employee" + } } }, "Employee": { @@ -2576,6 +2424,16 @@ expression: result } } } + }, + "foreign_keys": { + "FK_EmployeeReportsTo": { + "column_mapping": { + "ReportsTo": [ + "EmployeeId" + ] + }, + "foreign_collection": "Employee" + } } }, "Genre": { @@ -2595,7 +2453,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "Invoice": { "fields": { @@ -2668,6 +2527,16 @@ expression: result "name": "numeric" } } + }, + "foreign_keys": { + "FK_InvoiceCustomerId": { + "column_mapping": { + "CustomerId": [ + "CustomerId" + ] + }, + "foreign_collection": "Customer" + } } }, "InvoiceLine": { @@ -2702,6 +2571,24 @@ expression: result "name": "numeric" } } + }, + "foreign_keys": { + "FK_InvoiceLineInvoiceId": { + "column_mapping": { + "InvoiceId": [ + "InvoiceId" + ] + }, + "foreign_collection": "Invoice" + }, + "FK_InvoiceLineTrackId": { + "column_mapping": { + "TrackId": [ + "TrackId" + ] + }, + "foreign_collection": "Track" + } } }, "MediaType": { @@ -2721,7 +2608,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "Playlist": { "fields": { @@ -2740,7 +2628,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "PlaylistTrack": { "fields": { @@ -2756,6 +2645,24 @@ expression: result "name": "int4" } } + }, + "foreign_keys": { + "FK_PlaylistTrackPlaylistId": { + "column_mapping": { + "PlaylistId": [ + "PlaylistId" + ] + }, + "foreign_collection": "Playlist" + }, + "FK_PlaylistTrackTrackId": { + "column_mapping": { + "TrackId": [ + "TrackId" + ] + }, + "foreign_collection": "Track" + } } }, "Track": { @@ -2826,6 +2733,32 @@ expression: result "name": "numeric" } } + }, + "foreign_keys": { + "FK_TrackAlbumId": { + "column_mapping": { + "AlbumId": [ + "AlbumId" + ] + }, + "foreign_collection": "Album" + }, + "FK_TrackGenreId": { + "column_mapping": { + "GenreId": [ + "GenreId" + ] + }, + "foreign_collection": "Genre" + }, + "FK_TrackMediaTypeId": { + "column_mapping": { + "MediaTypeId": [ + "MediaTypeId" + ] + }, + "foreign_collection": "MediaType" + } } }, "address_identity_function": { @@ -2840,7 +2773,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "album_by_title": { "fields": { @@ -2871,7 +2805,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "array_reverse": { "description": "A native query used to test support for arrays as inputs", @@ -2892,7 +2827,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "array_series": { "description": "A native query used to test support for arrays", @@ -2921,7 +2857,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "artist": { "fields": { @@ -2943,7 +2880,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "artist_below_id": { "fields": { @@ -2965,7 +2903,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "chara": { "fields": { @@ -2987,7 +2926,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "characters": { "fields": { @@ -3015,7 +2955,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "committee": { "fields": { @@ -3043,7 +2984,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "count_elements": { "description": "A native query used to test support array-valued variables", @@ -3057,7 +2999,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "deck_of_cards": { "fields": { @@ -3073,7 +3016,8 @@ expression: result "name": "card_suit" } } - } + }, + "foreign_keys": {} }, "delete_playlist_track": { "fields": { @@ -3095,7 +3039,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_playlist_track_response": { "description": "Responses from the 'delete_playlist_track' procedure", @@ -3117,7 +3062,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "discoverable_types": { "fields": { @@ -3130,7 +3076,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "discoverable_types_root_occurrence": { "fields": { @@ -3143,7 +3090,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "even_numbers": { "fields": { @@ -3153,7 +3101,8 @@ expression: result "name": "even_number" } } - } + }, + "foreign_keys": {} }, "group_leader": { "fields": { @@ -3184,7 +3133,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_album": { "fields": { @@ -3215,7 +3165,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_album_response": { "description": "Responses from the 'insert_album' procedure", @@ -3237,7 +3188,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_artist": { "fields": { @@ -3259,7 +3211,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_artist_response": { "description": "Responses from the 'insert_artist' procedure", @@ -3281,7 +3234,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "make_person": { "description": "A native query used to test support for composite types", @@ -3295,7 +3249,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "organization": { "fields": { @@ -3323,7 +3278,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "organization_identity_function": { "description": "A native query used to test support for composite types", @@ -3337,7 +3293,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "person": { "fields": { @@ -3359,7 +3316,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "person_address": { "description": "The address of a person, obviously", @@ -3384,7 +3342,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "person_name": { "description": "The name of a person, obviously", @@ -3409,7 +3368,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "phone_numbers": { "fields": { @@ -3419,7 +3379,8 @@ expression: result "name": "Phone" } } - } + }, + "foreign_keys": {} }, "summarize_organizations": { "description": "A native query used to test support array-valued variables", @@ -3433,7 +3394,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Album_by_AlbumId_response": { "description": "Responses from the 'v1_delete_Album_by_AlbumId' procedure", @@ -3455,7 +3417,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Artist_by_ArtistId_response": { "description": "Responses from the 'v1_delete_Artist_by_ArtistId' procedure", @@ -3477,7 +3440,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Customer_by_CustomerId_response": { "description": "Responses from the 'v1_delete_Customer_by_CustomerId' procedure", @@ -3499,7 +3463,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Employee_by_EmployeeId_response": { "description": "Responses from the 'v1_delete_Employee_by_EmployeeId' procedure", @@ -3521,7 +3486,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Genre_by_GenreId_response": { "description": "Responses from the 'v1_delete_Genre_by_GenreId' procedure", @@ -3543,7 +3509,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_InvoiceLine_by_InvoiceLineId_response": { "description": "Responses from the 'v1_delete_InvoiceLine_by_InvoiceLineId' procedure", @@ -3565,7 +3532,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Invoice_by_InvoiceId_response": { "description": "Responses from the 'v1_delete_Invoice_by_InvoiceId' procedure", @@ -3587,7 +3555,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_MediaType_by_MediaTypeId_response": { "description": "Responses from the 'v1_delete_MediaType_by_MediaTypeId' procedure", @@ -3609,7 +3578,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Playlist_by_PlaylistId_response": { "description": "Responses from the 'v1_delete_Playlist_by_PlaylistId' procedure", @@ -3631,7 +3601,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Track_by_TrackId_response": { "description": "Responses from the 'v1_delete_Track_by_TrackId' procedure", @@ -3653,7 +3624,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Album_object": { "fields": { @@ -3678,7 +3650,8 @@ expression: result "name": "varchar" } } - } + }, + "foreign_keys": {} }, "v1_insert_Album_response": { "description": "Responses from the 'v1_insert_Album' procedure", @@ -3700,7 +3673,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Artist_object": { "fields": { @@ -3721,7 +3695,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Artist_response": { "description": "Responses from the 'v1_insert_Artist' procedure", @@ -3743,7 +3718,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Customer_object": { "fields": { @@ -3855,7 +3831,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Customer_response": { "description": "Responses from the 'v1_insert_Customer' procedure", @@ -3877,7 +3854,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Employee_object": { "fields": { @@ -4007,7 +3985,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Employee_response": { "description": "Responses from the 'v1_insert_Employee' procedure", @@ -4029,7 +4008,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Genre_object": { "fields": { @@ -4048,7 +4028,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Genre_response": { "description": "Responses from the 'v1_insert_Genre' procedure", @@ -4070,7 +4051,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_InvoiceLine_object": { "fields": { @@ -4104,7 +4086,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "v1_insert_InvoiceLine_response": { "description": "Responses from the 'v1_insert_InvoiceLine' procedure", @@ -4126,7 +4109,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Invoice_object": { "fields": { @@ -4199,7 +4183,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "v1_insert_Invoice_response": { "description": "Responses from the 'v1_insert_Invoice' procedure", @@ -4221,7 +4206,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_MediaType_object": { "fields": { @@ -4240,7 +4226,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_MediaType_response": { "description": "Responses from the 'v1_insert_MediaType' procedure", @@ -4262,7 +4249,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_PlaylistTrack_object": { "fields": { @@ -4278,7 +4266,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "v1_insert_PlaylistTrack_response": { "description": "Responses from the 'v1_insert_PlaylistTrack' procedure", @@ -4300,7 +4289,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Playlist_object": { "fields": { @@ -4319,7 +4309,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "v1_insert_Playlist_response": { "description": "Responses from the 'v1_insert_Playlist' procedure", @@ -4341,7 +4332,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Track_object": { "fields": { @@ -4411,7 +4403,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "v1_insert_Track_response": { "description": "Responses from the 'v1_insert_Track' procedure", @@ -4433,7 +4426,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_deck_of_cards_object": { "fields": { @@ -4449,7 +4443,8 @@ expression: result "name": "card_suit" } } - } + }, + "foreign_keys": {} }, "v1_insert_deck_of_cards_response": { "description": "Responses from the 'v1_insert_deck_of_cards' procedure", @@ -4471,7 +4466,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_discoverable_types_root_occurrence_object": { "fields": { @@ -4484,7 +4480,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_discoverable_types_root_occurrence_response": { "description": "Responses from the 'v1_insert_discoverable_types_root_occurrence' procedure", @@ -4506,7 +4503,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_even_numbers_object": { "fields": { @@ -4516,7 +4514,8 @@ expression: result "name": "even_number" } } - } + }, + "foreign_keys": {} }, "v1_insert_even_numbers_response": { "description": "Responses from the 'v1_insert_even_numbers' procedure", @@ -4538,7 +4537,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_group_leader_object": { "fields": { @@ -4569,7 +4569,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_group_leader_response": { "description": "Responses from the 'v1_insert_group_leader' procedure", @@ -4591,7 +4592,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_phone_numbers_object": { "fields": { @@ -4601,7 +4603,8 @@ expression: result "name": "Phone" } } - } + }, + "foreign_keys": {} }, "v1_insert_phone_numbers_response": { "description": "Responses from the 'v1_insert_phone_numbers' procedure", @@ -4623,7 +4626,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "value_types": { "fields": { @@ -4771,7 +4775,8 @@ expression: result } } } - } + }, + "foreign_keys": {} } }, "collections": [ @@ -4786,14 +4791,6 @@ expression: result "AlbumId" ] } - }, - "foreign_keys": { - "FK_AlbumArtistId": { - "column_mapping": { - "ArtistId": "ArtistId" - }, - "foreign_collection": "Artist" - } } }, { @@ -4807,8 +4804,7 @@ expression: result "ArtistId" ] } - }, - "foreign_keys": {} + } }, { "name": "Customer", @@ -4821,14 +4817,6 @@ expression: result "CustomerId" ] } - }, - "foreign_keys": { - "FK_CustomerSupportRepId": { - "column_mapping": { - "SupportRepId": "EmployeeId" - }, - "foreign_collection": "Employee" - } } }, { @@ -4841,14 +4829,6 @@ expression: result "EmployeeId" ] } - }, - "foreign_keys": { - "FK_EmployeeReportsTo": { - "column_mapping": { - "ReportsTo": "EmployeeId" - }, - "foreign_collection": "Employee" - } } }, { @@ -4861,8 +4841,7 @@ expression: result "GenreId" ] } - }, - "foreign_keys": {} + } }, { "name": "Invoice", @@ -4874,14 +4853,6 @@ expression: result "InvoiceId" ] } - }, - "foreign_keys": { - "FK_InvoiceCustomerId": { - "column_mapping": { - "CustomerId": "CustomerId" - }, - "foreign_collection": "Customer" - } } }, { @@ -4894,20 +4865,6 @@ expression: result "InvoiceLineId" ] } - }, - "foreign_keys": { - "FK_InvoiceLineInvoiceId": { - "column_mapping": { - "InvoiceId": "InvoiceId" - }, - "foreign_collection": "Invoice" - }, - "FK_InvoiceLineTrackId": { - "column_mapping": { - "TrackId": "TrackId" - }, - "foreign_collection": "Track" - } } }, { @@ -4920,8 +4877,7 @@ expression: result "MediaTypeId" ] } - }, - "foreign_keys": {} + } }, { "name": "Playlist", @@ -4933,8 +4889,7 @@ expression: result "PlaylistId" ] } - }, - "foreign_keys": {} + } }, { "name": "PlaylistTrack", @@ -4947,20 +4902,6 @@ expression: result "TrackId" ] } - }, - "foreign_keys": { - "FK_PlaylistTrackPlaylistId": { - "column_mapping": { - "PlaylistId": "PlaylistId" - }, - "foreign_collection": "Playlist" - }, - "FK_PlaylistTrackTrackId": { - "column_mapping": { - "TrackId": "TrackId" - }, - "foreign_collection": "Track" - } } }, { @@ -4973,62 +4914,37 @@ expression: result "TrackId" ] } - }, - "foreign_keys": { - "FK_TrackAlbumId": { - "column_mapping": { - "AlbumId": "AlbumId" - }, - "foreign_collection": "Album" - }, - "FK_TrackGenreId": { - "column_mapping": { - "GenreId": "GenreId" - }, - "foreign_collection": "Genre" - }, - "FK_TrackMediaTypeId": { - "column_mapping": { - "MediaTypeId": "MediaTypeId" - }, - "foreign_collection": "MediaType" - } } }, { "name": "deck_of_cards", "arguments": {}, "type": "deck_of_cards", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "discoverable_types_root_occurrence", "arguments": {}, "type": "discoverable_types_root_occurrence", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "even_numbers", "arguments": {}, "type": "even_numbers", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "group_leader", "arguments": {}, "type": "group_leader", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "phone_numbers", "arguments": {}, "type": "phone_numbers", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "address_identity_function", @@ -5045,8 +4961,7 @@ expression: result } }, "type": "address_identity_function", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "album_by_title", @@ -5071,8 +4986,7 @@ expression: result } }, "type": "album_by_title", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "array_reverse", @@ -5093,8 +5007,7 @@ expression: result } }, "type": "array_reverse", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "array_series", @@ -5120,15 +5033,13 @@ expression: result } }, "type": "array_series", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "artist", "arguments": {}, "type": "artist", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "artist_below_id", @@ -5144,8 +5055,7 @@ expression: result } }, "type": "artist_below_id", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "count_elements", @@ -5168,8 +5078,7 @@ expression: result } }, "type": "count_elements", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "make_person", @@ -5195,8 +5104,7 @@ expression: result } }, "type": "make_person", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "organization_identity_function", @@ -5213,8 +5121,7 @@ expression: result } }, "type": "organization_identity_function", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "summarize_organizations", @@ -5237,8 +5144,7 @@ expression: result } }, "type": "summarize_organizations", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "value_types", @@ -5389,8 +5295,7 @@ expression: result } }, "type": "value_types", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} } ], "functions": [], @@ -5895,5 +5800,12 @@ expression: result "name": "v1_insert_phone_numbers_response" } } - ] + ], + "capabilities": { + "query": { + "aggregates": { + "count_scalar_type": "int8" + } + } + } } diff --git a/crates/tests/databases-tests/src/cockroach/snapshots/databases_tests__cockroach__schema_tests__schema_test__get_schema.snap b/crates/tests/databases-tests/src/cockroach/snapshots/databases_tests__cockroach__schema_tests__schema_test__get_schema.snap index 015eb5939..d20aa5c39 100644 --- a/crates/tests/databases-tests/src/cockroach/snapshots/databases_tests__cockroach__schema_tests__schema_test__get_schema.snap +++ b/crates/tests/databases-tests/src/cockroach/snapshots/databases_tests__cockroach__schema_tests__schema_test__get_schema.snap @@ -1,6 +1,7 @@ --- source: crates/tests/databases-tests/src/cockroach/schema_tests.rs expression: result +snapshot_kind: text --- { "scalar_types": { @@ -10,6 +11,7 @@ expression: result }, "aggregate_functions": { "bool_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -19,6 +21,7 @@ expression: result } }, "bool_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -28,6 +31,7 @@ expression: result } }, "every": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -93,22 +97,10 @@ expression: result }, "aggregate_functions": { "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "card_suit" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "card_suit" - } - } + "type": "min" } }, "comparison_operators": { @@ -161,6 +153,7 @@ expression: result }, "aggregate_functions": { "concat_agg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -367,15 +360,11 @@ expression: result }, "aggregate_functions": { "avg": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float8" - } - } + "type": "average", + "result_type": "float8" }, "sqrdiff": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -385,6 +374,7 @@ expression: result } }, "stddev": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -394,6 +384,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -403,6 +394,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -412,15 +404,11 @@ expression: result } }, "sum": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float8" - } - } + "type": "sum", + "result_type": "float8" }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -430,6 +418,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -439,6 +428,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -498,15 +488,11 @@ expression: result }, "aggregate_functions": { "avg": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float8" - } - } + "type": "average", + "result_type": "float8" }, "sqrdiff": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -516,6 +502,7 @@ expression: result } }, "stddev": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -525,6 +512,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -534,6 +522,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -543,15 +532,11 @@ expression: result } }, "sum": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float8" - } - } + "type": "sum", + "result_type": "float8" }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -561,6 +546,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -570,6 +556,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -629,15 +616,11 @@ expression: result }, "aggregate_functions": { "avg": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float8" - } - } + "type": "average", + "result_type": "float8" }, "bit_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -647,6 +630,7 @@ expression: result } }, "bit_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -656,6 +640,7 @@ expression: result } }, "sqrdiff": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -665,6 +650,7 @@ expression: result } }, "stddev": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -674,6 +660,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -683,6 +670,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -692,15 +680,11 @@ expression: result } }, "sum": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float8" - } - } + "type": "sum", + "result_type": "float8" }, "sum_int": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -710,6 +694,7 @@ expression: result } }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -719,6 +704,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -728,6 +714,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -737,6 +724,7 @@ expression: result } }, "xor_agg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -796,15 +784,11 @@ expression: result }, "aggregate_functions": { "avg": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float8" - } - } + "type": "average", + "result_type": "float8" }, "bit_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -814,6 +798,7 @@ expression: result } }, "bit_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -823,6 +808,7 @@ expression: result } }, "sqrdiff": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -832,6 +818,7 @@ expression: result } }, "stddev": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -841,6 +828,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -850,6 +838,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -859,15 +848,11 @@ expression: result } }, "sum": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float8" - } - } + "type": "sum", + "result_type": "float8" }, "sum_int": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -877,6 +862,7 @@ expression: result } }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -886,6 +872,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -895,6 +882,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -904,6 +892,7 @@ expression: result } }, "xor_agg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -963,6 +952,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -972,6 +962,7 @@ expression: result } }, "bit_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -981,6 +972,7 @@ expression: result } }, "bit_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -990,6 +982,7 @@ expression: result } }, "sqrdiff": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -999,6 +992,7 @@ expression: result } }, "stddev": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1008,6 +1002,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1017,6 +1012,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1026,6 +1022,7 @@ expression: result } }, "sum": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1035,6 +1032,7 @@ expression: result } }, "sum_int": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1044,6 +1042,7 @@ expression: result } }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1053,6 +1052,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1062,6 +1062,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1071,6 +1072,7 @@ expression: result } }, "xor_agg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1125,8 +1127,12 @@ expression: result } }, "interval": { + "representation": { + "type": "json" + }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1136,6 +1142,7 @@ expression: result } }, "sum": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1195,6 +1202,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1204,6 +1212,7 @@ expression: result } }, "sqrdiff": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1213,6 +1222,7 @@ expression: result } }, "stddev": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1222,6 +1232,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1231,6 +1242,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1240,6 +1252,7 @@ expression: result } }, "sum": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1249,6 +1262,7 @@ expression: result } }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1258,6 +1272,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1267,6 +1282,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1326,6 +1342,7 @@ expression: result }, "aggregate_functions": { "concat_agg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1483,6 +1500,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1492,6 +1510,7 @@ expression: result } }, "sum": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1747,6 +1766,7 @@ expression: result }, "aggregate_functions": { "concat_agg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1924,6 +1944,16 @@ expression: result "name": "varchar" } } + }, + "foreign_keys": { + "FK_AlbumArtistId": { + "column_mapping": { + "ArtistId": [ + "ArtistId" + ] + }, + "foreign_collection": "Artist" + } } }, "Artist": { @@ -1946,7 +1976,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "Customer": { "description": "The record of all customers", @@ -2059,6 +2090,16 @@ expression: result } } } + }, + "foreign_keys": { + "FK_CustomerSupportRepId": { + "column_mapping": { + "SupportRepId": [ + "EmployeeId" + ] + }, + "foreign_collection": "Employee" + } } }, "Employee": { @@ -2189,6 +2230,16 @@ expression: result } } } + }, + "foreign_keys": { + "FK_EmployeeReportsTo": { + "column_mapping": { + "ReportsTo": [ + "EmployeeId" + ] + }, + "foreign_collection": "Employee" + } } }, "Genre": { @@ -2208,7 +2259,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "Invoice": { "fields": { @@ -2281,6 +2333,16 @@ expression: result "name": "numeric" } } + }, + "foreign_keys": { + "FK_InvoiceCustomerId": { + "column_mapping": { + "CustomerId": [ + "CustomerId" + ] + }, + "foreign_collection": "Customer" + } } }, "InvoiceLine": { @@ -2315,6 +2377,24 @@ expression: result "name": "numeric" } } + }, + "foreign_keys": { + "FK_InvoiceLineInvoiceId": { + "column_mapping": { + "InvoiceId": [ + "InvoiceId" + ] + }, + "foreign_collection": "Invoice" + }, + "FK_InvoiceLineTrackId": { + "column_mapping": { + "TrackId": [ + "TrackId" + ] + }, + "foreign_collection": "Track" + } } }, "MediaType": { @@ -2334,7 +2414,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "Playlist": { "fields": { @@ -2353,7 +2434,8 @@ expression: result "name": "int8" } } - } + }, + "foreign_keys": {} }, "PlaylistTrack": { "fields": { @@ -2369,6 +2451,24 @@ expression: result "name": "int8" } } + }, + "foreign_keys": { + "FK_PlaylistTrackPlaylistId": { + "column_mapping": { + "PlaylistId": [ + "PlaylistId" + ] + }, + "foreign_collection": "Playlist" + }, + "FK_PlaylistTrackTrackId": { + "column_mapping": { + "TrackId": [ + "TrackId" + ] + }, + "foreign_collection": "Track" + } } }, "Track": { @@ -2439,6 +2539,32 @@ expression: result "name": "numeric" } } + }, + "foreign_keys": { + "FK_TrackAlbumId": { + "column_mapping": { + "AlbumId": [ + "AlbumId" + ] + }, + "foreign_collection": "Album" + }, + "FK_TrackGenreId": { + "column_mapping": { + "GenreId": [ + "GenreId" + ] + }, + "foreign_collection": "Genre" + }, + "FK_TrackMediaTypeId": { + "column_mapping": { + "MediaTypeId": [ + "MediaTypeId" + ] + }, + "foreign_collection": "MediaType" + } } }, "address_identity_function": { @@ -2453,7 +2579,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "album_by_title": { "fields": { @@ -2484,7 +2611,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "array_reverse": { "description": "A native query used to test support for arrays as inputs", @@ -2505,7 +2633,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "array_series": { "description": "A native query used to test support for arrays", @@ -2534,7 +2663,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "artist": { "fields": { @@ -2556,7 +2686,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "artist_below_id": { "fields": { @@ -2578,7 +2709,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "count_elements": { "description": "A native query used to test support array-valued variables", @@ -2592,7 +2724,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "deck_of_cards": { "fields": { @@ -2614,7 +2747,8 @@ expression: result "name": "card_suit" } } - } + }, + "foreign_keys": {} }, "delete_playlist_track": { "fields": { @@ -2636,7 +2770,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_playlist_track_response": { "description": "Responses from the 'delete_playlist_track' procedure", @@ -2658,7 +2793,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "discoverable_types_root_occurrence": { "fields": { @@ -2677,7 +2813,8 @@ expression: result "name": "int8" } } - } + }, + "foreign_keys": {} }, "insert_album": { "fields": { @@ -2708,7 +2845,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_album_response": { "description": "Responses from the 'insert_album' procedure", @@ -2730,7 +2868,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_artist": { "fields": { @@ -2752,7 +2891,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_artist_response": { "description": "Responses from the 'insert_artist' procedure", @@ -2774,7 +2914,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "pg_extension_spatial_ref_sys": { "description": "Shows all defined Spatial Reference Identifiers (SRIDs). Matches PostGIS' spatial_ref_sys table.", @@ -2824,7 +2965,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Album_by_AlbumId_response": { "description": "Responses from the 'v1_delete_Album_by_AlbumId' procedure", @@ -2846,7 +2988,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Artist_by_ArtistId_response": { "description": "Responses from the 'v1_delete_Artist_by_ArtistId' procedure", @@ -2868,7 +3011,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Customer_by_CustomerId_response": { "description": "Responses from the 'v1_delete_Customer_by_CustomerId' procedure", @@ -2890,7 +3034,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Employee_by_EmployeeId_response": { "description": "Responses from the 'v1_delete_Employee_by_EmployeeId' procedure", @@ -2912,7 +3057,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Genre_by_GenreId_response": { "description": "Responses from the 'v1_delete_Genre_by_GenreId' procedure", @@ -2934,7 +3080,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_InvoiceLine_by_InvoiceLineId_response": { "description": "Responses from the 'v1_delete_InvoiceLine_by_InvoiceLineId' procedure", @@ -2956,7 +3103,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Invoice_by_InvoiceId_response": { "description": "Responses from the 'v1_delete_Invoice_by_InvoiceId' procedure", @@ -2978,7 +3126,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_MediaType_by_MediaTypeId_response": { "description": "Responses from the 'v1_delete_MediaType_by_MediaTypeId' procedure", @@ -3000,7 +3149,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Playlist_by_PlaylistId_response": { "description": "Responses from the 'v1_delete_Playlist_by_PlaylistId' procedure", @@ -3022,7 +3172,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Track_by_TrackId_response": { "description": "Responses from the 'v1_delete_Track_by_TrackId' procedure", @@ -3044,7 +3195,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_deck_of_cards_by_rowid_response": { "description": "Responses from the 'v1_delete_deck_of_cards_by_rowid' procedure", @@ -3066,7 +3218,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_discoverable_types_root_occurrence_by_rowid_response": { "description": "Responses from the 'v1_delete_discoverable_types_root_occurrence_by_rowid' procedure", @@ -3088,7 +3241,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Album_object": { "fields": { @@ -3113,7 +3267,8 @@ expression: result "name": "varchar" } } - } + }, + "foreign_keys": {} }, "v1_insert_Album_response": { "description": "Responses from the 'v1_insert_Album' procedure", @@ -3135,7 +3290,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Artist_object": { "fields": { @@ -3156,7 +3312,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Artist_response": { "description": "Responses from the 'v1_insert_Artist' procedure", @@ -3178,7 +3335,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Customer_object": { "fields": { @@ -3290,7 +3448,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Customer_response": { "description": "Responses from the 'v1_insert_Customer' procedure", @@ -3312,7 +3471,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Employee_object": { "fields": { @@ -3442,7 +3602,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Employee_response": { "description": "Responses from the 'v1_insert_Employee' procedure", @@ -3464,7 +3625,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Genre_object": { "fields": { @@ -3483,7 +3645,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Genre_response": { "description": "Responses from the 'v1_insert_Genre' procedure", @@ -3505,7 +3668,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_InvoiceLine_object": { "fields": { @@ -3539,7 +3703,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "v1_insert_InvoiceLine_response": { "description": "Responses from the 'v1_insert_InvoiceLine' procedure", @@ -3561,7 +3726,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Invoice_object": { "fields": { @@ -3634,7 +3800,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "v1_insert_Invoice_response": { "description": "Responses from the 'v1_insert_Invoice' procedure", @@ -3656,7 +3823,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_MediaType_object": { "fields": { @@ -3675,7 +3843,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_MediaType_response": { "description": "Responses from the 'v1_insert_MediaType' procedure", @@ -3697,7 +3866,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_PlaylistTrack_object": { "fields": { @@ -3713,7 +3883,8 @@ expression: result "name": "int8" } } - } + }, + "foreign_keys": {} }, "v1_insert_PlaylistTrack_response": { "description": "Responses from the 'v1_insert_PlaylistTrack' procedure", @@ -3735,7 +3906,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Playlist_object": { "fields": { @@ -3754,7 +3926,8 @@ expression: result "name": "int8" } } - } + }, + "foreign_keys": {} }, "v1_insert_Playlist_response": { "description": "Responses from the 'v1_insert_Playlist' procedure", @@ -3776,7 +3949,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Track_object": { "fields": { @@ -3846,7 +4020,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "v1_insert_Track_response": { "description": "Responses from the 'v1_insert_Track' procedure", @@ -3868,7 +4043,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_deck_of_cards_object": { "fields": { @@ -3893,7 +4069,8 @@ expression: result "name": "card_suit" } } - } + }, + "foreign_keys": {} }, "v1_insert_deck_of_cards_response": { "description": "Responses from the 'v1_insert_deck_of_cards' procedure", @@ -3915,7 +4092,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_discoverable_types_root_occurrence_object": { "fields": { @@ -3937,7 +4115,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_discoverable_types_root_occurrence_response": { "description": "Responses from the 'v1_insert_discoverable_types_root_occurrence' procedure", @@ -3959,7 +4138,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_pg_extension_spatial_ref_sys_object": { "fields": { @@ -4008,7 +4188,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_pg_extension_spatial_ref_sys_response": { "description": "Responses from the 'v1_insert_pg_extension_spatial_ref_sys' procedure", @@ -4030,7 +4211,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "value_types": { "fields": { @@ -4178,7 +4360,8 @@ expression: result } } } - } + }, + "foreign_keys": {} } }, "collections": [ @@ -4193,14 +4376,6 @@ expression: result "AlbumId" ] } - }, - "foreign_keys": { - "FK_AlbumArtistId": { - "column_mapping": { - "ArtistId": "ArtistId" - }, - "foreign_collection": "Artist" - } } }, { @@ -4214,8 +4389,7 @@ expression: result "ArtistId" ] } - }, - "foreign_keys": {} + } }, { "name": "Customer", @@ -4228,14 +4402,6 @@ expression: result "CustomerId" ] } - }, - "foreign_keys": { - "FK_CustomerSupportRepId": { - "column_mapping": { - "SupportRepId": "EmployeeId" - }, - "foreign_collection": "Employee" - } } }, { @@ -4248,14 +4414,6 @@ expression: result "EmployeeId" ] } - }, - "foreign_keys": { - "FK_EmployeeReportsTo": { - "column_mapping": { - "ReportsTo": "EmployeeId" - }, - "foreign_collection": "Employee" - } } }, { @@ -4268,8 +4426,7 @@ expression: result "GenreId" ] } - }, - "foreign_keys": {} + } }, { "name": "Invoice", @@ -4281,14 +4438,6 @@ expression: result "InvoiceId" ] } - }, - "foreign_keys": { - "FK_InvoiceCustomerId": { - "column_mapping": { - "CustomerId": "CustomerId" - }, - "foreign_collection": "Customer" - } } }, { @@ -4301,20 +4450,6 @@ expression: result "InvoiceLineId" ] } - }, - "foreign_keys": { - "FK_InvoiceLineInvoiceId": { - "column_mapping": { - "InvoiceId": "InvoiceId" - }, - "foreign_collection": "Invoice" - }, - "FK_InvoiceLineTrackId": { - "column_mapping": { - "TrackId": "TrackId" - }, - "foreign_collection": "Track" - } } }, { @@ -4327,8 +4462,7 @@ expression: result "MediaTypeId" ] } - }, - "foreign_keys": {} + } }, { "name": "Playlist", @@ -4340,8 +4474,7 @@ expression: result "PlaylistId" ] } - }, - "foreign_keys": {} + } }, { "name": "PlaylistTrack", @@ -4354,20 +4487,6 @@ expression: result "TrackId" ] } - }, - "foreign_keys": { - "FK_PlaylistTrackPlaylistId": { - "column_mapping": { - "PlaylistId": "PlaylistId" - }, - "foreign_collection": "Playlist" - }, - "FK_PlaylistTrackTrackId": { - "column_mapping": { - "TrackId": "TrackId" - }, - "foreign_collection": "Track" - } } }, { @@ -4380,26 +4499,6 @@ expression: result "TrackId" ] } - }, - "foreign_keys": { - "FK_TrackAlbumId": { - "column_mapping": { - "AlbumId": "AlbumId" - }, - "foreign_collection": "Album" - }, - "FK_TrackGenreId": { - "column_mapping": { - "GenreId": "GenreId" - }, - "foreign_collection": "Genre" - }, - "FK_TrackMediaTypeId": { - "column_mapping": { - "MediaTypeId": "MediaTypeId" - }, - "foreign_collection": "MediaType" - } } }, { @@ -4412,8 +4511,7 @@ expression: result "rowid" ] } - }, - "foreign_keys": {} + } }, { "name": "discoverable_types_root_occurrence", @@ -4425,16 +4523,14 @@ expression: result "rowid" ] } - }, - "foreign_keys": {} + } }, { "name": "pg_extension_spatial_ref_sys", "description": "Shows all defined Spatial Reference Identifiers (SRIDs). Matches PostGIS' spatial_ref_sys table.", "arguments": {}, "type": "pg_extension_spatial_ref_sys", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "address_identity_function", @@ -4451,8 +4547,7 @@ expression: result } }, "type": "address_identity_function", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "album_by_title", @@ -4477,8 +4572,7 @@ expression: result } }, "type": "album_by_title", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "array_reverse", @@ -4499,8 +4593,7 @@ expression: result } }, "type": "array_reverse", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "array_series", @@ -4526,15 +4619,13 @@ expression: result } }, "type": "array_series", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "artist", "arguments": {}, "type": "artist", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "artist_below_id", @@ -4550,8 +4641,7 @@ expression: result } }, "type": "artist_below_id", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "count_elements", @@ -4574,8 +4664,7 @@ expression: result } }, "type": "count_elements", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "value_types", @@ -4726,8 +4815,7 @@ expression: result } }, "type": "value_types", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} } ], "functions": [], @@ -5232,5 +5320,12 @@ expression: result "name": "v1_insert_pg_extension_spatial_ref_sys_response" } } - ] + ], + "capabilities": { + "query": { + "aggregates": { + "count_scalar_type": "int8" + } + } + } } diff --git a/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__cli_version3_tests__postgres_current_only_configure_initial_configuration_is_unchanged.snap b/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__cli_version3_tests__postgres_current_only_configure_initial_configuration_is_unchanged.snap index d60b0d35b..bf61df47e 100644 --- a/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__cli_version3_tests__postgres_current_only_configure_initial_configuration_is_unchanged.snap +++ b/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__cli_version3_tests__postgres_current_only_configure_initial_configuration_is_unchanged.snap @@ -1611,13 +1611,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "Phone", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "Phone", "isInfix": true }, @@ -1647,13 +1647,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "Phone", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "Phone", "isInfix": true }, @@ -1739,13 +1739,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "bool", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "bool", "isInfix": true }, @@ -1757,13 +1757,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "bool", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "bool", "isInfix": true }, @@ -1783,13 +1783,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "card_suit", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "card_suit", "isInfix": true }, @@ -1801,13 +1801,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "card_suit", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "card_suit", "isInfix": true }, @@ -1827,13 +1827,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "cidr", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "cidr", "isInfix": true }, @@ -1845,13 +1845,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "cidr", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "cidr", "isInfix": true }, @@ -1895,13 +1895,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "date", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "date", "isInfix": true }, @@ -1913,13 +1913,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "date", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "date", "isInfix": true }, @@ -1939,13 +1939,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "even_number", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "even_number", "isInfix": true }, @@ -1957,13 +1957,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "even_number", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "even_number", "isInfix": true }, @@ -1983,13 +1983,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "float8", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "float8", "isInfix": true }, @@ -2001,13 +2001,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "float8", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "float8", "isInfix": true }, @@ -2027,13 +2027,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "int2", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "int2", "isInfix": true }, @@ -2045,13 +2045,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "int2", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "int2", "isInfix": true }, @@ -2071,13 +2071,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "int4", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "int4", "isInfix": true }, @@ -2089,13 +2089,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "int4", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "int4", "isInfix": true }, @@ -2115,13 +2115,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "int8", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "int8", "isInfix": true }, @@ -2133,13 +2133,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "int8", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "int8", "isInfix": true }, @@ -2159,13 +2159,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "numeric", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "numeric", "isInfix": true }, @@ -2177,13 +2177,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "numeric", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "numeric", "isInfix": true }, @@ -2203,13 +2203,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "text", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "text", "isInfix": true }, @@ -2239,13 +2239,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "text", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "text", "isInfix": true }, @@ -2331,13 +2331,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "timestamp", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "timestamp", "isInfix": true }, @@ -2349,13 +2349,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "timestamp", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "timestamp", "isInfix": true }, @@ -2375,13 +2375,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "varchar", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "varchar", "isInfix": true }, @@ -2411,13 +2411,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "varchar", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "varchar", "isInfix": true }, @@ -2554,22 +2554,22 @@ expression: default_configuration { "operatorName": "<=", "exposedName": "_lte", - "operatorKind": "custom" + "operatorKind": "lessThanOrEqual" }, { "operatorName": ">", "exposedName": "_gt", - "operatorKind": "custom" + "operatorKind": "greaterThan" }, { "operatorName": ">=", "exposedName": "_gte", - "operatorKind": "custom" + "operatorKind": "greaterThanOrEqual" }, { "operatorName": "<", "exposedName": "_lt", - "operatorKind": "custom" + "operatorKind": "lessThan" }, { "operatorName": "<>", diff --git a/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__cli_version4_tests__postgres_current_only_configure_initial_configuration_is_unchanged.snap b/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__cli_version4_tests__postgres_current_only_configure_initial_configuration_is_unchanged.snap index e77782c79..d79a7c3fd 100644 --- a/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__cli_version4_tests__postgres_current_only_configure_initial_configuration_is_unchanged.snap +++ b/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__cli_version4_tests__postgres_current_only_configure_initial_configuration_is_unchanged.snap @@ -1333,13 +1333,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "Phone", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "Phone", "isInfix": true }, @@ -1369,13 +1369,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "Phone", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "Phone", "isInfix": true }, @@ -1478,13 +1478,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "bool", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "bool", "isInfix": true }, @@ -1496,13 +1496,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "bool", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "bool", "isInfix": true }, @@ -1536,13 +1536,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "card_suit", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "card_suit", "isInfix": true }, @@ -1554,13 +1554,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "card_suit", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "card_suit", "isInfix": true }, @@ -1601,13 +1601,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "cidr", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "cidr", "isInfix": true }, @@ -1619,13 +1619,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "cidr", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "cidr", "isInfix": true }, @@ -1683,13 +1683,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "date", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "date", "isInfix": true }, @@ -1701,13 +1701,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "date", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "date", "isInfix": true }, @@ -1774,13 +1774,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "even_number", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "even_number", "isInfix": true }, @@ -1792,13 +1792,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "even_number", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "even_number", "isInfix": true }, @@ -1856,13 +1856,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "float8", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "float8", "isInfix": true }, @@ -1874,13 +1874,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "float8", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "float8", "isInfix": true }, @@ -1914,13 +1914,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "inet", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "inet", "isInfix": true }, @@ -1932,13 +1932,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "inet", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "inet", "isInfix": true }, @@ -2029,13 +2029,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "int2", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "int2", "isInfix": true }, @@ -2047,13 +2047,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "int2", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "int2", "isInfix": true }, @@ -2120,13 +2120,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "int4", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "int4", "isInfix": true }, @@ -2138,13 +2138,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "int4", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "int4", "isInfix": true }, @@ -2211,13 +2211,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "int8", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "int8", "isInfix": true }, @@ -2229,13 +2229,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "int8", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "int8", "isInfix": true }, @@ -2293,13 +2293,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "numeric", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "numeric", "isInfix": true }, @@ -2311,13 +2311,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "numeric", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "numeric", "isInfix": true }, @@ -2351,13 +2351,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "text", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "text", "isInfix": true }, @@ -2387,13 +2387,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "text", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "text", "isInfix": true }, @@ -2493,13 +2493,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "timestamp", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "timestamp", "isInfix": true }, @@ -2511,13 +2511,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "timestamp", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "timestamp", "isInfix": true }, @@ -2551,13 +2551,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "varchar", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "varchar", "isInfix": true }, @@ -2587,13 +2587,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "varchar", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "varchar", "isInfix": true }, @@ -2878,22 +2878,22 @@ expression: default_configuration { "operatorName": "<=", "exposedName": "_lte", - "operatorKind": "custom" + "operatorKind": "lessThanOrEqual" }, { "operatorName": ">", "exposedName": "_gt", - "operatorKind": "custom" + "operatorKind": "greaterThan" }, { "operatorName": ">=", "exposedName": "_gte", - "operatorKind": "custom" + "operatorKind": "greaterThanOrEqual" }, { "operatorName": "<", "exposedName": "_lt", - "operatorKind": "custom" + "operatorKind": "lessThan" }, { "operatorName": "<>", diff --git a/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__cli_version5_tests__postgres_current_only_configure_initial_configuration_is_unchanged.snap b/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__cli_version5_tests__postgres_current_only_configure_initial_configuration_is_unchanged.snap index 3f4cc498d..f907a45a6 100644 --- a/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__cli_version5_tests__postgres_current_only_configure_initial_configuration_is_unchanged.snap +++ b/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__cli_version5_tests__postgres_current_only_configure_initial_configuration_is_unchanged.snap @@ -1334,13 +1334,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "Phone", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "Phone", "isInfix": true }, @@ -1370,13 +1370,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "Phone", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "Phone", "isInfix": true }, @@ -1479,13 +1479,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "bool", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "bool", "isInfix": true }, @@ -1497,13 +1497,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "bool", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "bool", "isInfix": true }, @@ -1537,13 +1537,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "card_suit", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "card_suit", "isInfix": true }, @@ -1555,13 +1555,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "card_suit", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "card_suit", "isInfix": true }, @@ -1602,13 +1602,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "cidr", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "cidr", "isInfix": true }, @@ -1620,13 +1620,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "cidr", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "cidr", "isInfix": true }, @@ -1696,13 +1696,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "date", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "date", "isInfix": true }, @@ -1714,13 +1714,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "date", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "date", "isInfix": true }, @@ -1787,13 +1787,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "even_number", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "even_number", "isInfix": true }, @@ -1805,13 +1805,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "even_number", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "even_number", "isInfix": true }, @@ -1869,13 +1869,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "float8", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "float8", "isInfix": true }, @@ -1887,13 +1887,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "float8", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "float8", "isInfix": true }, @@ -1927,13 +1927,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "inet", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "inet", "isInfix": true }, @@ -1945,13 +1945,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "inet", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "inet", "isInfix": true }, @@ -2054,13 +2054,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "int2", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "int2", "isInfix": true }, @@ -2072,13 +2072,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "int2", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "int2", "isInfix": true }, @@ -2145,13 +2145,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "int4", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "int4", "isInfix": true }, @@ -2163,13 +2163,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "int4", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "int4", "isInfix": true }, @@ -2236,13 +2236,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "int8", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "int8", "isInfix": true }, @@ -2254,13 +2254,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "int8", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "int8", "isInfix": true }, @@ -2318,13 +2318,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "numeric", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "numeric", "isInfix": true }, @@ -2336,13 +2336,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "numeric", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "numeric", "isInfix": true }, @@ -2376,13 +2376,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "text", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "text", "isInfix": true }, @@ -2412,13 +2412,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "text", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "text", "isInfix": true }, @@ -2518,13 +2518,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "timestamp", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "timestamp", "isInfix": true }, @@ -2536,13 +2536,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "timestamp", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "timestamp", "isInfix": true }, @@ -2576,13 +2576,13 @@ expression: default_configuration }, "_gt": { "operatorName": ">", - "operatorKind": "custom", + "operatorKind": "greaterThan", "argumentType": "varchar", "isInfix": true }, "_gte": { "operatorName": ">=", - "operatorKind": "custom", + "operatorKind": "greaterThanOrEqual", "argumentType": "varchar", "isInfix": true }, @@ -2612,13 +2612,13 @@ expression: default_configuration }, "_lt": { "operatorName": "<", - "operatorKind": "custom", + "operatorKind": "lessThan", "argumentType": "varchar", "isInfix": true }, "_lte": { "operatorName": "<=", - "operatorKind": "custom", + "operatorKind": "lessThanOrEqual", "argumentType": "varchar", "isInfix": true }, @@ -2907,22 +2907,22 @@ expression: default_configuration { "operatorName": "<=", "exposedName": "_lte", - "operatorKind": "custom" + "operatorKind": "lessThanOrEqual" }, { "operatorName": ">", "exposedName": "_gt", - "operatorKind": "custom" + "operatorKind": "greaterThan" }, { "operatorName": ">=", "exposedName": "_gte", - "operatorKind": "custom" + "operatorKind": "greaterThanOrEqual" }, { "operatorName": "<", "exposedName": "_lt", - "operatorKind": "custom" + "operatorKind": "lessThan" }, { "operatorName": "<>", diff --git a/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__explain_tests__mutation__delete_invoice_line.snap b/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__explain_tests__mutation__delete_invoice_line.snap index d2faa9cb4..313677b45 100644 --- a/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__explain_tests__mutation__delete_invoice_line.snap +++ b/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__explain_tests__mutation__delete_invoice_line.snap @@ -10,25 +10,16 @@ EXPLAIN WITH "%0_generated_mutation" AS ( ("%1_InvoiceLine"."InvoiceLineId" = 90) AND EXISTS ( SELECT - 1 + 1 AS "one" FROM - ( - SELECT - "%2_BOOLEXP_Track".* - FROM - ( - SELECT - * - FROM - "public"."Track" AS "%2_BOOLEXP_Track" - WHERE - ( - "%1_InvoiceLine"."TrackId" = "%2_BOOLEXP_Track"."TrackId" - ) - ) AS "%2_BOOLEXP_Track" - ) AS "%3_BOOLEXP_Track" + "public"."Track" AS "%2_Track" WHERE - ("%3_BOOLEXP_Track"."TrackId" = 512) + ( + ("%2_Track"."TrackId" = 512) + AND ( + "%1_InvoiceLine"."TrackId" = "%2_Track"."TrackId" + ) + ) ) ) RETURNING *, true AS "%check__constraint" @@ -36,7 +27,7 @@ EXPLAIN WITH "%0_generated_mutation" AS ( SELECT ( SELECT - json_build_object('result', row_to_json("%8_universe"), 'type', $1) AS "universe" + json_build_object('result', row_to_json("%7_universe"), 'type', $1) AS "universe" FROM ( SELECT @@ -44,42 +35,42 @@ SELECT FROM ( SELECT - coalesce(json_agg(row_to_json("%9_returning")), '[]') AS "returning" + coalesce(json_agg(row_to_json("%8_returning")), '[]') AS "returning" FROM ( SELECT - "%5_InvoiceLine"."InvoiceLineId" AS "invoice_line_id", - "%5_InvoiceLine"."Quantity" AS "quantity" + "%4_InvoiceLine"."InvoiceLineId" AS "invoice_line_id", + "%4_InvoiceLine"."Quantity" AS "quantity" FROM ( SELECT - "%4_InvoiceLine".* + "%3_InvoiceLine".* FROM - "%0_generated_mutation" AS "%4_InvoiceLine" - ) AS "%5_InvoiceLine" - ) AS "%9_returning" - ) AS "%9_returning" + "%0_generated_mutation" AS "%3_InvoiceLine" + ) AS "%4_InvoiceLine" + ) AS "%8_returning" + ) AS "%8_returning" CROSS JOIN ( SELECT COUNT(*) AS "affected_rows" FROM ( SELECT - "%6_InvoiceLine".* + "%5_InvoiceLine".* FROM - "%0_generated_mutation" AS "%6_InvoiceLine" - ) AS "%7_InvoiceLine" - ) AS "%10_aggregates" - ) AS "%8_universe" + "%0_generated_mutation" AS "%5_InvoiceLine" + ) AS "%6_InvoiceLine" + ) AS "%9_aggregates" + ) AS "%7_universe" ) AS "%results", ( SELECT coalesce( bool_and( - "%11_delete_InvoiceLine_by_InvoiceLineId"."%check__constraint" + "%10_delete_InvoiceLine_by_InvoiceLineId"."%check__constraint" ), true ) AS "%check__constraint" FROM - "%0_generated_mutation" AS "%11_delete_InvoiceLine_by_InvoiceLineId" + "%0_generated_mutation" AS "%10_delete_InvoiceLine_by_InvoiceLineId" ) AS "%check__constraint" diff --git a/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__explain_tests__query__duplicate_filter_results.snap b/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__explain_tests__query__duplicate_filter_results.snap index c65564fa9..3c57a9565 100644 --- a/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__explain_tests__query__duplicate_filter_results.snap +++ b/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__explain_tests__query__duplicate_filter_results.snap @@ -4,7 +4,7 @@ expression: result.details.query --- EXPLAIN SELECT - coalesce(json_agg(row_to_json("%4_universe")), '[]') AS "universe" + coalesce(json_agg(row_to_json("%3_universe")), '[]') AS "universe" FROM ( SELECT @@ -12,11 +12,11 @@ FROM FROM ( SELECT - coalesce(json_agg(row_to_json("%5_rows")), '[]') AS "rows" + coalesce(json_agg(row_to_json("%4_rows")), '[]') AS "rows" FROM ( SELECT - "%3_Artist"."Name" AS "Name" + "%2_Artist"."Name" AS "Name" FROM ( SELECT @@ -26,35 +26,24 @@ FROM WHERE EXISTS ( SELECT - 1 + 1 AS "one" FROM - ( - SELECT - "%1_BOOLEXP_Album".* - FROM - ( - SELECT - * - FROM - "public"."Album" AS "%1_BOOLEXP_Album" - WHERE - ( - "%0_Artist"."ArtistId" = "%1_BOOLEXP_Album"."ArtistId" - ) - ) AS "%1_BOOLEXP_Album" - ) AS "%2_BOOLEXP_Album" + "public"."Album" AS "%1_Album" WHERE ( - "%2_BOOLEXP_Album"."Title" ~~ cast($1 as "pg_catalog"."varchar") + ( + "%1_Album"."Title" ~~ cast($1 as "pg_catalog"."varchar") + ) + AND ("%0_Artist"."ArtistId" = "%1_Album"."ArtistId") ) ) ORDER BY "%0_Artist"."ArtistId" ASC LIMIT 5 - ) AS "%3_Artist" + ) AS "%2_Artist" ORDER BY - "%3_Artist"."ArtistId" ASC - ) AS "%5_rows" - ) AS "%5_rows" - ) AS "%4_universe" + "%2_Artist"."ArtistId" ASC + ) AS "%4_rows" + ) AS "%4_rows" + ) AS "%3_universe" diff --git a/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__explain_tests__query__duplicate_filter_results_nested.snap b/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__explain_tests__query__duplicate_filter_results_nested.snap index f10bcb0b6..23779f1c8 100644 --- a/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__explain_tests__query__duplicate_filter_results_nested.snap +++ b/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__explain_tests__query__duplicate_filter_results_nested.snap @@ -4,7 +4,7 @@ expression: result.details.query --- EXPLAIN SELECT - coalesce(json_agg(row_to_json("%7_universe")), '[]') AS "universe" + coalesce(json_agg(row_to_json("%5_universe")), '[]') AS "universe" FROM ( SELECT @@ -12,11 +12,11 @@ FROM FROM ( SELECT - coalesce(json_agg(row_to_json("%8_rows")), '[]') AS "rows" + coalesce(json_agg(row_to_json("%6_rows")), '[]') AS "rows" FROM ( SELECT - "%6_Artist"."Name" AS "Name" + "%4_Artist"."Name" AS "Name" FROM ( SELECT @@ -24,67 +24,51 @@ FROM FROM "public"."Artist" AS "%0_Artist" WHERE - EXISTS ( - SELECT - 1 - FROM - ( - SELECT - "%2_BOOLEXP_Track".* - FROM - ( - SELECT - * - FROM - "public"."Album" AS "%1_BOOLEXP_Album" - WHERE - ( - "%0_Artist"."ArtistId" = "%1_BOOLEXP_Album"."ArtistId" - ) - ) AS "%1_BOOLEXP_Album" - INNER JOIN LATERAL ( - SELECT - * - FROM - "public"."Track" AS "%2_BOOLEXP_Track" - WHERE - ( - "%1_BOOLEXP_Album"."AlbumId" = "%2_BOOLEXP_Track"."AlbumId" - ) - ) AS "%2_BOOLEXP_Track" ON ('true') - ) AS "%3_BOOLEXP_Track" FULL - OUTER JOIN LATERAL ( - SELECT - "%4_BOOLEXP_Album".* - FROM - ( + ( + EXISTS ( + SELECT + 1 AS "one" + FROM + "public"."Album" AS "%1_Album" + WHERE + ( + EXISTS ( SELECT - * + 1 AS "one" FROM - "public"."Album" AS "%4_BOOLEXP_Album" + "public"."Track" AS "%2_Track" WHERE ( - "%0_Artist"."ArtistId" = "%4_BOOLEXP_Album"."ArtistId" + ( + "%2_Track"."Name" ~~ cast($1 as "pg_catalog"."varchar") + ) + AND ("%1_Album"."AlbumId" = "%2_Track"."AlbumId") ) - ) AS "%4_BOOLEXP_Album" - ) AS "%5_BOOLEXP_Album" ON ('true') - WHERE - ( - ( - "%3_BOOLEXP_Track"."Name" ~~ cast($1 as "pg_catalog"."varchar") + ) + AND ("%0_Artist"."ArtistId" = "%1_Album"."ArtistId") ) - OR ( - "%5_BOOLEXP_Album"."Title" ~~ cast($2 as "pg_catalog"."varchar") + ) + OR EXISTS ( + SELECT + 1 AS "one" + FROM + "public"."Album" AS "%3_Album" + WHERE + ( + ( + "%3_Album"."Title" ~~ cast($2 as "pg_catalog"."varchar") + ) + AND ("%0_Artist"."ArtistId" = "%3_Album"."ArtistId") ) - ) + ) ) ORDER BY "%0_Artist"."ArtistId" ASC LIMIT 5 - ) AS "%6_Artist" + ) AS "%4_Artist" ORDER BY - "%6_Artist"."ArtistId" ASC - ) AS "%8_rows" - ) AS "%8_rows" - ) AS "%7_universe" + "%4_Artist"."ArtistId" ASC + ) AS "%6_rows" + ) AS "%6_rows" + ) AS "%5_universe" diff --git a/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__schema_tests__schema_test__get_schema.snap b/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__schema_tests__schema_test__get_schema.snap index 4f5c8a11d..060865f3b 100644 --- a/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__schema_tests__schema_test__get_schema.snap +++ b/crates/tests/databases-tests/src/postgres/snapshots/databases_tests__postgres__schema_tests__schema_test__get_schema.snap @@ -10,22 +10,10 @@ expression: result }, "aggregate_functions": { "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "text" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "text" - } - } + "type": "min" } }, "comparison_operators": { @@ -176,6 +164,7 @@ expression: result }, "aggregate_functions": { "bool_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -185,6 +174,7 @@ expression: result } }, "bool_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -194,6 +184,7 @@ expression: result } }, "every": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -259,22 +250,10 @@ expression: result }, "aggregate_functions": { "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "card_suit" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "card_suit" - } - } + "type": "min" } }, "comparison_operators": { @@ -327,22 +306,10 @@ expression: result }, "aggregate_functions": { "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "text" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "text" - } - } + "type": "min" } }, "comparison_operators": { @@ -488,24 +455,15 @@ expression: result } }, "cidr": { + "representation": { + "type": "json" + }, "aggregate_functions": { "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "inet" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "inet" - } - } + "type": "min" } }, "comparison_operators": { @@ -600,22 +558,10 @@ expression: result }, "aggregate_functions": { "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "date" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "date" - } - } + "type": "min" } }, "comparison_operators": { @@ -668,6 +614,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -677,6 +624,7 @@ expression: result } }, "bit_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -686,6 +634,7 @@ expression: result } }, "bit_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -695,6 +644,7 @@ expression: result } }, "bit_xor": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -704,24 +654,13 @@ expression: result } }, "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int4" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int4" - } - } + "type": "min" }, "stddev": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -731,6 +670,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -740,6 +680,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -749,15 +690,11 @@ expression: result } }, "sum": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int8" - } - } + "type": "sum", + "result_type": "int8" }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -767,6 +704,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -776,6 +714,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -835,33 +774,17 @@ expression: result }, "aggregate_functions": { "avg": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float8" - } - } + "type": "average", + "result_type": "float8" }, "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float4" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float4" - } - } + "type": "min" }, "stddev": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -871,6 +794,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -880,6 +804,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -889,6 +814,7 @@ expression: result } }, "sum": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -898,6 +824,7 @@ expression: result } }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -907,6 +834,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -916,6 +844,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -975,33 +904,17 @@ expression: result }, "aggregate_functions": { "avg": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float8" - } - } + "type": "average", + "result_type": "float8" }, "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float8" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float8" - } - } + "type": "min" }, "stddev": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1011,6 +924,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1020,6 +934,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1029,15 +944,11 @@ expression: result } }, "sum": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float8" - } - } + "type": "sum", + "result_type": "float8" }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1047,6 +958,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1056,6 +968,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1110,24 +1023,15 @@ expression: result } }, "inet": { + "representation": { + "type": "json" + }, "aggregate_functions": { "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "inet" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "inet" - } - } + "type": "min" } }, "comparison_operators": { @@ -1222,6 +1126,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1231,6 +1136,7 @@ expression: result } }, "bit_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1240,6 +1146,7 @@ expression: result } }, "bit_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1249,6 +1156,7 @@ expression: result } }, "bit_xor": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1258,24 +1166,13 @@ expression: result } }, "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int2" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int2" - } - } + "type": "min" }, "stddev": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1285,6 +1182,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1294,6 +1192,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1303,15 +1202,11 @@ expression: result } }, "sum": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int8" - } - } + "type": "sum", + "result_type": "int8" }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1321,6 +1216,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1330,6 +1226,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1389,6 +1286,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1398,6 +1296,7 @@ expression: result } }, "bit_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1407,6 +1306,7 @@ expression: result } }, "bit_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1416,6 +1316,7 @@ expression: result } }, "bit_xor": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1425,24 +1326,13 @@ expression: result } }, "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int4" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int4" - } - } + "type": "min" }, "stddev": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1452,6 +1342,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1461,6 +1352,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1470,15 +1362,11 @@ expression: result } }, "sum": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int8" - } - } + "type": "sum", + "result_type": "int8" }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1488,6 +1376,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1497,6 +1386,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1556,6 +1446,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1565,6 +1456,7 @@ expression: result } }, "bit_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1574,6 +1466,7 @@ expression: result } }, "bit_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1583,6 +1476,7 @@ expression: result } }, "bit_xor": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1592,24 +1486,13 @@ expression: result } }, "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int8" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int8" - } - } + "type": "min" }, "stddev": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1619,6 +1502,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1628,6 +1512,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1637,6 +1522,7 @@ expression: result } }, "sum": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1646,6 +1532,7 @@ expression: result } }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1655,6 +1542,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1664,6 +1552,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1718,8 +1607,12 @@ expression: result } }, "interval": { + "representation": { + "type": "json" + }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1729,24 +1622,13 @@ expression: result } }, "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "interval" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "interval" - } - } + "type": "min" }, "sum": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1806,6 +1688,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1815,24 +1698,13 @@ expression: result } }, "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "numeric" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "numeric" - } - } + "type": "min" }, "stddev": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1842,6 +1714,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1851,6 +1724,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1860,6 +1734,7 @@ expression: result } }, "sum": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1869,6 +1744,7 @@ expression: result } }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1878,6 +1754,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1887,6 +1764,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1942,26 +1820,14 @@ expression: result }, "text": { "representation": { - "type": "string" - }, - "aggregate_functions": { - "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "text" - } - } + "type": "string" + }, + "aggregate_functions": { + "max": { + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "text" - } - } + "type": "min" } }, "comparison_operators": { @@ -2112,6 +1978,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -2121,24 +1988,13 @@ expression: result } }, "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "time" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "time" - } - } + "type": "min" }, "sum": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -2198,22 +2054,10 @@ expression: result }, "aggregate_functions": { "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "timestamp" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "timestamp" - } - } + "type": "min" } }, "comparison_operators": { @@ -2266,22 +2110,10 @@ expression: result }, "aggregate_functions": { "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "timestamptz" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "timestamptz" - } - } + "type": "min" } }, "comparison_operators": { @@ -2334,22 +2166,10 @@ expression: result }, "aggregate_functions": { "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "timetz" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "timetz" - } - } + "type": "min" } }, "comparison_operators": { @@ -2451,22 +2271,10 @@ expression: result }, "aggregate_functions": { "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "text" - } - } + "type": "max" }, "min": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "text" - } - } + "type": "min" } }, "comparison_operators": { @@ -2637,6 +2445,16 @@ expression: result "name": "varchar" } } + }, + "foreign_keys": { + "FK_AlbumArtistId": { + "column_mapping": { + "ArtistId": [ + "ArtistId" + ] + }, + "foreign_collection": "Artist" + } } }, "Artist": { @@ -2659,7 +2477,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "Customer": { "description": "The record of all customers", @@ -2772,6 +2591,16 @@ expression: result } } } + }, + "foreign_keys": { + "FK_CustomerSupportRepId": { + "column_mapping": { + "SupportRepId": [ + "EmployeeId" + ] + }, + "foreign_collection": "Employee" + } } }, "Employee": { @@ -2902,6 +2731,16 @@ expression: result } } } + }, + "foreign_keys": { + "FK_EmployeeReportsTo": { + "column_mapping": { + "ReportsTo": [ + "EmployeeId" + ] + }, + "foreign_collection": "Employee" + } } }, "Genre": { @@ -2921,7 +2760,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "Invoice": { "fields": { @@ -2994,6 +2834,16 @@ expression: result "name": "numeric" } } + }, + "foreign_keys": { + "FK_InvoiceCustomerId": { + "column_mapping": { + "CustomerId": [ + "CustomerId" + ] + }, + "foreign_collection": "Customer" + } } }, "InvoiceLine": { @@ -3028,6 +2878,24 @@ expression: result "name": "numeric" } } + }, + "foreign_keys": { + "FK_InvoiceLineInvoiceId": { + "column_mapping": { + "InvoiceId": [ + "InvoiceId" + ] + }, + "foreign_collection": "Invoice" + }, + "FK_InvoiceLineTrackId": { + "column_mapping": { + "TrackId": [ + "TrackId" + ] + }, + "foreign_collection": "Track" + } } }, "MediaType": { @@ -3047,7 +2915,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "Playlist": { "fields": { @@ -3066,7 +2935,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "PlaylistTrack": { "fields": { @@ -3082,6 +2952,24 @@ expression: result "name": "int4" } } + }, + "foreign_keys": { + "FK_PlaylistTrackPlaylistId": { + "column_mapping": { + "PlaylistId": [ + "PlaylistId" + ] + }, + "foreign_collection": "Playlist" + }, + "FK_PlaylistTrackTrackId": { + "column_mapping": { + "TrackId": [ + "TrackId" + ] + }, + "foreign_collection": "Track" + } } }, "Track": { @@ -3152,6 +3040,32 @@ expression: result "name": "numeric" } } + }, + "foreign_keys": { + "FK_TrackAlbumId": { + "column_mapping": { + "AlbumId": [ + "AlbumId" + ] + }, + "foreign_collection": "Album" + }, + "FK_TrackGenreId": { + "column_mapping": { + "GenreId": [ + "GenreId" + ] + }, + "foreign_collection": "Genre" + }, + "FK_TrackMediaTypeId": { + "column_mapping": { + "MediaTypeId": [ + "MediaTypeId" + ] + }, + "foreign_collection": "MediaType" + } } }, "address_identity_function": { @@ -3166,7 +3080,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "album_by_title": { "fields": { @@ -3197,7 +3112,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "array_reverse": { "description": "A native query used to test support for arrays as inputs", @@ -3218,7 +3134,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "array_series": { "description": "A native query used to test support for arrays", @@ -3247,7 +3164,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "artist": { "fields": { @@ -3269,7 +3187,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "artist_below_id": { "fields": { @@ -3291,7 +3210,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "chara": { "fields": { @@ -3313,7 +3233,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "characters": { "fields": { @@ -3341,7 +3262,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "committee": { "fields": { @@ -3369,7 +3291,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "count_elements": { "description": "A native query used to test support array-valued variables", @@ -3383,7 +3306,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "custom_defaults": { "fields": { @@ -3423,7 +3347,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "custom_dog": { "fields": { @@ -3469,7 +3394,8 @@ expression: result "name": "text" } } - } + }, + "foreign_keys": {} }, "custom_test_cidr": { "fields": { @@ -3491,7 +3417,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "deck_of_cards": { "fields": { @@ -3507,7 +3434,8 @@ expression: result "name": "card_suit" } } - } + }, + "foreign_keys": {} }, "delete_Album_by_AlbumId_response": { "description": "Responses from the 'delete_Album_by_AlbumId' procedure", @@ -3529,7 +3457,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_Artist_by_ArtistId_response": { "description": "Responses from the 'delete_Artist_by_ArtistId' procedure", @@ -3551,7 +3480,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_Customer_by_CustomerId_response": { "description": "Responses from the 'delete_Customer_by_CustomerId' procedure", @@ -3573,7 +3503,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_Employee_by_EmployeeId_response": { "description": "Responses from the 'delete_Employee_by_EmployeeId' procedure", @@ -3595,7 +3526,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_Genre_by_GenreId_response": { "description": "Responses from the 'delete_Genre_by_GenreId' procedure", @@ -3617,7 +3549,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_InvoiceLine_by_InvoiceLineId_response": { "description": "Responses from the 'delete_InvoiceLine_by_InvoiceLineId' procedure", @@ -3639,7 +3572,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_Invoice_by_InvoiceId_response": { "description": "Responses from the 'delete_Invoice_by_InvoiceId' procedure", @@ -3661,7 +3595,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_MediaType_by_MediaTypeId_response": { "description": "Responses from the 'delete_MediaType_by_MediaTypeId' procedure", @@ -3683,7 +3618,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_PlaylistTrack_by_PlaylistId_and_TrackId_response": { "description": "Responses from the 'delete_PlaylistTrack_by_PlaylistId_and_TrackId' procedure", @@ -3705,7 +3641,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_Playlist_by_PlaylistId_response": { "description": "Responses from the 'delete_Playlist_by_PlaylistId' procedure", @@ -3727,7 +3664,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_Track_by_TrackId_response": { "description": "Responses from the 'delete_Track_by_TrackId' procedure", @@ -3749,7 +3687,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_custom_defaults_by_id_response": { "description": "Responses from the 'delete_custom_defaults_by_id' procedure", @@ -3771,7 +3710,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_custom_dog_by_id_response": { "description": "Responses from the 'delete_custom_dog_by_id' procedure", @@ -3793,7 +3733,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_institution_institution_by_id_response": { "description": "Responses from the 'delete_institution_institution_by_id' procedure", @@ -3815,7 +3756,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_playlist_track": { "fields": { @@ -3837,7 +3779,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_playlist_track_response": { "description": "Responses from the 'delete_playlist_track' procedure", @@ -3859,7 +3802,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_spatial_ref_sys_by_srid_response": { "description": "Responses from the 'delete_spatial_ref_sys_by_srid' procedure", @@ -3881,7 +3825,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_topology_layer_by_feature_column_and_schema_name_and_table_name_response": { "description": "Responses from the 'delete_topology_layer_by_feature_column_and_schema_name_and_table_name' procedure", @@ -3903,7 +3848,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_topology_layer_by_layer_id_and_topology_id_response": { "description": "Responses from the 'delete_topology_layer_by_layer_id_and_topology_id' procedure", @@ -3925,7 +3871,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_topology_topology_by_id_response": { "description": "Responses from the 'delete_topology_topology_by_id' procedure", @@ -3947,7 +3894,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_topology_topology_by_name_response": { "description": "Responses from the 'delete_topology_topology_by_name' procedure", @@ -3969,7 +3917,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "discoverable_types": { "fields": { @@ -3982,7 +3931,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "discoverable_types_root_occurrence": { "fields": { @@ -3995,7 +3945,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "even_numbers": { "fields": { @@ -4005,7 +3956,8 @@ expression: result "name": "even_number" } } - } + }, + "foreign_keys": {} }, "group_leader": { "fields": { @@ -4036,7 +3988,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_Album_object": { "fields": { @@ -4061,7 +4014,8 @@ expression: result "name": "varchar" } } - } + }, + "foreign_keys": {} }, "insert_Album_response": { "description": "Responses from the 'insert_Album' procedure", @@ -4083,7 +4037,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_Artist_object": { "fields": { @@ -4104,7 +4059,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_Artist_response": { "description": "Responses from the 'insert_Artist' procedure", @@ -4126,7 +4082,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_Customer_object": { "fields": { @@ -4238,7 +4195,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_Customer_response": { "description": "Responses from the 'insert_Customer' procedure", @@ -4260,7 +4218,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_Employee_object": { "fields": { @@ -4390,7 +4349,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_Employee_response": { "description": "Responses from the 'insert_Employee' procedure", @@ -4412,7 +4372,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_Genre_object": { "fields": { @@ -4431,7 +4392,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_Genre_response": { "description": "Responses from the 'insert_Genre' procedure", @@ -4453,7 +4415,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_InvoiceLine_object": { "fields": { @@ -4487,7 +4450,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "insert_InvoiceLine_response": { "description": "Responses from the 'insert_InvoiceLine' procedure", @@ -4509,7 +4473,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_Invoice_object": { "fields": { @@ -4582,7 +4547,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "insert_Invoice_response": { "description": "Responses from the 'insert_Invoice' procedure", @@ -4604,7 +4570,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_MediaType_object": { "fields": { @@ -4623,7 +4590,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_MediaType_response": { "description": "Responses from the 'insert_MediaType' procedure", @@ -4645,7 +4613,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_PlaylistTrack_object": { "fields": { @@ -4661,7 +4630,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "insert_PlaylistTrack_response": { "description": "Responses from the 'insert_PlaylistTrack' procedure", @@ -4683,7 +4653,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_Playlist_object": { "fields": { @@ -4702,7 +4673,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "insert_Playlist_response": { "description": "Responses from the 'insert_Playlist' procedure", @@ -4724,7 +4696,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_Track_object": { "fields": { @@ -4794,7 +4767,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "insert_Track_response": { "description": "Responses from the 'insert_Track' procedure", @@ -4816,7 +4790,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_album": { "fields": { @@ -4847,7 +4822,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_album_response": { "description": "Responses from the 'insert_album' procedure", @@ -4869,7 +4845,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_artist": { "fields": { @@ -4891,7 +4868,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_artist_response": { "description": "Responses from the 'insert_artist' procedure", @@ -4913,7 +4891,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_custom_defaults_object": { "fields": { @@ -4944,7 +4923,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_custom_defaults_response": { "description": "Responses from the 'insert_custom_defaults' procedure", @@ -4966,7 +4946,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_custom_dog_object": { "fields": { @@ -5000,7 +4981,8 @@ expression: result "name": "text" } } - } + }, + "foreign_keys": {} }, "insert_custom_dog_response": { "description": "Responses from the 'insert_custom_dog' procedure", @@ -5022,7 +5004,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_custom_test_cidr_object": { "fields": { @@ -5044,7 +5027,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_custom_test_cidr_response": { "description": "Responses from the 'insert_custom_test_cidr' procedure", @@ -5066,7 +5050,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_deck_of_cards_object": { "fields": { @@ -5082,7 +5067,8 @@ expression: result "name": "card_suit" } } - } + }, + "foreign_keys": {} }, "insert_deck_of_cards_response": { "description": "Responses from the 'insert_deck_of_cards' procedure", @@ -5104,7 +5090,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_discoverable_types_root_occurrence_object": { "fields": { @@ -5117,7 +5104,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_discoverable_types_root_occurrence_response": { "description": "Responses from the 'insert_discoverable_types_root_occurrence' procedure", @@ -5139,7 +5127,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_even_numbers_object": { "fields": { @@ -5149,7 +5138,8 @@ expression: result "name": "even_number" } } - } + }, + "foreign_keys": {} }, "insert_even_numbers_response": { "description": "Responses from the 'insert_even_numbers' procedure", @@ -5171,7 +5161,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_genre": { "fields": { @@ -5190,7 +5181,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_genre_response": { "description": "Responses from the 'insert_genre' procedure", @@ -5212,7 +5204,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_group_leader_object": { "fields": { @@ -5243,7 +5236,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_group_leader_response": { "description": "Responses from the 'insert_group_leader' procedure", @@ -5265,7 +5259,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_institution_institution_object": { "fields": { @@ -5332,7 +5327,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_institution_institution_response": { "description": "Responses from the 'insert_institution_institution' procedure", @@ -5354,7 +5350,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_phone_numbers_object": { "fields": { @@ -5364,7 +5361,8 @@ expression: result "name": "Phone" } } - } + }, + "foreign_keys": {} }, "insert_phone_numbers_response": { "description": "Responses from the 'insert_phone_numbers' procedure", @@ -5386,7 +5384,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_spatial_ref_sys_object": { "fields": { @@ -5432,7 +5431,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_spatial_ref_sys_response": { "description": "Responses from the 'insert_spatial_ref_sys' procedure", @@ -5454,7 +5454,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_text_table_object": { "fields": { @@ -5476,7 +5477,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_text_table_response": { "description": "Responses from the 'insert_text_table' procedure", @@ -5498,7 +5500,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_topology_layer_object": { "fields": { @@ -5556,7 +5559,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "insert_topology_layer_response": { "description": "Responses from the 'insert_topology_layer' procedure", @@ -5578,7 +5582,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_topology_topology_object": { "fields": { @@ -5618,7 +5623,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "insert_topology_topology_response": { "description": "Responses from the 'insert_topology_topology' procedure", @@ -5640,7 +5646,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "institution_country": { "fields": { @@ -5662,7 +5669,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "institution_institution": { "fields": { @@ -5729,7 +5737,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "institution_institution_songs": { "fields": { @@ -5751,7 +5760,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "institution_location": { "fields": { @@ -5788,7 +5798,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "institution_staff": { "fields": { @@ -5834,7 +5845,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "make_person": { "description": "A native query used to test support for composite types", @@ -5848,7 +5860,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "organization": { "fields": { @@ -5876,7 +5889,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "organization_identity_function": { "description": "A native query used to test support for composite types", @@ -5890,7 +5904,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "person": { "fields": { @@ -5912,7 +5927,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "person_address": { "description": "The address of a person, obviously", @@ -5937,7 +5953,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "person_name": { "description": "The name of a person, obviously", @@ -5962,7 +5979,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "phone_numbers": { "fields": { @@ -5972,7 +5990,8 @@ expression: result "name": "Phone" } } - } + }, + "foreign_keys": {} }, "spatial_ref_sys": { "fields": { @@ -6018,7 +6037,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "summarize_organizations": { "description": "A native query used to test support array-valued variables", @@ -6032,7 +6052,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "text_table": { "fields": { @@ -6054,7 +6075,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "topology_layer": { "fields": { @@ -6109,6 +6131,16 @@ expression: result "name": "int4" } } + }, + "foreign_keys": { + "layer_topology_id_fkey": { + "column_mapping": { + "topology_id": [ + "id" + ] + }, + "foreign_collection": "topology_topology" + } } }, "topology_topology": { @@ -6143,7 +6175,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_Album_by_AlbumId_response": { "description": "Responses from the 'update_Album_by_AlbumId' procedure", @@ -6165,7 +6198,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Album_by_AlbumId_update_columns": { "description": "Update the columns of the 'Album' collection", @@ -6200,7 +6234,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Artist_by_ArtistId_response": { "description": "Responses from the 'update_Artist_by_ArtistId' procedure", @@ -6222,7 +6257,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Artist_by_ArtistId_update_columns": { "description": "Update the columns of the 'Artist' collection", @@ -6247,7 +6283,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Customer_by_CustomerId_response": { "description": "Responses from the 'update_Customer_by_CustomerId' procedure", @@ -6269,7 +6306,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Customer_by_CustomerId_update_columns": { "description": "Update the columns of the 'Customer' collection", @@ -6404,7 +6442,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Employee_by_EmployeeId_response": { "description": "Responses from the 'update_Employee_by_EmployeeId' procedure", @@ -6426,7 +6465,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Employee_by_EmployeeId_update_columns": { "description": "Update the columns of the 'Employee' collection", @@ -6581,7 +6621,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Genre_by_GenreId_response": { "description": "Responses from the 'update_Genre_by_GenreId' procedure", @@ -6603,7 +6644,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Genre_by_GenreId_update_columns": { "description": "Update the columns of the 'Genre' collection", @@ -6628,7 +6670,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_InvoiceLine_by_InvoiceLineId_response": { "description": "Responses from the 'update_InvoiceLine_by_InvoiceLineId' procedure", @@ -6650,7 +6693,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_InvoiceLine_by_InvoiceLineId_update_columns": { "description": "Update the columns of the 'InvoiceLine' collection", @@ -6705,7 +6749,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Invoice_by_InvoiceId_response": { "description": "Responses from the 'update_Invoice_by_InvoiceId' procedure", @@ -6727,7 +6772,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Invoice_by_InvoiceId_update_columns": { "description": "Update the columns of the 'Invoice' collection", @@ -6822,7 +6868,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_MediaType_by_MediaTypeId_response": { "description": "Responses from the 'update_MediaType_by_MediaTypeId' procedure", @@ -6844,7 +6891,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_MediaType_by_MediaTypeId_update_columns": { "description": "Update the columns of the 'MediaType' collection", @@ -6869,7 +6917,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_PlaylistTrack_by_PlaylistId_and_TrackId_response": { "description": "Responses from the 'update_PlaylistTrack_by_PlaylistId_and_TrackId' procedure", @@ -6891,7 +6940,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_PlaylistTrack_by_PlaylistId_and_TrackId_update_columns": { "description": "Update the columns of the 'PlaylistTrack' collection", @@ -6916,7 +6966,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Playlist_by_PlaylistId_response": { "description": "Responses from the 'update_Playlist_by_PlaylistId' procedure", @@ -6938,7 +6989,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Playlist_by_PlaylistId_update_columns": { "description": "Update the columns of the 'Playlist' collection", @@ -6963,7 +7015,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Track_by_TrackId_response": { "description": "Responses from the 'update_Track_by_TrackId' procedure", @@ -6985,7 +7038,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Track_by_TrackId_update_columns": { "description": "Update the columns of the 'Track' collection", @@ -7080,7 +7134,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Album_AlbumId": { "description": "Update the 'AlbumId' column in the 'Album' collection", @@ -7092,7 +7147,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_Album_ArtistId": { "description": "Update the 'ArtistId' column in the 'Album' collection", @@ -7104,7 +7160,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_Album_Title": { "description": "Update the 'Title' column in the 'Album' collection", @@ -7116,7 +7173,8 @@ expression: result "name": "varchar" } } - } + }, + "foreign_keys": {} }, "update_column_Artist_ArtistId": { "description": "Update the 'ArtistId' column in the 'Artist' collection", @@ -7128,7 +7186,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_Artist_Name": { "description": "Update the 'Name' column in the 'Artist' collection", @@ -7143,7 +7202,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Customer_Address": { "description": "Update the 'Address' column in the 'Customer' collection", @@ -7158,7 +7218,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Customer_City": { "description": "Update the 'City' column in the 'Customer' collection", @@ -7173,7 +7234,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Customer_Company": { "description": "Update the 'Company' column in the 'Customer' collection", @@ -7188,7 +7250,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Customer_Country": { "description": "Update the 'Country' column in the 'Customer' collection", @@ -7203,7 +7266,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Customer_CustomerId": { "description": "Update the 'CustomerId' column in the 'Customer' collection", @@ -7215,7 +7279,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_Customer_Email": { "description": "Update the 'Email' column in the 'Customer' collection", @@ -7227,7 +7292,8 @@ expression: result "name": "varchar" } } - } + }, + "foreign_keys": {} }, "update_column_Customer_Fax": { "description": "Update the 'Fax' column in the 'Customer' collection", @@ -7242,7 +7308,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Customer_FirstName": { "description": "Update the 'FirstName' column in the 'Customer' collection", @@ -7254,7 +7321,8 @@ expression: result "name": "varchar" } } - } + }, + "foreign_keys": {} }, "update_column_Customer_LastName": { "description": "Update the 'LastName' column in the 'Customer' collection", @@ -7266,7 +7334,8 @@ expression: result "name": "varchar" } } - } + }, + "foreign_keys": {} }, "update_column_Customer_Phone": { "description": "Update the 'Phone' column in the 'Customer' collection", @@ -7281,7 +7350,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Customer_PostalCode": { "description": "Update the 'PostalCode' column in the 'Customer' collection", @@ -7296,7 +7366,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Customer_State": { "description": "Update the 'State' column in the 'Customer' collection", @@ -7311,7 +7382,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Customer_SupportRepId": { "description": "Update the 'SupportRepId' column in the 'Customer' collection", @@ -7326,7 +7398,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Employee_Address": { "description": "Update the 'Address' column in the 'Employee' collection", @@ -7341,7 +7414,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Employee_BirthDate": { "description": "Update the 'BirthDate' column in the 'Employee' collection", @@ -7356,7 +7430,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Employee_City": { "description": "Update the 'City' column in the 'Employee' collection", @@ -7371,7 +7446,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Employee_Country": { "description": "Update the 'Country' column in the 'Employee' collection", @@ -7386,7 +7462,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Employee_Email": { "description": "Update the 'Email' column in the 'Employee' collection", @@ -7401,7 +7478,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Employee_EmployeeId": { "description": "Update the 'EmployeeId' column in the 'Employee' collection", @@ -7413,7 +7491,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_Employee_Fax": { "description": "Update the 'Fax' column in the 'Employee' collection", @@ -7428,7 +7507,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Employee_FirstName": { "description": "Update the 'FirstName' column in the 'Employee' collection", @@ -7440,7 +7520,8 @@ expression: result "name": "varchar" } } - } + }, + "foreign_keys": {} }, "update_column_Employee_HireDate": { "description": "Update the 'HireDate' column in the 'Employee' collection", @@ -7455,7 +7536,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Employee_LastName": { "description": "Update the 'LastName' column in the 'Employee' collection", @@ -7467,7 +7549,8 @@ expression: result "name": "varchar" } } - } + }, + "foreign_keys": {} }, "update_column_Employee_Phone": { "description": "Update the 'Phone' column in the 'Employee' collection", @@ -7482,7 +7565,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Employee_PostalCode": { "description": "Update the 'PostalCode' column in the 'Employee' collection", @@ -7497,7 +7581,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Employee_ReportsTo": { "description": "Update the 'ReportsTo' column in the 'Employee' collection", @@ -7512,7 +7597,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Employee_State": { "description": "Update the 'State' column in the 'Employee' collection", @@ -7527,7 +7613,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Employee_Title": { "description": "Update the 'Title' column in the 'Employee' collection", @@ -7542,7 +7629,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Genre_GenreId": { "description": "Update the 'GenreId' column in the 'Genre' collection", @@ -7554,7 +7642,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_Genre_Name": { "description": "Update the 'Name' column in the 'Genre' collection", @@ -7569,7 +7658,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_InvoiceLine_InvoiceId": { "description": "Update the 'InvoiceId' column in the 'InvoiceLine' collection", @@ -7581,7 +7671,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_InvoiceLine_InvoiceLineId": { "description": "Update the 'InvoiceLineId' column in the 'InvoiceLine' collection", @@ -7593,7 +7684,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_InvoiceLine_Quantity": { "description": "Update the 'Quantity' column in the 'InvoiceLine' collection", @@ -7605,7 +7697,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_InvoiceLine_TrackId": { "description": "Update the 'TrackId' column in the 'InvoiceLine' collection", @@ -7617,7 +7710,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_InvoiceLine_UnitPrice": { "description": "Update the 'UnitPrice' column in the 'InvoiceLine' collection", @@ -7629,7 +7723,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "update_column_Invoice_BillingAddress": { "description": "Update the 'BillingAddress' column in the 'Invoice' collection", @@ -7644,7 +7739,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Invoice_BillingCity": { "description": "Update the 'BillingCity' column in the 'Invoice' collection", @@ -7659,7 +7755,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Invoice_BillingCountry": { "description": "Update the 'BillingCountry' column in the 'Invoice' collection", @@ -7674,7 +7771,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Invoice_BillingPostalCode": { "description": "Update the 'BillingPostalCode' column in the 'Invoice' collection", @@ -7689,7 +7787,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Invoice_BillingState": { "description": "Update the 'BillingState' column in the 'Invoice' collection", @@ -7704,7 +7803,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Invoice_CustomerId": { "description": "Update the 'CustomerId' column in the 'Invoice' collection", @@ -7716,7 +7816,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_Invoice_InvoiceDate": { "description": "Update the 'InvoiceDate' column in the 'Invoice' collection", @@ -7728,7 +7829,8 @@ expression: result "name": "timestamp" } } - } + }, + "foreign_keys": {} }, "update_column_Invoice_InvoiceId": { "description": "Update the 'InvoiceId' column in the 'Invoice' collection", @@ -7740,7 +7842,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_Invoice_Total": { "description": "Update the 'Total' column in the 'Invoice' collection", @@ -7752,7 +7855,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "update_column_MediaType_MediaTypeId": { "description": "Update the 'MediaTypeId' column in the 'MediaType' collection", @@ -7764,7 +7868,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_MediaType_Name": { "description": "Update the 'Name' column in the 'MediaType' collection", @@ -7779,7 +7884,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_PlaylistTrack_PlaylistId": { "description": "Update the 'PlaylistId' column in the 'PlaylistTrack' collection", @@ -7791,7 +7897,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_PlaylistTrack_TrackId": { "description": "Update the 'TrackId' column in the 'PlaylistTrack' collection", @@ -7803,7 +7910,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_Playlist_Name": { "description": "Update the 'Name' column in the 'Playlist' collection", @@ -7818,7 +7926,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Playlist_PlaylistId": { "description": "Update the 'PlaylistId' column in the 'Playlist' collection", @@ -7830,7 +7939,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_Track_AlbumId": { "description": "Update the 'AlbumId' column in the 'Track' collection", @@ -7845,7 +7955,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Track_Bytes": { "description": "Update the 'Bytes' column in the 'Track' collection", @@ -7860,7 +7971,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Track_Composer": { "description": "Update the 'Composer' column in the 'Track' collection", @@ -7875,7 +7987,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Track_GenreId": { "description": "Update the 'GenreId' column in the 'Track' collection", @@ -7890,7 +8003,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Track_MediaTypeId": { "description": "Update the 'MediaTypeId' column in the 'Track' collection", @@ -7902,7 +8016,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_Track_Milliseconds": { "description": "Update the 'Milliseconds' column in the 'Track' collection", @@ -7914,7 +8029,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_Track_Name": { "description": "Update the 'Name' column in the 'Track' collection", @@ -7926,7 +8042,8 @@ expression: result "name": "varchar" } } - } + }, + "foreign_keys": {} }, "update_column_Track_TrackId": { "description": "Update the 'TrackId' column in the 'Track' collection", @@ -7938,7 +8055,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_Track_UnitPrice": { "description": "Update the 'UnitPrice' column in the 'Track' collection", @@ -7950,7 +8068,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "update_column_custom_defaults_birthday": { "description": "Update the 'birthday' column in the 'custom_defaults' collection", @@ -7962,7 +8081,8 @@ expression: result "name": "date" } } - } + }, + "foreign_keys": {} }, "update_column_custom_defaults_height_cm": { "description": "Update the 'height_cm' column in the 'custom_defaults' collection", @@ -7974,7 +8094,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "update_column_custom_defaults_name": { "description": "Update the 'name' column in the 'custom_defaults' collection", @@ -7989,7 +8110,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_custom_dog_adopter_name": { "description": "Update the 'adopter_name' column in the 'custom_dog' collection", @@ -8004,7 +8126,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_custom_dog_birthday": { "description": "Update the 'birthday' column in the 'custom_dog' collection", @@ -8016,7 +8139,8 @@ expression: result "name": "date" } } - } + }, + "foreign_keys": {} }, "update_column_custom_dog_height_cm": { "description": "Update the 'height_cm' column in the 'custom_dog' collection", @@ -8028,7 +8152,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "update_column_custom_dog_name": { "description": "Update the 'name' column in the 'custom_dog' collection", @@ -8040,7 +8165,8 @@ expression: result "name": "text" } } - } + }, + "foreign_keys": {} }, "update_column_institution_institution_departments": { "description": "Update the 'departments' column in the 'institution_institution' collection", @@ -8061,7 +8187,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_institution_institution_id": { "description": "Update the 'id' column in the 'institution_institution' collection", @@ -8073,7 +8200,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_institution_institution_location": { "description": "Update the 'location' column in the 'institution_institution' collection", @@ -8088,7 +8216,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_institution_institution_name": { "description": "Update the 'name' column in the 'institution_institution' collection", @@ -8103,7 +8232,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_institution_institution_songs": { "description": "Update the 'songs' column in the 'institution_institution' collection", @@ -8118,7 +8248,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_institution_institution_staff": { "description": "Update the 'staff' column in the 'institution_institution' collection", @@ -8139,7 +8270,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_spatial_ref_sys_auth_name": { "description": "Update the 'auth_name' column in the 'spatial_ref_sys' collection", @@ -8154,7 +8286,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_spatial_ref_sys_auth_srid": { "description": "Update the 'auth_srid' column in the 'spatial_ref_sys' collection", @@ -8169,7 +8302,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_spatial_ref_sys_proj4text": { "description": "Update the 'proj4text' column in the 'spatial_ref_sys' collection", @@ -8184,7 +8318,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_spatial_ref_sys_srid": { "description": "Update the 'srid' column in the 'spatial_ref_sys' collection", @@ -8196,7 +8331,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_spatial_ref_sys_srtext": { "description": "Update the 'srtext' column in the 'spatial_ref_sys' collection", @@ -8211,7 +8347,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_topology_layer_child_id": { "description": "Update the 'child_id' column in the 'topology_layer' collection", @@ -8226,7 +8363,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_topology_layer_feature_column": { "description": "Update the 'feature_column' column in the 'topology_layer' collection", @@ -8238,7 +8376,8 @@ expression: result "name": "varchar" } } - } + }, + "foreign_keys": {} }, "update_column_topology_layer_feature_type": { "description": "Update the 'feature_type' column in the 'topology_layer' collection", @@ -8250,7 +8389,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_topology_layer_layer_id": { "description": "Update the 'layer_id' column in the 'topology_layer' collection", @@ -8262,7 +8402,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_topology_layer_level": { "description": "Update the 'level' column in the 'topology_layer' collection", @@ -8274,7 +8415,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_topology_layer_schema_name": { "description": "Update the 'schema_name' column in the 'topology_layer' collection", @@ -8286,7 +8428,8 @@ expression: result "name": "varchar" } } - } + }, + "foreign_keys": {} }, "update_column_topology_layer_table_name": { "description": "Update the 'table_name' column in the 'topology_layer' collection", @@ -8298,7 +8441,8 @@ expression: result "name": "varchar" } } - } + }, + "foreign_keys": {} }, "update_column_topology_layer_topology_id": { "description": "Update the 'topology_id' column in the 'topology_layer' collection", @@ -8310,7 +8454,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_topology_topology_hasz": { "description": "Update the 'hasz' column in the 'topology_topology' collection", @@ -8322,7 +8467,8 @@ expression: result "name": "bool" } } - } + }, + "foreign_keys": {} }, "update_column_topology_topology_id": { "description": "Update the 'id' column in the 'topology_topology' collection", @@ -8334,7 +8480,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_topology_topology_name": { "description": "Update the 'name' column in the 'topology_topology' collection", @@ -8346,7 +8493,8 @@ expression: result "name": "varchar" } } - } + }, + "foreign_keys": {} }, "update_column_topology_topology_precision": { "description": "Update the 'precision' column in the 'topology_topology' collection", @@ -8358,7 +8506,8 @@ expression: result "name": "float8" } } - } + }, + "foreign_keys": {} }, "update_column_topology_topology_srid": { "description": "Update the 'srid' column in the 'topology_topology' collection", @@ -8370,7 +8519,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_custom_defaults_by_id_response": { "description": "Responses from the 'update_custom_defaults_by_id' procedure", @@ -8392,7 +8542,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_custom_defaults_by_id_update_columns": { "description": "Update the columns of the 'custom_defaults' collection", @@ -8427,7 +8578,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_custom_dog_by_id_response": { "description": "Responses from the 'update_custom_dog_by_id' procedure", @@ -8449,7 +8601,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_custom_dog_by_id_update_columns": { "description": "Update the columns of the 'custom_dog' collection", @@ -8494,7 +8647,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_institution_institution_by_id_response": { "description": "Responses from the 'update_institution_institution_by_id' procedure", @@ -8516,7 +8670,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_institution_institution_by_id_update_columns": { "description": "Update the columns of the 'institution_institution' collection", @@ -8581,7 +8736,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_spatial_ref_sys_by_srid_response": { "description": "Responses from the 'update_spatial_ref_sys_by_srid' procedure", @@ -8603,7 +8759,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_spatial_ref_sys_by_srid_update_columns": { "description": "Update the columns of the 'spatial_ref_sys' collection", @@ -8658,7 +8815,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_topology_layer_by_feature_column_and_schema_name_and_table_name_response": { "description": "Responses from the 'update_topology_layer_by_feature_column_and_schema_name_and_table_name' procedure", @@ -8680,7 +8838,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_topology_layer_by_feature_column_and_schema_name_and_table_name_update_columns": { "description": "Update the columns of the 'topology_layer' collection", @@ -8765,7 +8924,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_topology_layer_by_layer_id_and_topology_id_response": { "description": "Responses from the 'update_topology_layer_by_layer_id_and_topology_id' procedure", @@ -8787,7 +8947,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_topology_layer_by_layer_id_and_topology_id_update_columns": { "description": "Update the columns of the 'topology_layer' collection", @@ -8872,7 +9033,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_topology_topology_by_id_response": { "description": "Responses from the 'update_topology_topology_by_id' procedure", @@ -8894,7 +9056,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_topology_topology_by_id_update_columns": { "description": "Update the columns of the 'topology_topology' collection", @@ -8949,7 +9112,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_topology_topology_by_name_response": { "description": "Responses from the 'update_topology_topology_by_name' procedure", @@ -8971,7 +9135,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_topology_topology_by_name_update_columns": { "description": "Update the columns of the 'topology_topology' collection", @@ -9026,7 +9191,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "value_types": { "fields": { @@ -9174,7 +9340,8 @@ expression: result } } } - } + }, + "foreign_keys": {} } }, "collections": [ @@ -9189,14 +9356,6 @@ expression: result "AlbumId" ] } - }, - "foreign_keys": { - "FK_AlbumArtistId": { - "column_mapping": { - "ArtistId": "ArtistId" - }, - "foreign_collection": "Artist" - } } }, { @@ -9210,8 +9369,7 @@ expression: result "ArtistId" ] } - }, - "foreign_keys": {} + } }, { "name": "Customer", @@ -9224,14 +9382,6 @@ expression: result "CustomerId" ] } - }, - "foreign_keys": { - "FK_CustomerSupportRepId": { - "column_mapping": { - "SupportRepId": "EmployeeId" - }, - "foreign_collection": "Employee" - } } }, { @@ -9244,14 +9394,6 @@ expression: result "EmployeeId" ] } - }, - "foreign_keys": { - "FK_EmployeeReportsTo": { - "column_mapping": { - "ReportsTo": "EmployeeId" - }, - "foreign_collection": "Employee" - } } }, { @@ -9264,8 +9406,7 @@ expression: result "GenreId" ] } - }, - "foreign_keys": {} + } }, { "name": "Invoice", @@ -9277,14 +9418,6 @@ expression: result "InvoiceId" ] } - }, - "foreign_keys": { - "FK_InvoiceCustomerId": { - "column_mapping": { - "CustomerId": "CustomerId" - }, - "foreign_collection": "Customer" - } } }, { @@ -9297,20 +9430,6 @@ expression: result "InvoiceLineId" ] } - }, - "foreign_keys": { - "FK_InvoiceLineInvoiceId": { - "column_mapping": { - "InvoiceId": "InvoiceId" - }, - "foreign_collection": "Invoice" - }, - "FK_InvoiceLineTrackId": { - "column_mapping": { - "TrackId": "TrackId" - }, - "foreign_collection": "Track" - } } }, { @@ -9323,8 +9442,7 @@ expression: result "MediaTypeId" ] } - }, - "foreign_keys": {} + } }, { "name": "Playlist", @@ -9336,8 +9454,7 @@ expression: result "PlaylistId" ] } - }, - "foreign_keys": {} + } }, { "name": "PlaylistTrack", @@ -9350,20 +9467,6 @@ expression: result "TrackId" ] } - }, - "foreign_keys": { - "FK_PlaylistTrackPlaylistId": { - "column_mapping": { - "PlaylistId": "PlaylistId" - }, - "foreign_collection": "Playlist" - }, - "FK_PlaylistTrackTrackId": { - "column_mapping": { - "TrackId": "TrackId" - }, - "foreign_collection": "Track" - } } }, { @@ -9376,26 +9479,6 @@ expression: result "TrackId" ] } - }, - "foreign_keys": { - "FK_TrackAlbumId": { - "column_mapping": { - "AlbumId": "AlbumId" - }, - "foreign_collection": "Album" - }, - "FK_TrackGenreId": { - "column_mapping": { - "GenreId": "GenreId" - }, - "foreign_collection": "Genre" - }, - "FK_TrackMediaTypeId": { - "column_mapping": { - "MediaTypeId": "MediaTypeId" - }, - "foreign_collection": "MediaType" - } } }, { @@ -9408,8 +9491,7 @@ expression: result "id" ] } - }, - "foreign_keys": {} + } }, { "name": "custom_dog", @@ -9421,43 +9503,37 @@ expression: result "id" ] } - }, - "foreign_keys": {} + } }, { "name": "custom_test_cidr", "arguments": {}, "type": "custom_test_cidr", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "deck_of_cards", "arguments": {}, "type": "deck_of_cards", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "discoverable_types_root_occurrence", "arguments": {}, "type": "discoverable_types_root_occurrence", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "even_numbers", "arguments": {}, "type": "even_numbers", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "group_leader", "arguments": {}, "type": "group_leader", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "institution_institution", @@ -9469,15 +9545,13 @@ expression: result "id" ] } - }, - "foreign_keys": {} + } }, { "name": "phone_numbers", "arguments": {}, "type": "phone_numbers", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "spatial_ref_sys", @@ -9489,15 +9563,13 @@ expression: result "srid" ] } - }, - "foreign_keys": {} + } }, { "name": "text_table", "arguments": {}, "type": "text_table", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "topology_layer", @@ -9517,14 +9589,6 @@ expression: result "table_name" ] } - }, - "foreign_keys": { - "layer_topology_id_fkey": { - "column_mapping": { - "topology_id": "id" - }, - "foreign_collection": "topology_topology" - } } }, { @@ -9542,8 +9606,7 @@ expression: result "id" ] } - }, - "foreign_keys": {} + } }, { "name": "address_identity_function", @@ -9560,8 +9623,7 @@ expression: result } }, "type": "address_identity_function", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "album_by_title", @@ -9586,8 +9648,7 @@ expression: result } }, "type": "album_by_title", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "array_reverse", @@ -9608,8 +9669,7 @@ expression: result } }, "type": "array_reverse", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "array_series", @@ -9635,15 +9695,13 @@ expression: result } }, "type": "array_series", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "artist", "arguments": {}, "type": "artist", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "artist_below_id", @@ -9659,8 +9717,7 @@ expression: result } }, "type": "artist_below_id", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "count_elements", @@ -9683,8 +9740,7 @@ expression: result } }, "type": "count_elements", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "make_person", @@ -9710,8 +9766,7 @@ expression: result } }, "type": "make_person", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "organization_identity_function", @@ -9728,8 +9783,7 @@ expression: result } }, "type": "organization_identity_function", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "summarize_organizations", @@ -9752,8 +9806,7 @@ expression: result } }, "type": "summarize_organizations", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "value_types", @@ -9904,8 +9957,7 @@ expression: result } }, "type": "value_types", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} } ], "functions": [], @@ -12057,5 +12109,12 @@ expression: result "name": "update_topology_topology_by_name_response" } } - ] + ], + "capabilities": { + "query": { + "aggregates": { + "count_scalar_type": "int8" + } + } + } } diff --git a/crates/tests/databases-tests/src/snapshots/databases_tests__capabilities_tests__get_capabilities.snap b/crates/tests/databases-tests/src/snapshots/databases_tests__capabilities_tests__get_capabilities.snap index ec31756c1..0bfd09d89 100644 --- a/crates/tests/databases-tests/src/snapshots/databases_tests__capabilities_tests__get_capabilities.snap +++ b/crates/tests/databases-tests/src/snapshots/databases_tests__capabilities_tests__get_capabilities.snap @@ -9,7 +9,8 @@ expression: "ndc_postgres::capabilities::get_capabilities()" "explain": {}, "nested_fields": { "filter_by": {}, - "order_by": {} + "order_by": {}, + "aggregates": {} }, "exists": { "nested_collections": {} @@ -21,6 +22,9 @@ expression: "ndc_postgres::capabilities::get_capabilities()" }, "relationships": { "relation_comparisons": {}, - "order_by_aggregate": {} + "order_by_aggregate": {}, + "nested": { + "array": {} + } } } diff --git a/crates/tests/tests-common/Cargo.toml b/crates/tests/tests-common/Cargo.toml index 7794b82c1..237235ea9 100644 --- a/crates/tests/tests-common/Cargo.toml +++ b/crates/tests/tests-common/Cargo.toml @@ -27,8 +27,12 @@ reqwest = { workspace = true } schemars = { workspace = true } serde = { workspace = true } serde_json = { workspace = true, features = ["raw_value"] } -sqlx = { workspace = true, features = [ "json", "postgres", "runtime-tokio-rustls" ] } +sqlx = { workspace = true, features = [ + "json", + "postgres", + "runtime-tokio-rustls", +] } tokio = { workspace = true, features = ["full"] } tracing = { workspace = true } url = { workspace = true } -uuid = { workspace = true, features = [ "v4", "fast-rng", "macro-diagnostics" ] } +uuid = { workspace = true, features = ["v4", "fast-rng", "macro-diagnostics"] } diff --git a/crates/tests/tests-common/goldenfiles/aggregate_count_artist_albums.json b/crates/tests/tests-common/goldenfiles/aggregate_count_artist_albums.json index c6c02d46e..92b94c97d 100644 --- a/crates/tests/tests-common/goldenfiles/aggregate_count_artist_albums.json +++ b/crates/tests/tests-common/goldenfiles/aggregate_count_artist_albums.json @@ -40,7 +40,7 @@ "collection_relationships": { "ArtistToAlbums": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album", diff --git a/crates/tests/tests-common/goldenfiles/aggregate_count_artist_albums_plus_field.json b/crates/tests/tests-common/goldenfiles/aggregate_count_artist_albums_plus_field.json index 4dbad7617..2e739ac95 100644 --- a/crates/tests/tests-common/goldenfiles/aggregate_count_artist_albums_plus_field.json +++ b/crates/tests/tests-common/goldenfiles/aggregate_count_artist_albums_plus_field.json @@ -59,7 +59,7 @@ "collection_relationships": { "ArtistToAlbums": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album", diff --git a/crates/tests/tests-common/goldenfiles/dup_array_relationship.json b/crates/tests/tests-common/goldenfiles/dup_array_relationship.json index 819b01ad2..2b92f88b4 100644 --- a/crates/tests/tests-common/goldenfiles/dup_array_relationship.json +++ b/crates/tests/tests-common/goldenfiles/dup_array_relationship.json @@ -74,7 +74,7 @@ "collection_relationships": { "ArtistAlbums": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album", diff --git a/crates/tests/tests-common/goldenfiles/duplicate_filter_results.json b/crates/tests/tests-common/goldenfiles/duplicate_filter_results.json index f7de89b9d..d2536fa73 100644 --- a/crates/tests/tests-common/goldenfiles/duplicate_filter_results.json +++ b/crates/tests/tests-common/goldenfiles/duplicate_filter_results.json @@ -10,25 +10,23 @@ } }, "predicate": { - "type": "binary_comparison_operator", - "column": { - "type": "column", - "name": "Title", - "path": [ - { - "relationship": "Artist_Albums", - "arguments": {}, - "predicate": { - "type": "and", - "expressions": [] - } - } - ] + "type": "exists", + "in_collection": { + "type": "related", + "relationship": "Artist_Albums", + "arguments": {} }, - "operator": "_like", - "value": { - "type": "scalar", - "value": "%e%" + "predicate": { + "type": "binary_comparison_operator", + "column": { + "type": "column", + "name": "Title" + }, + "operator": "_like", + "value": { + "type": "scalar", + "value": "%e%" + } } }, "order_by": { @@ -50,7 +48,7 @@ "Artist_Albums": { "arguments": {}, "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album" diff --git a/crates/tests/tests-common/goldenfiles/duplicate_filter_results_nested.json b/crates/tests/tests-common/goldenfiles/duplicate_filter_results_nested.json index 648847205..fe3bf2430 100644 --- a/crates/tests/tests-common/goldenfiles/duplicate_filter_results_nested.json +++ b/crates/tests/tests-common/goldenfiles/duplicate_filter_results_nested.json @@ -13,55 +13,51 @@ "type": "or", "expressions": [ { - "type": "binary_comparison_operator", - "column": { - "type": "column", - "name": "Name", - "path": [ - { - "relationship": "Artist_Albums", - "arguments": {}, - "predicate": { - "type": "and", - "expressions": [] - } + "type": "exists", + "in_collection": { + "type": "related", + "relationship": "Artist_Albums", + "arguments": {} + }, + "predicate": { + "type": "exists", + "in_collection": { + "type": "related", + "relationship": "Albums_Tracks", + "arguments": {} + }, + "predicate": { + "type": "binary_comparison_operator", + "column": { + "type": "column", + "name": "Name" }, - { - "relationship": "Albums_Tracks", - "arguments": {}, - "predicate": { - "type": "and", - "expressions": [] - } + "operator": "_like", + "value": { + "type": "scalar", + "value": "%e%" } - ] - }, - "operator": "_like", - "value": { - "type": "scalar", - "value": "%e%" + } } }, { - "type": "binary_comparison_operator", - "column": { - "type": "column", - "name": "Title", - "path": [ - { - "relationship": "Artist_Albums", - "arguments": {}, - "predicate": { - "type": "and", - "expressions": [] - } - } - ] + "type": "exists", + "in_collection": { + "type": "related", + "relationship": "Artist_Albums", + "arguments": {} }, - "operator": "_like", - "value": { - "type": "scalar", - "value": "%e%" + "predicate": { + "type": "binary_comparison_operator", + "column": { + "type": "column", + "name": "Title" + }, + "operator": "_like", + "value": { + "type": "scalar", + "value": "%e%" + } } } ] @@ -85,7 +81,7 @@ "Artist_Albums": { "arguments": {}, "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album" @@ -93,7 +89,7 @@ "Albums_Tracks": { "arguments": {}, "column_mapping": { - "AlbumId": "AlbumId" + "AlbumId": ["AlbumId"] }, "relationship_type": "array", "target_collection": "Track" diff --git a/crates/tests/tests-common/goldenfiles/mutations/delete_invoice_line.json b/crates/tests/tests-common/goldenfiles/mutations/delete_invoice_line.json index 1c2d72370..3b3a1a64b 100644 --- a/crates/tests/tests-common/goldenfiles/mutations/delete_invoice_line.json +++ b/crates/tests/tests-common/goldenfiles/mutations/delete_invoice_line.json @@ -7,21 +7,23 @@ "arguments": { "key_InvoiceLineId": 90, "pre_check": { - "type": "binary_comparison_operator", - "column": { - "type": "column", - "name": "TrackId", - "path": [ - { - "relationship": "InvoiceLineTrack", - "arguments": {} - } - ] + "type": "exists", + "in_collection": { + "type": "related", + "relationship": "InvoiceLineTrack", + "arguments": {} }, - "operator": "_eq", - "value": { - "type": "scalar", - "value": 512 + "predicate": { + "type": "binary_comparison_operator", + "column": { + "type": "column", + "name": "TrackId" + }, + "operator": "_eq", + "value": { + "type": "scalar", + "value": 512 + } } } }, @@ -59,7 +61,7 @@ "collection_relationships": { "InvoiceLineTrack": { "column_mapping": { - "TrackId": "TrackId" + "TrackId": ["TrackId"] }, "relationship_type": "object", "target_collection": "Track", diff --git a/crates/tests/tests-common/goldenfiles/mutations/insert_artist_album.json b/crates/tests/tests-common/goldenfiles/mutations/insert_artist_album.json index 1060a97ea..f27fe90d7 100644 --- a/crates/tests/tests-common/goldenfiles/mutations/insert_artist_album.json +++ b/crates/tests/tests-common/goldenfiles/mutations/insert_artist_album.json @@ -97,7 +97,7 @@ "collection_relationships": { "AlbumToArtist": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "object", "target_collection": "Artist", diff --git a/crates/tests/tests-common/goldenfiles/mutations/insert_artist_album_bad.json b/crates/tests/tests-common/goldenfiles/mutations/insert_artist_album_bad.json index c700deb3e..29dffff3a 100644 --- a/crates/tests/tests-common/goldenfiles/mutations/insert_artist_album_bad.json +++ b/crates/tests/tests-common/goldenfiles/mutations/insert_artist_album_bad.json @@ -97,7 +97,7 @@ "collection_relationships": { "AlbumToArtist": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "object", "target_collection": "Artist", diff --git a/crates/tests/tests-common/goldenfiles/native_queries/select_artist_with_album_by_title_relationship_arguments.json b/crates/tests/tests-common/goldenfiles/native_queries/select_artist_with_album_by_title_relationship_arguments.json index 4116a76e7..ffd70aba9 100644 --- a/crates/tests/tests-common/goldenfiles/native_queries/select_artist_with_album_by_title_relationship_arguments.json +++ b/crates/tests/tests-common/goldenfiles/native_queries/select_artist_with_album_by_title_relationship_arguments.json @@ -58,7 +58,7 @@ "collection_relationships": { "Albums": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "album_by_title", diff --git a/crates/tests/tests-common/goldenfiles/native_queries/select_order_by_artist_album_count.json b/crates/tests/tests-common/goldenfiles/native_queries/select_order_by_artist_album_count.json index 7ff101f5e..61e29d8fc 100644 --- a/crates/tests/tests-common/goldenfiles/native_queries/select_order_by_artist_album_count.json +++ b/crates/tests/tests-common/goldenfiles/native_queries/select_order_by_artist_album_count.json @@ -45,7 +45,10 @@ { "order_direction": "desc", "target": { - "type": "star_count_aggregate", + "type": "aggregate", + "aggregate": { + "type": "star_count" + }, "path": [ { "relationship": "ArtistAlbums", @@ -74,7 +77,7 @@ "collection_relationships": { "ArtistAlbums": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "album_by_title", diff --git a/crates/tests/tests-common/goldenfiles/native_queries/select_sort_relationship.json b/crates/tests/tests-common/goldenfiles/native_queries/select_sort_relationship.json index 612425346..0654e7d34 100644 --- a/crates/tests/tests-common/goldenfiles/native_queries/select_sort_relationship.json +++ b/crates/tests/tests-common/goldenfiles/native_queries/select_sort_relationship.json @@ -52,7 +52,7 @@ "collection_relationships": { "AlbumToArtist": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "object", "target_collection": "artist", diff --git a/crates/tests/tests-common/goldenfiles/native_queries/select_where_relationship.json b/crates/tests/tests-common/goldenfiles/native_queries/select_where_relationship.json index 91cb776ef..dd49ea2b6 100644 --- a/crates/tests/tests-common/goldenfiles/native_queries/select_where_relationship.json +++ b/crates/tests/tests-common/goldenfiles/native_queries/select_where_relationship.json @@ -28,25 +28,23 @@ }, "limit": 5, "predicate": { - "type": "binary_comparison_operator", - "column": { - "type": "column", - "name": "Name", - "path": [ - { - "relationship": "AlbumToArtist", - "arguments": {}, - "predicate": { - "type": "and", - "expressions": [] - } - } - ] + "type": "exists", + "in_collection": { + "type": "related", + "relationship": "AlbumToArtist", + "arguments": {} }, - "operator": "_like", - "value": { - "type": "scalar", - "value": "A%" + "predicate": { + "type": "binary_comparison_operator", + "column": { + "type": "column", + "name": "Name" + }, + "operator": "_like", + "value": { + "type": "scalar", + "value": "A%" + } } } }, @@ -57,7 +55,7 @@ "collection_relationships": { "AlbumToArtist": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "object", "target_collection": "artist", diff --git a/crates/tests/tests-common/goldenfiles/nested_array_relationships.json b/crates/tests/tests-common/goldenfiles/nested_array_relationships.json index 6c89c2f05..7b701a060 100644 --- a/crates/tests/tests-common/goldenfiles/nested_array_relationships.json +++ b/crates/tests/tests-common/goldenfiles/nested_array_relationships.json @@ -82,7 +82,7 @@ "collection_relationships": { "ArtistAlbums": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album", @@ -90,7 +90,7 @@ }, "AlbumTracks": { "column_mapping": { - "AlbumId": "AlbumId" + "AlbumId": ["AlbumId"] }, "relationship_type": "array", "target_collection": "Track", diff --git a/crates/tests/tests-common/goldenfiles/nested_field_relationship.json b/crates/tests/tests-common/goldenfiles/nested_field_relationship.json index 08d29910e..e2f5ca9cf 100644 --- a/crates/tests/tests-common/goldenfiles/nested_field_relationship.json +++ b/crates/tests/tests-common/goldenfiles/nested_field_relationship.json @@ -45,7 +45,7 @@ "collection_relationships": { "default___staff_member__favourite_artist": { "column_mapping": { - "favourite_artist_id": "ArtistId" + "favourite_artist_id": ["ArtistId"] }, "relationship_type": "object", "target_collection": "Artist", diff --git a/crates/tests/tests-common/goldenfiles/nested_object_relationships.json b/crates/tests/tests-common/goldenfiles/nested_object_relationships.json index d9fa338d1..b4e9ac0ca 100644 --- a/crates/tests/tests-common/goldenfiles/nested_object_relationships.json +++ b/crates/tests/tests-common/goldenfiles/nested_object_relationships.json @@ -56,7 +56,7 @@ "collection_relationships": { "TrackToAlbum": { "column_mapping": { - "AlbumId": "AlbumId" + "AlbumId": ["AlbumId"] }, "relationship_type": "object", "target_collection": "Album", @@ -64,7 +64,7 @@ }, "AlbumToArtist": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "object", "target_collection": "Artist", diff --git a/crates/tests/tests-common/goldenfiles/select_album_object_relationship_to_artist.json b/crates/tests/tests-common/goldenfiles/select_album_object_relationship_to_artist.json index c3a42f643..0ed8988f2 100644 --- a/crates/tests/tests-common/goldenfiles/select_album_object_relationship_to_artist.json +++ b/crates/tests/tests-common/goldenfiles/select_album_object_relationship_to_artist.json @@ -42,7 +42,7 @@ "collection_relationships": { "AlbumToArtist": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "object", "target_collection": "Artist", diff --git a/crates/tests/tests-common/goldenfiles/select_artist_array_relationship_to_album.json b/crates/tests/tests-common/goldenfiles/select_artist_array_relationship_to_album.json index a592f76b7..7818812a8 100644 --- a/crates/tests/tests-common/goldenfiles/select_artist_array_relationship_to_album.json +++ b/crates/tests/tests-common/goldenfiles/select_artist_array_relationship_to_album.json @@ -54,7 +54,7 @@ "collection_relationships": { "ArtistToAlbums": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album", diff --git a/crates/tests/tests-common/goldenfiles/select_order_by_album_artist_name.json b/crates/tests/tests-common/goldenfiles/select_order_by_album_artist_name.json index 0161ad3d9..30090ef5a 100644 --- a/crates/tests/tests-common/goldenfiles/select_order_by_album_artist_name.json +++ b/crates/tests/tests-common/goldenfiles/select_order_by_album_artist_name.json @@ -52,7 +52,7 @@ "collection_relationships": { "AlbumArtist": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "object", "target_collection": "Artist", @@ -60,7 +60,7 @@ }, "TrackAlbum": { "column_mapping": { - "AlbumId": "AlbumId" + "AlbumId": ["AlbumId"] }, "relationship_type": "object", "target_collection": "Album", diff --git a/crates/tests/tests-common/goldenfiles/select_order_by_artist_album_count.json b/crates/tests/tests-common/goldenfiles/select_order_by_artist_album_count.json index d25c2cedd..c9cf0dfee 100644 --- a/crates/tests/tests-common/goldenfiles/select_order_by_artist_album_count.json +++ b/crates/tests/tests-common/goldenfiles/select_order_by_artist_album_count.json @@ -15,7 +15,10 @@ { "order_direction": "desc", "target": { - "type": "star_count_aggregate", + "type": "aggregate", + "aggregate": { + "type": "star_count" + }, "path": [ { "relationship": "ArtistAlbums", @@ -35,7 +38,7 @@ "collection_relationships": { "ArtistAlbums": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album", diff --git a/crates/tests/tests-common/goldenfiles/select_order_by_artist_album_count_agg.json b/crates/tests/tests-common/goldenfiles/select_order_by_artist_album_count_agg.json index bcfd5b633..c56a1c428 100644 --- a/crates/tests/tests-common/goldenfiles/select_order_by_artist_album_count_agg.json +++ b/crates/tests/tests-common/goldenfiles/select_order_by_artist_album_count_agg.json @@ -13,9 +13,12 @@ "elements": [ { "target": { - "type": "single_column_aggregate", - "column": "AlbumId", - "function": "count", + "type": "aggregate", + "aggregate": { + "type": "single_column", + "column": "AlbumId", + "function": "count" + }, "path": [ { "relationship": "ArtistAlbum", @@ -37,7 +40,7 @@ "collection_relationships": { "ArtistAlbum": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album", diff --git a/crates/tests/tests-common/goldenfiles/select_order_by_artist_name.json b/crates/tests/tests-common/goldenfiles/select_order_by_artist_name.json index b874669e4..103100299 100644 --- a/crates/tests/tests-common/goldenfiles/select_order_by_artist_name.json +++ b/crates/tests/tests-common/goldenfiles/select_order_by_artist_name.json @@ -45,7 +45,7 @@ "collection_relationships": { "AlbumArtist": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "object", "target_collection": "Artist", diff --git a/crates/tests/tests-common/goldenfiles/select_order_by_artist_name_with_name.json b/crates/tests/tests-common/goldenfiles/select_order_by_artist_name_with_name.json index 81e27722c..256052a51 100644 --- a/crates/tests/tests-common/goldenfiles/select_order_by_artist_name_with_name.json +++ b/crates/tests/tests-common/goldenfiles/select_order_by_artist_name_with_name.json @@ -58,7 +58,7 @@ "collection_relationships": { "AlbumArtist": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "object", "target_collection": "Artist", diff --git a/crates/tests/tests-common/goldenfiles/select_track_order_by_artist_id_and_album_title.json b/crates/tests/tests-common/goldenfiles/select_track_order_by_artist_id_and_album_title.json index e23078da4..09cac14b6 100644 --- a/crates/tests/tests-common/goldenfiles/select_track_order_by_artist_id_and_album_title.json +++ b/crates/tests/tests-common/goldenfiles/select_track_order_by_artist_id_and_album_title.json @@ -61,7 +61,7 @@ "collection_relationships": { "TrackAlbum": { "column_mapping": { - "AlbumId": "AlbumId" + "AlbumId": ["AlbumId"] }, "relationship_type": "object", "target_collection": "Album", diff --git a/crates/tests/tests-common/goldenfiles/select_where_album_id_equals_self.json b/crates/tests/tests-common/goldenfiles/select_where_album_id_equals_self.json index cf3bc11bf..19674eb75 100644 --- a/crates/tests/tests-common/goldenfiles/select_where_album_id_equals_self.json +++ b/crates/tests/tests-common/goldenfiles/select_where_album_id_equals_self.json @@ -27,11 +27,8 @@ "operator": "_eq", "value": { "type": "column", - "column": { - "type": "column", - "name": "AlbumId", - "path": [] - } + "name": "AlbumId", + "path": [] } }, { diff --git a/crates/tests/tests-common/goldenfiles/select_where_album_id_equals_self_nested_object_relationship.json b/crates/tests/tests-common/goldenfiles/select_where_album_id_equals_self_nested_object_relationship.json index 3aea7084f..b87554c33 100644 --- a/crates/tests/tests-common/goldenfiles/select_where_album_id_equals_self_nested_object_relationship.json +++ b/crates/tests/tests-common/goldenfiles/select_where_album_id_equals_self_nested_object_relationship.json @@ -79,28 +79,25 @@ "operator": "_gt", "value": { "type": "column", - "column": { - "type": "column", - "name": "ArtistId", - "path": [ - { - "relationship": "TrackToAlbum", - "arguments": {}, - "predicate": { - "type": "and", - "expressions": [] - } - }, - { - "relationship": "AlbumToArtist", - "arguments": {}, - "predicate": { - "type": "and", - "expressions": [] - } + "name": "ArtistId", + "path": [ + { + "relationship": "TrackToAlbum", + "arguments": {}, + "predicate": { + "type": "and", + "expressions": [] } - ] - } + }, + { + "relationship": "AlbumToArtist", + "arguments": {}, + "predicate": { + "type": "and", + "expressions": [] + } + } + ] } } }, @@ -108,7 +105,7 @@ "collection_relationships": { "TrackToAlbum": { "column_mapping": { - "AlbumId": "AlbumId" + "AlbumId": ["AlbumId"] }, "relationship_type": "object", "target_collection": "Album", @@ -116,7 +113,7 @@ }, "AlbumToArtist": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "object", "target_collection": "Artist", diff --git a/crates/tests/tests-common/goldenfiles/select_where_array_relationship.json b/crates/tests/tests-common/goldenfiles/select_where_array_relationship.json index 9183cfe67..edbad921c 100644 --- a/crates/tests/tests-common/goldenfiles/select_where_array_relationship.json +++ b/crates/tests/tests-common/goldenfiles/select_where_array_relationship.json @@ -36,25 +36,23 @@ } }, "predicate": { - "type": "binary_comparison_operator", - "column": { - "type": "column", - "name": "Title", - "path": [ - { - "relationship": "Artist_Albums", - "arguments": {}, - "predicate": { - "type": "and", - "expressions": [] - } - } - ] + "type": "exists", + "in_collection": { + "type": "related", + "relationship": "Artist_Albums", + "arguments": {} }, - "operator": "_like", - "value": { - "type": "scalar", - "value": "Supernatural" + "predicate": { + "type": "binary_comparison_operator", + "column": { + "type": "column", + "name": "Title" + }, + "operator": "_like", + "value": { + "type": "scalar", + "value": "Supernatural" + } } }, "order_by": { @@ -75,7 +73,7 @@ "Artist_Albums": { "arguments": {}, "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album" diff --git a/crates/tests/tests-common/goldenfiles/select_where_in_column.json b/crates/tests/tests-common/goldenfiles/select_where_in_column.json index c732ba934..870ae51ea 100644 --- a/crates/tests/tests-common/goldenfiles/select_where_in_column.json +++ b/crates/tests/tests-common/goldenfiles/select_where_in_column.json @@ -19,11 +19,8 @@ "operator": "_in", "value": { "type": "column", - "column": { - "type": "column", - "name": "series", - "path": [] - } + "name": "series", + "path": [] } } }, diff --git a/crates/tests/tests-common/goldenfiles/select_where_related_exists.json b/crates/tests/tests-common/goldenfiles/select_where_related_exists.json index 256a0998c..509328521 100644 --- a/crates/tests/tests-common/goldenfiles/select_where_related_exists.json +++ b/crates/tests/tests-common/goldenfiles/select_where_related_exists.json @@ -74,7 +74,7 @@ "Artist_Albums": { "arguments": {}, "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album" diff --git a/crates/tests/tests-common/goldenfiles/select_where_unrelated_exists.json b/crates/tests/tests-common/goldenfiles/select_where_unrelated_exists.json index 1616f8c34..4c4be2785 100644 --- a/crates/tests/tests-common/goldenfiles/select_where_unrelated_exists.json +++ b/crates/tests/tests-common/goldenfiles/select_where_unrelated_exists.json @@ -35,17 +35,15 @@ { "type": "binary_comparison_operator", "column": { - "type": "root_collection_column", + "type": "column", "name": "ArtistId" }, "operator": "_eq", "value": { "type": "column", - "column": { - "type": "column", - "name": "ArtistId", - "path": [] - } + "name": "ArtistId", + "path": [], + "scope": 1 } } ] diff --git a/crates/tests/tests-common/goldenfiles/sorting_by_nested_relationship_column_with_predicate.json b/crates/tests/tests-common/goldenfiles/sorting_by_nested_relationship_column_with_predicate.json index 410ab0dc2..4ae315f14 100644 --- a/crates/tests/tests-common/goldenfiles/sorting_by_nested_relationship_column_with_predicate.json +++ b/crates/tests/tests-common/goldenfiles/sorting_by_nested_relationship_column_with_predicate.json @@ -66,7 +66,7 @@ "collection_relationships": { "AlbumArtist": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "object", "target_collection": "Artist", @@ -74,7 +74,7 @@ }, "TrackAlbum": { "column_mapping": { - "AlbumId": "AlbumId" + "AlbumId": ["AlbumId"] }, "relationship_type": "object", "target_collection": "Album", diff --git a/crates/tests/tests-common/goldenfiles/sorting_by_nested_relationship_column_with_predicate_exists.json b/crates/tests/tests-common/goldenfiles/sorting_by_nested_relationship_column_with_predicate_exists.json index 3fe436185..deea0f950 100644 --- a/crates/tests/tests-common/goldenfiles/sorting_by_nested_relationship_column_with_predicate_exists.json +++ b/crates/tests/tests-common/goldenfiles/sorting_by_nested_relationship_column_with_predicate_exists.json @@ -74,7 +74,7 @@ "collection_relationships": { "AlbumArtist": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "object", "target_collection": "Artist", @@ -82,7 +82,7 @@ }, "TrackAlbum": { "column_mapping": { - "AlbumId": "AlbumId" + "AlbumId": ["AlbumId"] }, "relationship_type": "object", "target_collection": "Album", diff --git a/crates/tests/tests-common/goldenfiles/sorting_by_nested_relationship_count.json b/crates/tests/tests-common/goldenfiles/sorting_by_nested_relationship_count.json index 2d257dd0d..53f1893b3 100644 --- a/crates/tests/tests-common/goldenfiles/sorting_by_nested_relationship_count.json +++ b/crates/tests/tests-common/goldenfiles/sorting_by_nested_relationship_count.json @@ -69,7 +69,10 @@ { "order_direction": "desc", "target": { - "type": "star_count_aggregate", + "type": "aggregate", + "aggregate": { + "type": "star_count" + }, "path": [ { "relationship": "ArtistAlbums", @@ -107,7 +110,7 @@ "collection_relationships": { "ArtistAlbums": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album", @@ -115,7 +118,7 @@ }, "AlbumTracks": { "column_mapping": { - "AlbumId": "AlbumId" + "AlbumId": ["AlbumId"] }, "relationship_type": "array", "target_collection": "Track", diff --git a/crates/tests/tests-common/goldenfiles/sorting_by_relationship_count_with_predicate.json b/crates/tests/tests-common/goldenfiles/sorting_by_relationship_count_with_predicate.json index 634fdc63b..b487bf3d8 100644 --- a/crates/tests/tests-common/goldenfiles/sorting_by_relationship_count_with_predicate.json +++ b/crates/tests/tests-common/goldenfiles/sorting_by_relationship_count_with_predicate.json @@ -15,7 +15,10 @@ { "order_direction": "desc", "target": { - "type": "star_count_aggregate", + "type": "aggregate", + "aggregate": { + "type": "star_count" + }, "path": [ { "relationship": "ArtistAlbums", @@ -65,7 +68,7 @@ "collection_relationships": { "ArtistAlbums": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album", @@ -73,7 +76,7 @@ }, "AlbumTracks": { "column_mapping": { - "AlbumId": "AlbumId" + "AlbumId": ["AlbumId"] }, "relationship_type": "array", "target_collection": "Track", diff --git a/crates/tests/tests-common/goldenfiles/very_nested_recursive_relationship.json b/crates/tests/tests-common/goldenfiles/very_nested_recursive_relationship.json index 7724caef9..db2e076df 100644 --- a/crates/tests/tests-common/goldenfiles/very_nested_recursive_relationship.json +++ b/crates/tests/tests-common/goldenfiles/very_nested_recursive_relationship.json @@ -110,7 +110,7 @@ "collection_relationships": { "ArtistAlbums": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album", @@ -118,7 +118,7 @@ }, "AlbumArtist": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "object", "target_collection": "Artist", diff --git a/crates/tests/tests-common/src/router.rs b/crates/tests/tests-common/src/router.rs index 704c638a8..5bb233d97 100644 --- a/crates/tests/tests-common/src/router.rs +++ b/crates/tests/tests-common/src/router.rs @@ -21,9 +21,9 @@ pub async fn create_router( )]); let setup = PostgresSetup::new(environment); - let state = ndc_sdk::default_main::init_server_state(setup, &absolute_configuration_directory) + let state = ndc_sdk::state::init_server_state(setup, &absolute_configuration_directory) .await .unwrap(); - ndc_sdk::default_main::create_router(state, None) + ndc_sdk::default_main::create_router(state, None, None) }