From 4e3512c33a43089c9fb48f1b9f47ef8e14a939cb Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 25 Dec 2024 03:51:02 -0400 Subject: [PATCH 01/49] Update to ndc-models 0.2.0 Note we are pointing to a specific sdk revision We should tag a release and point to that --- Cargo.lock | 377 +++++++++++++++++++++++++++++++++++++++++++++-------- Cargo.toml | 13 +- 2 files changed, 328 insertions(+), 62 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 93a7a8875..5edeb789e 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.8" @@ -3250,6 +3442,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" @@ -3269,7 +3470,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]] @@ -3282,6 +3494,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.16.0" @@ -3325,12 +3547,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", @@ -3507,6 +3729,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" @@ -3543,10 +3776,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", @@ -3555,7 +3788,7 @@ dependencies = [ "rustls-pemfile 2.1.3", "rustls-pki-types", "tokio", - "tokio-rustls", + "tokio-rustls 0.25.0", "tokio-stream", "tower", "tower-layer", @@ -3593,8 +3826,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", @@ -4053,6 +4286,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 b201b351a..3e33ea629 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" From e3478277adf93e4d1f9abb03cb4641bc38288bc7 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 25 Dec 2024 04:04:50 -0400 Subject: [PATCH 02/49] scalar type representation is no longer optional. If the configuration does not include a type representation, we infer one based on the scalar type name. We default to JSON representation if we don't recognize the scalar type. The mapping is pulled from the default introspection configuration. This should enable a smooth upgrade, but we may need to publish a new version of the configuration with a mechanism to guarantee type representations, later. --- crates/configuration/src/version3/mod.rs | 38 ++++++++++++++++++- .../src/version4/to_runtime_configuration.rs | 30 +++++++++++++-- .../src/version5/to_runtime_configuration.rs | 30 +++++++++++++-- .../metadata/src/metadata/database.rs | 2 +- 4 files changed, 89 insertions(+), 11 deletions(-) diff --git a/crates/configuration/src/version3/mod.rs b/crates/configuration/src/version3/mod.rs index 1dd7cc77b..08a2155bb 100644 --- a/crates/configuration/src/version3/mod.rs +++ b/crates/configuration/src/version3/mod.rs @@ -5,7 +5,7 @@ pub mod connection_settings; pub mod metadata; pub(crate) mod options; -use ndc_models::{self as models, CollectionName, TypeName}; +use ndc_models::{self as models, CollectionName, ScalarTypeName, TypeName}; use std::borrow::Cow; use std::collections::{BTreeMap, BTreeSet, HashSet}; use std::path::Path; @@ -714,7 +714,10 @@ fn convert_scalar_types( .cloned() .unwrap_or(BTreeMap::new()), - type_representation: representations.0.get(&t).cloned(), + type_representation: convert_or_infer_type_representation( + representations.0.get(&t).cloned(), + &t, + ), }, ) }) @@ -722,6 +725,37 @@ fn convert_scalar_types( ) } +/// Infer scalar type representation from scalar type name, if necessary. Defaults to JSON representation +fn convert_or_infer_type_representation( + representation: Option, + scalar_type_name: &ScalarTypeName, +) -> query_engine_metadata::metadata::TypeRepresentation { + if let Some(representation) = representation { + representation + } else { + match scalar_type_name.as_str() { + "bit" => query_engine_metadata::metadata::TypeRepresentation::String, + "bool" => query_engine_metadata::metadata::TypeRepresentation::Boolean, + "bpchar" | "char" | "varchar" | "text" => { + query_engine_metadata::metadata::TypeRepresentation::String + } + "date" => query_engine_metadata::metadata::TypeRepresentation::Date, + "float4" => query_engine_metadata::metadata::TypeRepresentation::Float32, + "float8" => query_engine_metadata::metadata::TypeRepresentation::Float64, + "int2" => query_engine_metadata::metadata::TypeRepresentation::Int16, + "int4" => query_engine_metadata::metadata::TypeRepresentation::Int32, + "int8" => query_engine_metadata::metadata::TypeRepresentation::Int64AsString, + "numeric" => query_engine_metadata::metadata::TypeRepresentation::BigDecimalAsString, + "time" => query_engine_metadata::metadata::TypeRepresentation::Time, + "timestamp" => query_engine_metadata::metadata::TypeRepresentation::Timestamp, + "timestamptz" => query_engine_metadata::metadata::TypeRepresentation::Timestamptz, + "timetz" => query_engine_metadata::metadata::TypeRepresentation::Timetz, + "uuid" => query_engine_metadata::metadata::TypeRepresentation::UUID, + _ => query_engine_metadata::metadata::TypeRepresentation::Json, + } + } +} + fn convert_aggregate_functions( aggregate_functions: metadata::AggregateFunctions, ) -> BTreeMap< diff --git a/crates/configuration/src/version4/to_runtime_configuration.rs b/crates/configuration/src/version4/to_runtime_configuration.rs index b4fa402db..46d1b205e 100644 --- a/crates/configuration/src/version4/to_runtime_configuration.rs +++ b/crates/configuration/src/version4/to_runtime_configuration.rs @@ -3,7 +3,10 @@ use std::collections::BTreeMap; +use ndc_models::ScalarTypeName; + use super::metadata; +use super::options::IntrospectionOptions; use super::ParsedConfiguration; use crate::environment::Environment; use crate::error::MakeRuntimeConfigurationError; @@ -58,7 +61,7 @@ fn convert_scalar_types( .into_iter() .map(|(scalar_type_name, scalar_type)| { ( - scalar_type_name, + scalar_type_name.clone(), query_engine_metadata::metadata::ScalarType { type_name: scalar_type.type_name, schema_name: Some(scalar_type.schema_name), @@ -73,9 +76,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: convert_or_infer_type_representation( + scalar_type.type_representation, + &scalar_type_name, + ), }, ) }) @@ -83,6 +87,24 @@ fn convert_scalar_types( ) } +/// Infer scalar type representation from scalar type name, if necessary. Defaults to JSON representation +fn convert_or_infer_type_representation( + representation: Option, + scalar_type_name: &ScalarTypeName, +) -> query_engine_metadata::metadata::TypeRepresentation { + if let Some(representation) = representation { + convert_type_representation(representation) + } else if let Some(representation) = IntrospectionOptions::default() + .type_representations + .0 + .get(scalar_type_name) + { + convert_type_representation(representation.to_owned()) + } else { + query_engine_metadata::metadata::TypeRepresentation::Json + } +} + fn convert_aggregate_function( aggregate_function: metadata::AggregateFunction, ) -> query_engine_metadata::metadata::AggregateFunction { diff --git a/crates/configuration/src/version5/to_runtime_configuration.rs b/crates/configuration/src/version5/to_runtime_configuration.rs index 222f4364c..00457f850 100644 --- a/crates/configuration/src/version5/to_runtime_configuration.rs +++ b/crates/configuration/src/version5/to_runtime_configuration.rs @@ -3,7 +3,10 @@ use std::collections::BTreeMap; +use ndc_models::ScalarTypeName; + use super::metadata; +use super::options::IntrospectionOptions; use super::ParsedConfiguration; use crate::environment::Environment; use crate::error::MakeRuntimeConfigurationError; @@ -58,7 +61,7 @@ fn convert_scalar_types( .into_iter() .map(|(scalar_type_name, scalar_type)| { ( - scalar_type_name, + scalar_type_name.clone(), query_engine_metadata::metadata::ScalarType { type_name: scalar_type.type_name, schema_name: Some(scalar_type.schema_name), @@ -73,9 +76,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: convert_or_infer_type_representation( + scalar_type.type_representation, + &scalar_type_name, + ), }, ) }) @@ -83,6 +87,24 @@ fn convert_scalar_types( ) } +/// Infer scalar type representation from scalar type name, if necessary. Defaults to JSON representation +fn convert_or_infer_type_representation( + representation: Option, + scalar_type_name: &ScalarTypeName, +) -> query_engine_metadata::metadata::TypeRepresentation { + if let Some(representation) = representation { + convert_type_representation(representation) + } else if let Some(representation) = IntrospectionOptions::default() + .type_representations + .0 + .get(scalar_type_name) + { + convert_type_representation(representation.to_owned()) + } else { + query_engine_metadata::metadata::TypeRepresentation::Json + } +} + fn convert_aggregate_function( aggregate_function: metadata::AggregateFunction, ) -> query_engine_metadata::metadata::AggregateFunction { diff --git a/crates/query-engine/metadata/src/metadata/database.rs b/crates/query-engine/metadata/src/metadata/database.rs index 21e07de38..20ac3682c 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. From d3359fddd8efaf6bf164d8e69c2aab92e85b2723 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 25 Dec 2024 04:08:18 -0400 Subject: [PATCH 03/49] We assume we don't support any capability we did not previously support. Note! This is a regression with regards to named scopes, which replace the previously supported RootTableColumn. There was technically no way to consume this api from the engine, so this is not a major issue, and will be addressed in an upcoming PR. --- crates/connectors/ndc-postgres/src/capabilities.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/crates/connectors/ndc-postgres/src/capabilities.rs b/crates/connectors/ndc-postgres/src/capabilities.rs index 91a42fa0b..5fed91d81 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, + nested_collections: None, }, }, mutation: models::MutationCapabilities { @@ -28,6 +37,7 @@ pub fn get_capabilities() -> models::Capabilities { relationships: Some(models::RelationshipCapabilities { relation_comparisons: Some(models::LeafCapability {}), order_by_aggregate: Some(models::LeafCapability {}), + nested: None, }), } } From f1aac02b2c996782c2d559680eb8d37f366fa80c Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 25 Dec 2024 04:49:26 -0400 Subject: [PATCH 04/49] Foreign Keys moved from collections to object types. Type representations are no longer optional Schema Response now includes a reference to the scalar type to be used for count results. AggregateFunctionDefinition is now an enum, so we map based on function name. Note! We are currently lying by omission about the return types. Postgres aggregates will return NULL if aggregating over no rows, except COUNT. We should have a discussion about wether we want to change aggregate function definitions to reflect this behavior, whether all these scalars will be implicitly nullable, or whether we want to change the SQL using COALESCE to default to some value when no rows are present. Arguably, there's no proper MAX, MIN, or AVG default values. As for SUM, ndc-test expects all SUM return values to be either represented as 64 bit integers or 64 bit floats. Postgres has types like INTERVAL, which is represented as a string, and can be aggregated with SUM. We need to discuss whether any of the above needs to be revisited. We cannot represent intervals as float64 or int64. --- .../connectors/ndc-postgres/src/connector.rs | 4 +- .../connectors/ndc-postgres/src/schema/mod.rs | 129 +++++++++++------- .../src/schema/mutation/helpers.rs | 5 +- .../ndc-postgres/src/schema/mutation/v2.rs | 1 + 4 files changed, 86 insertions(+), 53 deletions(-) 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..df0da1bde 100644 --- a/crates/connectors/ndc-postgres/src/schema/mod.rs +++ b/crates/connectors/ndc-postgres/src/schema/mod.rs @@ -30,25 +30,32 @@ 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)| { ( 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() { + "max" => models::AggregateFunctionDefinition::Max, + "min" => models::AggregateFunctionDefinition::Min, + "sum" => models::AggregateFunctionDefinition::Sum { + result_type: function_definition.return_type.clone().into(), + }, + "average" => 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(), + }), + }, }, }, ) @@ -119,42 +126,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 +152,6 @@ pub fn get_schema( .collect(), collection_type: name.as_str().into(), uniqueness_constraints: BTreeMap::new(), - foreign_keys: BTreeMap::new(), }) .collect(); @@ -209,6 +179,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 +242,7 @@ pub fn get_schema( ) }) .collect(), + foreign_keys: BTreeMap::new(), }; (nq_name.as_str().into(), object_type) }) @@ -263,6 +270,7 @@ pub fn get_schema( ) }) .collect(), + foreign_keys: BTreeMap::new(), }; (nq_name.as_str().into(), object_type) }) @@ -291,6 +299,7 @@ pub fn get_schema( ) }) .collect(), + foreign_keys: BTreeMap::new(), }; (ctype_name.as_str().into(), object_type) }) @@ -351,12 +360,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(), }, ); From 86d601ea9796a95def4d8b0bdddcb0c582d0cd55 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 25 Dec 2024 07:05:52 -0400 Subject: [PATCH 05/49] Count aggregates now take an expression instead of a column reference, so that we may count nested properties using field_path --- crates/query-engine/sql/src/sql/ast.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 From c5cdb1f5935621ff00cb2b2053d5c7384d0ac2c2 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 25 Dec 2024 08:14:16 -0400 Subject: [PATCH 06/49] remove todo --- .../src/translation/mutation/v1/insert.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) 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)?; From 6aa62e1ff44be310cf9efa4eef766a6431203114 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 25 Dec 2024 08:16:19 -0400 Subject: [PATCH 07/49] remove todo, jandle a couple additional cases as errors/unsupported --- .../src/translation/mutation/translate.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) 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) } From f2ba32425d0e72655ca40c72b7cc0454db63a617 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 25 Dec 2024 08:16:38 -0400 Subject: [PATCH 08/49] add additional error types --- .../translation/src/translation/error.rs | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/crates/query-engine/translation/src/translation/error.rs b/crates/query-engine/translation/src/translation/error.rs index 29f2307bf..0c13171a3 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,39 @@ pub enum Error { field_name: models::FieldName, actual_type: Type, }, + MutationVersionNotSet, + MissingAggregateFunctionForScalar { + scalar: models::ScalarTypeName, + function: models::AggregateFunctionName, + }, } /// Capabilities we don't currently support. #[derive(Debug, Clone)] pub enum UnsupportedCapabilities { FieldArguments, + NestedRelationships, + NestedCollectionFields, + NestedArrays, + ArrayComparison, + NestedScalarCollection, } 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") + } } } } @@ -93,6 +118,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 +230,11 @@ 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:?}" + ), } } } From 52292f6df6802559d3d8a5b5bf54fbc419260fcd Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 25 Dec 2024 08:22:19 -0400 Subject: [PATCH 09/49] add test for aggregate of nested field --- .../ndc-postgres/src/capabilities.rs | 2 +- .../configuration.json | 417 ++++++++++++++++++ .../request.json | 16 + ...t_composite_column_nested_field_count.snap | 32 ++ .../query-engine/translation/tests/tests.rs | 8 + 5 files changed, 474 insertions(+), 1 deletion(-) create mode 100644 crates/query-engine/translation/tests/goldenfiles/select_composite_column_nested_field_count/configuration.json create mode 100644 crates/query-engine/translation/tests/goldenfiles/select_composite_column_nested_field_count/request.json create mode 100644 crates/query-engine/translation/tests/snapshots/tests__select_composite_column_nested_field_count.snap diff --git a/crates/connectors/ndc-postgres/src/capabilities.rs b/crates/connectors/ndc-postgres/src/capabilities.rs index 5fed91d81..0564c7636 100644 --- a/crates/connectors/ndc-postgres/src/capabilities.rs +++ b/crates/connectors/ndc-postgres/src/capabilities.rs @@ -26,7 +26,7 @@ pub fn get_capabilities() -> models::Capabilities { nested_arrays: None, }), order_by: Some(models::LeafCapability {}), - aggregates: None, + aggregates: Some(models::LeafCapability {}), nested_collections: None, }, }, 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..5f4f47180 --- /dev/null +++ b/crates/query-engine/translation/tests/goldenfiles/select_composite_column_nested_field_count/configuration.json @@ -0,0 +1,417 @@ +{ + "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/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..16d66bf98 --- /dev/null +++ b/crates/query-engine/translation/tests/snapshots/tests__select_composite_column_nested_field_count.snap @@ -0,0 +1,32 @@ +--- +source: crates/query-engine/translation/tests/tests.rs +assertion_line: 62 +expression: result +snapshot_kind: text +--- +SELECT + coalesce(json_agg(row_to_json("%3_universe")), '[]') AS "universe" +FROM + ( + SELECT + * + FROM + ( + SELECT + coalesce(row_to_json("%5_aggregates"), '[]') AS "aggregates" + FROM + ( + SELECT + COUNT(DISTINCT ("%2_persons"."person")."age") AS "different ages" + FROM + ( + SELECT + "%1_persons".* + FROM + "public"."persons" AS "%1_persons" + ) AS "%2_persons" + ) AS "%5_aggregates" + ) AS "%5_aggregates" + ) AS "%3_universe"; + +{} diff --git a/crates/query-engine/translation/tests/tests.rs b/crates/query-engine/translation/tests/tests.rs index 204730350..3e233d598 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") From fb79bfb12471d817d3f3bc50eac4d6a645e61eb9 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 25 Dec 2024 08:27:13 -0400 Subject: [PATCH 10/49] relationship mapping now have an array on the right-hand side, so foreign key may be on a nested field. for now, we do not suport relationships.nested, so erroring out in that case --- .../translation/src/translation/query/relationships.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) 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( From 1240ffb0b2ab99bdaecf916a916ec457a1694093 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 25 Dec 2024 08:27:41 -0400 Subject: [PATCH 11/49] scalar type no longer optional --- crates/query-engine/translation/src/translation/helpers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/query-engine/translation/src/translation/helpers.rs b/crates/query-engine/translation/src/translation/helpers.rs index f5f8aec07..6cc936643 100644 --- a/crates/query-engine/translation/src/translation/helpers.rs +++ b/crates/query-engine/translation/src/translation/helpers.rs @@ -424,7 +424,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 From 7a227e8f32441a3f7021b08b0512bf74614655b4 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 25 Dec 2024 08:28:27 -0400 Subject: [PATCH 12/49] nested field collection not supported, add error handling --- .../translation/src/translation/query/fields.rs | 6 ++++++ 1 file changed, 6 insertions(+) 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 From 3647605e9106ef5a5582d67ac0e53e286ff61251 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 25 Dec 2024 08:30:04 -0400 Subject: [PATCH 13/49] update filtering, aggregates, sorting, to 0.2.0 --- .../src/translation/query/aggregates.rs | 51 ++-- .../src/translation/query/filtering.rs | 245 ++++++++++++++---- .../src/translation/query/sorting.rs | 140 +++++++--- 3 files changed, 333 insertions(+), 103 deletions(-) diff --git a/crates/query-engine/translation/src/translation/query/aggregates.rs b/crates/query-engine/translation/src/translation/query/aggregates.rs index 2885628d4..2cf75e10a 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,47 @@ 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()), + }, + ), + ); + sql::ast::Expression::FunctionCall { + function: sql::ast::Function::Unknown(function.to_string()), + args: vec![column], + } + } models::Aggregate::StarCount {} => { sql::ast::Expression::Count(sql::ast::CountType::Star) } diff --git a/crates/query-engine/translation/src/translation/query/filtering.rs b/crates/query-engine/translation/src/translation/query/filtering.rs index 73b1e3763..53e37e88e 100644 --- a/crates/query-engine/translation/src/translation/query/filtering.rs +++ b/crates/query-engine/translation/src/translation/query/filtering.rs @@ -117,13 +117,33 @@ pub fn translate_expression_with_joins( joins.extend(left_joins); match value { - models::ComparisonValue::Column { column } => { - let (right, right_joins) = translate_comparison_target( + models::ComparisonValue::Column { + path, + name, + arguments: _, + field_path, + scope: _, + } => { + let (table_ref, right_joins) = translate_comparison_pathelements( env, state, root_and_current_tables, - column, + 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)]; @@ -263,6 +283,9 @@ pub fn translate_expression_with_joins( )) } }, + models::Expression::ArrayComparison { .. } => Err(Error::CapabilityNotSupported( + UnsupportedCapabilities::ArrayComparison, + )), } } @@ -321,6 +344,7 @@ fn translate_comparison_pathelements( relationship, predicate, arguments, + field_path: _, }| { // get the relationship table let relationship_name = &relationship; @@ -441,11 +465,10 @@ fn translate_comparison_target( 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) = (root_and_current_tables.current_table.clone(), vec![]); // get the unrelated table information from the metadata. let collection_info = env.lookup_fields_info(&table_ref.source)?; @@ -462,26 +485,72 @@ fn translate_comparison_target( joins, )) } + ndc_models::ComparisonTarget::Aggregate { path, aggregate } => { + let (table_ref, joins) = + translate_comparison_pathelements(env, state, root_and_current_tables, path)?; - // 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)?; + match aggregate { + ndc_models::Aggregate::ColumnCount { + column, + arguments: _, + field_path, + distinct, + } => { + let collection_info = env.lookup_fields_info(&table_ref.source)?; + let ColumnInfo { name, .. } = collection_info.lookup_column(column)?; + + let column_reference = wrap_in_field_path( + &field_path.into(), + sql::ast::Expression::ColumnReference( + sql::ast::ColumnReference::TableColumn { + table: table_ref.reference.clone(), + name, + }, + ), + ); - // find the requested column in the tables columns. - let ColumnInfo { name, .. } = collection_info.lookup_column(name)?; + Ok(( + sql::ast::Expression::Count(if *distinct { + sql::ast::CountType::Distinct(Box::new(column_reference)) + } else { + sql::ast::CountType::Simple(Box::new(column_reference)) + }), + joins, + )) + } + ndc_models::Aggregate::SingleColumn { + column, + arguments: _, + field_path, + function, + } => { + let collection_info = env.lookup_fields_info(&table_ref.source)?; + let ColumnInfo { name, .. } = collection_info.lookup_column(column)?; + + let column_reference = wrap_in_field_path( + &field_path.into(), + sql::ast::Expression::ColumnReference( + sql::ast::ColumnReference::TableColumn { + table: table_ref.reference.clone(), + name, + }, + ), + ); - Ok(( - wrap_in_field_path( - &field_path.into(), - sql::ast::Expression::ColumnReference(sql::ast::ColumnReference::TableColumn { - table: root_table.reference.clone(), - name, - }), - ), - vec![], - )) + Ok(( + sql::ast::Expression::FunctionCall { + function: sql::ast::Function::Unknown(function.to_string()), + args: vec![column_reference], + }, + joins, + )) + } + // todo: is this sound? this count is not targeted, but maybe that is fine? + ndc_models::Aggregate::StarCount {} => Ok(( + sql::ast::Expression::Count(sql::ast::CountType::Star), + joins, + )), + } } } } @@ -495,8 +564,30 @@ fn translate_comparison_value( 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::Column { + path, + name, + arguments: _, + field_path, + scope: _, + } => { + let (table_ref, joins) = + translate_comparison_pathelements(env, state, root_and_current_tables, 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: table_ref.reference.clone(), + name, + }), + ), + joins, + )) } models::ComparisonValue::Scalar { value: json_value } => { Ok((values::translate(env, state, json_value, typ)?, vec![])) @@ -575,6 +666,7 @@ pub fn translate_exists_in_collection( models::ExistsInCollection::Related { relationship, arguments, + field_path: _, } => { // get the relationship table let relationship = env.lookup_relationship(&relationship)?; @@ -741,6 +833,13 @@ 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, + )), } } @@ -751,44 +850,84 @@ fn get_comparison_target_type( 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(&root_and_current_tables.current_table.source)? + .lookup_column(name)?; - get_column_scalar_type_name(env, &column.r#type, &mut field_path) + println!("Field name: {name:?}, Column Info: {column:?}"); + + 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(&root_and_current_tables.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/sorting.rs b/crates/query-engine/translation/src/translation/query/sorting.rs index 32e4cd7b2..448a63623 100644 --- a/crates/query-engine/translation/src/translation/query/sorting.rs +++ b/crates/query-engine/translation/src/translation/query/sorting.rs @@ -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 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 => { + sql::ast::Expression::Count(sql::ast::CountType::Star) + } + 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 +580,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, @@ -689,7 +745,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 +754,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 +776,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 + }), }) } } From 89c17fa5241461343b6745237369c5adc54ebe7b Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 25 Dec 2024 08:54:17 -0400 Subject: [PATCH 14/49] Update translation test configurations to v5 Add reference to configuration.schema.json Add missing type representations Add missing scalar types (v4 did not require all referenced scalar types to be defined) --- .../configuration.json | 4 +++- .../configuration.json | 12 +++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/crates/query-engine/translation/tests/goldenfiles/aggregate_limit_offset_order_by/configuration.json b/crates/query-engine/translation/tests/goldenfiles/aggregate_limit_offset_order_by/configuration.json index 9101ba72c..511337cf9 100644 --- a/crates/query-engine/translation/tests/goldenfiles/aggregate_limit_offset_order_by/configuration.json +++ b/crates/query-engine/translation/tests/goldenfiles/aggregate_limit_offset_order_by/configuration.json @@ -94,7 +94,9 @@ } }, "uniquenessConstraints": { - "PK_Invoice": ["InvoiceId"] + "PK_Invoice": [ + "InvoiceId" + ] }, "foreignRelations": { "FK_InvoiceCustomerId": { diff --git a/crates/query-engine/translation/tests/goldenfiles/select_where_album_id_equals_self_nested_object_relationship/configuration.json b/crates/query-engine/translation/tests/goldenfiles/select_where_album_id_equals_self_nested_object_relationship/configuration.json index d704c0ab8..bb83921ef 100644 --- a/crates/query-engine/translation/tests/goldenfiles/select_where_album_id_equals_self_nested_object_relationship/configuration.json +++ b/crates/query-engine/translation/tests/goldenfiles/select_where_album_id_equals_self_nested_object_relationship/configuration.json @@ -46,7 +46,9 @@ } }, "uniquenessConstraints": { - "PK_Album": ["AlbumId"] + "PK_Album": [ + "AlbumId" + ] }, "foreignRelations": { "FK_AlbumArtistId": { @@ -80,7 +82,9 @@ } }, "uniquenessConstraints": { - "PK_Artist": ["ArtistId"] + "PK_Artist": [ + "ArtistId" + ] }, "foreignRelations": {}, "description": null @@ -163,7 +167,9 @@ } }, "uniquenessConstraints": { - "PK_Track": ["TrackId"] + "PK_Track": [ + "TrackId" + ] }, "foreignRelations": { "FK_TrackAlbumId": { From 7eaa240035a1f06c1b4fff3add3cf77429fa436e Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 25 Dec 2024 09:11:47 -0400 Subject: [PATCH 15/49] add reference to query/mutation request schema json --- .../goldenfiles/select_array_column_reverse/request.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/query-engine/translation/tests/goldenfiles/select_array_column_reverse/request.json b/crates/query-engine/translation/tests/goldenfiles/select_array_column_reverse/request.json index 460586d50..96b772e33 100644 --- a/crates/query-engine/translation/tests/goldenfiles/select_array_column_reverse/request.json +++ b/crates/query-engine/translation/tests/goldenfiles/select_array_column_reverse/request.json @@ -13,7 +13,11 @@ "arguments": { "array": { "type": "literal", - "value": ["a", "b", "c"] + "value": [ + "a", + "b", + "c" + ] } }, "collection_relationships": {} From 2fb2fc8e94b85b63ea1aad35847df88455a933a9 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 25 Dec 2024 09:44:20 -0400 Subject: [PATCH 16/49] right hand side of relationship column mapping is now an array --- .../tests/goldenfiles/dup_array_relationship/request.json | 2 +- .../select_artist_with_album_by_title/request.json | 2 +- .../request.json | 2 +- .../tests/goldenfiles/nested_aggregates/request.json | 2 +- .../goldenfiles/nested_array_relationships/request.json | 4 ++-- .../goldenfiles/nested_recursive_relationship/request.json | 4 ++-- .../request.json | 2 +- .../request.json | 4 ++-- .../select_where_array_relationship/request.json | 2 +- .../goldenfiles/select_where_related_exists/request.json | 2 +- .../goldenfiles/simple_array_relationship/request.json | 2 +- .../goldenfiles/simple_object_relationship/request.json | 2 +- .../sorting_by_nested_relationship_column/request.json | 4 ++-- .../request.json | 4 ++-- .../sorting_by_nested_relationship_count/request.json | 2 +- .../sorting_by_recursive_relationship_column/request.json | 4 ++-- .../goldenfiles/sorting_by_relationship_column/request.json | 2 +- .../request.json | 2 +- .../goldenfiles/sorting_by_relationship_count/request.json | 2 +- .../request.json | 4 ++-- .../very_nested_recursive_relationship/request.json | 6 +++--- 21 files changed, 30 insertions(+), 30 deletions(-) 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/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_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..391faf3d5 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 @@ -150,7 +150,7 @@ "collection_relationships": { "TrackToAlbum": { "column_mapping": { - "AlbumId": "AlbumId" + "AlbumId": ["AlbumId"] }, "relationship_type": "object", "target_collection": "Album", @@ -158,7 +158,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..4c57d24ca 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 @@ -75,7 +75,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/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..158883c03 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 @@ -34,7 +34,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_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..f6c768db9 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 @@ -32,7 +32,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..ebe7ff5ac 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 @@ -65,7 +65,7 @@ "collection_relationships": { "ArtistAlbums": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album", @@ -73,7 +73,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..c2b81aa64 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 @@ -18,7 +18,7 @@ "name": { "type": "column", "column": "Name", - "arguments": {} + "arguments": {} }, "Albums": { @@ -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", From 8970cfcd5bf542e78eff39954123e6e5dbd6112c Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 25 Dec 2024 09:45:38 -0400 Subject: [PATCH 17/49] update aggregate expresion --- .../sorting_by_nested_relationship_count/request.json | 11 +++++++---- .../sorting_by_no_relationship_aggregate/request.json | 11 +++++++---- .../sorting_by_relationship_count/request.json | 7 +++++-- .../request.json | 7 +++++-- 4 files changed, 24 insertions(+), 12 deletions(-) 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 158883c03..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" } 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_relationship_count/request.json b/crates/query-engine/translation/tests/goldenfiles/sorting_by_relationship_count/request.json index f6c768db9..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" + } } } ] 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 ebe7ff5ac..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" + } } }, { From 4a648762b78bc932962850e8bd389d104fc08d46 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 25 Dec 2024 09:46:26 -0400 Subject: [PATCH 18/49] use exists instead of left-hand side path --- .../request.json | 125 +++++++----------- .../request.json | 34 +++-- 2 files changed, 67 insertions(+), 92 deletions(-) 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 391faf3d5..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" - } - } - ] - } - } - ] - } } } }, 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 4c57d24ca..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": { From a4987c2cdc2690092d893d17b4f42c06f2cd84e8 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 25 Dec 2024 09:48:56 -0400 Subject: [PATCH 19/49] update root_collection_column test to use scopes instead note thise feature is still not implemented so the test still fails --- .../select_where_unrelated_exists/request.json | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) 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 } } ] From e1c4e9a288961e34ae01eb9bb142fe476b95c18b Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 25 Dec 2024 10:14:24 -0400 Subject: [PATCH 20/49] Correct sorting behavior. We use CCUNT("col") for CountStar to count only non-null rows, instead of COUNT(*) which would count all rows --- .../translation/src/translation/query/sorting.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/crates/query-engine/translation/src/translation/query/sorting.rs b/crates/query-engine/translation/src/translation/query/sorting.rs index 448a63623..f2a019c64 100644 --- a/crates/query-engine/translation/src/translation/query/sorting.rs +++ b/crates/query-engine/translation/src/translation/query/sorting.rs @@ -494,12 +494,11 @@ fn build_select_and_joins_for_order_by_group( args: vec![column], } } - OrderByAggregate::StarCount => { - sql::ast::Expression::Count(sql::ast::CountType::Star) + OrderByAggregate::StarCount | OrderByAggregate::Count => { + sql::ast::Expression::Count( + sql::ast::CountType::Simple(Box::new(column)), + ) } - 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)), From 623ba6550d0fc8156d0da26ff115e4d44c28322d Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Tue, 31 Dec 2024 14:04:31 -0400 Subject: [PATCH 21/49] use exists instead of left-hand side path --- ...quals_self_nested_object_relationship.snap | 111 +++++++----------- ...ests__select_where_array_relationship.snap | 47 +++----- 2 files changed, 59 insertions(+), 99 deletions(-) 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 e6266fd7a..bf7b2f760 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("%14_universe")), '[]') AS "universe" + coalesce(json_agg(row_to_json("%12_universe")), '[]') AS "universe" FROM ( SELECT @@ -11,7 +11,7 @@ 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 @@ -30,17 +30,17 @@ FROM FROM ( SELECT - coalesce(json_agg(row_to_json("%12_rows")), '[]') AS "rows" + coalesce(json_agg(row_to_json("%10_rows")), '[]') AS "rows" FROM ( SELECT - "%7_Album"."Title" AS "album", - "%8_RELATIONSHIP_Artist"."Artist" AS "Artist" + "%5_Album"."Title" AS "album", + "%6_RELATIONSHIP_Artist"."Artist" AS "Artist" FROM - "public"."Album" AS "%7_Album" + "public"."Album" AS "%5_Album" LEFT OUTER JOIN LATERAL ( SELECT - row_to_json("%8_RELATIONSHIP_Artist") AS "Artist" + row_to_json("%6_RELATIONSHIP_Artist") AS "Artist" FROM ( SELECT @@ -48,107 +48,78 @@ FROM FROM ( SELECT - coalesce(json_agg(row_to_json("%10_rows")), '[]') AS "rows" + coalesce(json_agg(row_to_json("%8_rows")), '[]') AS "rows" FROM ( SELECT - "%9_Artist"."Name" AS "artist", - "%9_Artist"."ArtistId" AS "ArtistId" + "%7_Artist"."Name" AS "artist", + "%7_Artist"."ArtistId" AS "ArtistId" FROM - "public"."Artist" AS "%9_Artist" + "public"."Artist" AS "%7_Artist" WHERE - ("%7_Album"."ArtistId" = "%9_Artist"."ArtistId") - ) AS "%10_rows" - ) AS "%10_rows" - ) AS "%8_RELATIONSHIP_Artist" - ) AS "%8_RELATIONSHIP_Artist" ON ('true') + ("%5_Album"."ArtistId" = "%7_Artist"."ArtistId") + ) AS "%8_rows" + ) AS "%8_rows" + ) AS "%6_RELATIONSHIP_Artist" + ) AS "%6_RELATIONSHIP_Artist" ON ('true') WHERE - ("%0_Track"."AlbumId" = "%7_Album"."AlbumId") - ) AS "%12_rows" - ) AS "%12_rows" + ("%0_Track"."AlbumId" = "%5_Album"."AlbumId") + ) AS "%10_rows" + ) AS "%10_rows" ) AS "%1_RELATIONSHIP_Album" ) AS "%1_RELATIONSHIP_Album" ON ('true') WHERE EXISTS ( SELECT - 1 + 1 AS "one" FROM - ( - SELECT - "%2_BOOLEXP_Album".* - FROM - ( - SELECT - * - FROM - "public"."Album" AS "%2_BOOLEXP_Album" - WHERE - ( - ( - "%2_BOOLEXP_Album"."Title" = cast($1 as "pg_catalog"."varchar") - ) - AND ( - "%0_Track"."AlbumId" = "%2_BOOLEXP_Album"."AlbumId" - ) - ) - ) AS "%2_BOOLEXP_Album" - ) AS "%3_BOOLEXP_Album" FULL + "public"."Album" AS "%2_Album" FULL OUTER JOIN LATERAL ( SELECT - "%5_BOOLEXP_Artist".* + "%3_BOOLEXP_Artist".* FROM ( SELECT * FROM - "public"."Album" AS "%4_BOOLEXP_Album" - WHERE - ( - ( - "%4_BOOLEXP_Album"."Title" = cast($2 as "pg_catalog"."varchar") - ) - AND ( - "%0_Track"."AlbumId" = "%4_BOOLEXP_Album"."AlbumId" - ) - ) - ) AS "%4_BOOLEXP_Album" - INNER JOIN LATERAL ( - SELECT - * - FROM - "public"."Artist" AS "%5_BOOLEXP_Artist" + "public"."Artist" AS "%3_BOOLEXP_Artist" WHERE ( ( - "%5_BOOLEXP_Artist"."Name" = cast($3 as "pg_catalog"."varchar") + "%3_BOOLEXP_Artist"."Name" = cast($1 as "pg_catalog"."varchar") ) AND ( - "%4_BOOLEXP_Album"."ArtistId" = "%5_BOOLEXP_Artist"."ArtistId" + "%2_Album"."ArtistId" = "%3_BOOLEXP_Artist"."ArtistId" ) ) - ) AS "%5_BOOLEXP_Artist" ON ('true') - ) AS "%6_BOOLEXP_Artist" ON ('true') + ) AS "%3_BOOLEXP_Artist" + ) AS "%4_BOOLEXP_Artist" ON ('true') WHERE ( - "%3_BOOLEXP_Album"."AlbumId" > "%6_BOOLEXP_Artist"."ArtistId" + ( + ( + "%2_Album"."Title" = cast($2 as "pg_catalog"."varchar") + ) + AND ( + "%2_Album"."AlbumId" > "%4_BOOLEXP_Artist"."ArtistId" + ) + ) + AND ("%0_Track"."AlbumId" = "%2_Album"."AlbumId") ) ) ORDER BY "%0_Track"."TrackId" ASC LIMIT 5 - ) AS "%15_rows" - ) AS "%15_rows" - ) AS "%14_universe"; + ) AS "%13_rows" + ) AS "%13_rows" + ) AS "%12_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 d9cd86f6c..70a6cdc51 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("%7_universe")), '[]') AS "universe" + coalesce(json_agg(row_to_json("%6_universe")), '[]') AS "universe" FROM ( SELECT @@ -11,7 +11,7 @@ FROM FROM ( SELECT - coalesce(json_agg(row_to_json("%8_rows")), '[]') AS "rows" + coalesce(json_agg(row_to_json("%7_rows")), '[]') AS "rows" FROM ( SELECT @@ -29,51 +29,40 @@ 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 - "%4_Album"."Title" AS "title" + "%3_Album"."Title" AS "title" FROM - "public"."Album" AS "%4_Album" + "public"."Album" AS "%3_Album" WHERE - ("%0_Artist"."ArtistId" = "%4_Album"."ArtistId") + ("%0_Artist"."ArtistId" = "%3_Album"."ArtistId") ORDER BY - "%4_Album"."AlbumId" ASC - ) AS "%5_rows" - ) AS "%5_rows" + "%3_Album"."AlbumId" ASC + ) AS "%4_rows" + ) AS "%4_rows" ) AS "%1_RELATIONSHIP_albums" ) AS "%1_RELATIONSHIP_albums" ON ('true') WHERE EXISTS ( SELECT - 1 + 1 AS "one" FROM - ( - SELECT - "%2_BOOLEXP_Album".* - FROM - ( - SELECT - * - FROM - "public"."Album" AS "%2_BOOLEXP_Album" - WHERE - ( - "%0_Artist"."ArtistId" = "%2_BOOLEXP_Album"."ArtistId" - ) - ) AS "%2_BOOLEXP_Album" - ) AS "%3_BOOLEXP_Album" + "public"."Album" AS "%2_Album" WHERE ( - "%3_BOOLEXP_Album"."Title" LIKE cast($1 as "pg_catalog"."varchar") + ( + "%2_Album"."Title" LIKE cast($1 as "pg_catalog"."varchar") + ) + AND ("%0_Artist"."ArtistId" = "%2_Album"."ArtistId") ) ) ORDER BY "%0_Artist"."ArtistId" ASC - ) AS "%8_rows" - ) AS "%8_rows" - ) AS "%7_universe"; + ) AS "%7_rows" + ) AS "%7_rows" + ) AS "%6_universe"; { 1: String( From b75dbc25193820e6910c90e0c4233ef1064dc24d Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Tue, 31 Dec 2024 17:24:05 -0400 Subject: [PATCH 22/49] v0.2.0 schema update --- ...schema_tests__schema_test__get_schema.snap | 923 +++++----- ...schema_tests__schema_test__get_schema.snap | 580 ++++--- ...schema_tests__schema_test__get_schema.snap | 1510 +++++++++-------- 3 files changed, 1522 insertions(+), 1491 deletions(-) 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..4eefcfa61 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,8 @@ --- source: crates/tests/databases-tests/src/citus/schema_tests.rs +assertion_line: 7 expression: result +snapshot_kind: text --- { "scalar_types": { @@ -10,22 +12,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 +138,7 @@ expression: result }, "aggregate_functions": { "bool_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -157,6 +148,7 @@ expression: result } }, "bool_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -166,6 +158,7 @@ expression: result } }, "every": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -231,22 +224,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 +280,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 +406,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 +462,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -514,6 +472,7 @@ expression: result } }, "bit_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -523,6 +482,7 @@ expression: result } }, "bit_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -532,6 +492,7 @@ expression: result } }, "bit_xor": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -541,24 +502,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 +518,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -577,6 +528,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -586,15 +538,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 +552,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -613,6 +562,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -672,6 +622,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -681,24 +632,13 @@ expression: result } }, "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 +648,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -717,6 +658,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -726,15 +668,11 @@ expression: result } }, "sum": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float4" - } - } + "type": "sum", + "result_type": "float4" }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -744,6 +682,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -753,6 +692,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -812,6 +752,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -821,24 +762,13 @@ expression: result } }, "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 +778,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -857,6 +788,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -866,15 +798,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 +812,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -893,6 +822,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -952,6 +882,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -961,6 +892,7 @@ expression: result } }, "bit_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -970,6 +902,7 @@ expression: result } }, "bit_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -979,6 +912,7 @@ expression: result } }, "bit_xor": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -988,24 +922,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 +938,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1024,6 +948,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1033,15 +958,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 +972,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1060,6 +982,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1119,6 +1042,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1128,6 +1052,7 @@ expression: result } }, "bit_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1137,6 +1062,7 @@ expression: result } }, "bit_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1146,6 +1072,7 @@ expression: result } }, "bit_xor": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1155,24 +1082,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 +1098,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1191,6 +1108,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1200,15 +1118,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 +1132,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1227,6 +1142,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1286,6 +1202,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1295,6 +1212,7 @@ expression: result } }, "bit_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1304,6 +1222,7 @@ expression: result } }, "bit_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1313,6 +1232,7 @@ expression: result } }, "bit_xor": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1322,24 +1242,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 +1258,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1358,6 +1268,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1367,15 +1278,11 @@ expression: result } }, "sum": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "numeric" - } - } + "type": "sum", + "result_type": "numeric" }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1385,6 +1292,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1394,6 +1302,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1448,8 +1357,12 @@ expression: result } }, "interval": { + "representation": { + "type": "json" + }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1459,31 +1372,14 @@ 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": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "interval" - } - } + "type": "sum", + "result_type": "interval" } }, "comparison_operators": { @@ -1536,6 +1432,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1543,26 +1440,15 @@ expression: result "name": "numeric" } } - }, - "max": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "numeric" - } - } + }, + "max": { + "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 +1458,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1581,6 +1468,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1590,15 +1478,11 @@ expression: result } }, "sum": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "numeric" - } - } + "type": "sum", + "result_type": "numeric" }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1608,6 +1492,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1617,6 +1502,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1676,22 +1562,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 +1688,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1823,31 +1698,14 @@ 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": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "interval" - } - } + "type": "sum", + "result_type": "interval" } }, "comparison_operators": { @@ -1900,22 +1758,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 +1814,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 +1870,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 +1975,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 +2121,16 @@ expression: result "name": "varchar" } } + }, + "foreign_keys": { + "FK_AlbumArtistId": { + "column_mapping": { + "ArtistId": [ + "ArtistId" + ] + }, + "foreign_collection": "Artist" + } } }, "Artist": { @@ -2333,7 +2153,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "Customer": { "description": "The record of all customers", @@ -2446,6 +2267,16 @@ expression: result } } } + }, + "foreign_keys": { + "FK_CustomerSupportRepId": { + "column_mapping": { + "SupportRepId": [ + "EmployeeId" + ] + }, + "foreign_collection": "Employee" + } } }, "Employee": { @@ -2576,6 +2407,16 @@ expression: result } } } + }, + "foreign_keys": { + "FK_EmployeeReportsTo": { + "column_mapping": { + "ReportsTo": [ + "EmployeeId" + ] + }, + "foreign_collection": "Employee" + } } }, "Genre": { @@ -2595,7 +2436,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "Invoice": { "fields": { @@ -2668,6 +2510,16 @@ expression: result "name": "numeric" } } + }, + "foreign_keys": { + "FK_InvoiceCustomerId": { + "column_mapping": { + "CustomerId": [ + "CustomerId" + ] + }, + "foreign_collection": "Customer" + } } }, "InvoiceLine": { @@ -2702,6 +2554,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 +2591,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "Playlist": { "fields": { @@ -2740,7 +2611,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "PlaylistTrack": { "fields": { @@ -2756,6 +2628,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 +2716,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 +2756,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "album_by_title": { "fields": { @@ -2871,7 +2788,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "array_reverse": { "description": "A native query used to test support for arrays as inputs", @@ -2892,7 +2810,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "array_series": { "description": "A native query used to test support for arrays", @@ -2921,7 +2840,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "artist": { "fields": { @@ -2943,7 +2863,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "artist_below_id": { "fields": { @@ -2965,7 +2886,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "chara": { "fields": { @@ -2987,7 +2909,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "characters": { "fields": { @@ -3015,7 +2938,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "committee": { "fields": { @@ -3043,7 +2967,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "count_elements": { "description": "A native query used to test support array-valued variables", @@ -3057,7 +2982,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "deck_of_cards": { "fields": { @@ -3073,7 +2999,8 @@ expression: result "name": "card_suit" } } - } + }, + "foreign_keys": {} }, "delete_playlist_track": { "fields": { @@ -3095,7 +3022,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_playlist_track_response": { "description": "Responses from the 'delete_playlist_track' procedure", @@ -3117,7 +3045,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "discoverable_types": { "fields": { @@ -3130,7 +3059,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "discoverable_types_root_occurrence": { "fields": { @@ -3143,7 +3073,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "even_numbers": { "fields": { @@ -3153,7 +3084,8 @@ expression: result "name": "even_number" } } - } + }, + "foreign_keys": {} }, "group_leader": { "fields": { @@ -3184,7 +3116,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_album": { "fields": { @@ -3215,7 +3148,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_album_response": { "description": "Responses from the 'insert_album' procedure", @@ -3237,7 +3171,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_artist": { "fields": { @@ -3259,7 +3194,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_artist_response": { "description": "Responses from the 'insert_artist' procedure", @@ -3281,7 +3217,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "make_person": { "description": "A native query used to test support for composite types", @@ -3295,7 +3232,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "organization": { "fields": { @@ -3323,7 +3261,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "organization_identity_function": { "description": "A native query used to test support for composite types", @@ -3337,7 +3276,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "person": { "fields": { @@ -3359,7 +3299,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "person_address": { "description": "The address of a person, obviously", @@ -3384,7 +3325,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "person_name": { "description": "The name of a person, obviously", @@ -3409,7 +3351,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "phone_numbers": { "fields": { @@ -3419,7 +3362,8 @@ expression: result "name": "Phone" } } - } + }, + "foreign_keys": {} }, "summarize_organizations": { "description": "A native query used to test support array-valued variables", @@ -3433,7 +3377,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Album_by_AlbumId_response": { "description": "Responses from the 'v1_delete_Album_by_AlbumId' procedure", @@ -3455,7 +3400,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Artist_by_ArtistId_response": { "description": "Responses from the 'v1_delete_Artist_by_ArtistId' procedure", @@ -3477,7 +3423,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Customer_by_CustomerId_response": { "description": "Responses from the 'v1_delete_Customer_by_CustomerId' procedure", @@ -3499,7 +3446,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Employee_by_EmployeeId_response": { "description": "Responses from the 'v1_delete_Employee_by_EmployeeId' procedure", @@ -3521,7 +3469,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Genre_by_GenreId_response": { "description": "Responses from the 'v1_delete_Genre_by_GenreId' procedure", @@ -3543,7 +3492,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_InvoiceLine_by_InvoiceLineId_response": { "description": "Responses from the 'v1_delete_InvoiceLine_by_InvoiceLineId' procedure", @@ -3565,7 +3515,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Invoice_by_InvoiceId_response": { "description": "Responses from the 'v1_delete_Invoice_by_InvoiceId' procedure", @@ -3587,7 +3538,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_MediaType_by_MediaTypeId_response": { "description": "Responses from the 'v1_delete_MediaType_by_MediaTypeId' procedure", @@ -3609,7 +3561,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Playlist_by_PlaylistId_response": { "description": "Responses from the 'v1_delete_Playlist_by_PlaylistId' procedure", @@ -3631,7 +3584,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Track_by_TrackId_response": { "description": "Responses from the 'v1_delete_Track_by_TrackId' procedure", @@ -3653,7 +3607,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Album_object": { "fields": { @@ -3678,7 +3633,8 @@ expression: result "name": "varchar" } } - } + }, + "foreign_keys": {} }, "v1_insert_Album_response": { "description": "Responses from the 'v1_insert_Album' procedure", @@ -3700,7 +3656,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Artist_object": { "fields": { @@ -3721,7 +3678,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Artist_response": { "description": "Responses from the 'v1_insert_Artist' procedure", @@ -3743,7 +3701,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Customer_object": { "fields": { @@ -3855,7 +3814,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Customer_response": { "description": "Responses from the 'v1_insert_Customer' procedure", @@ -3877,7 +3837,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Employee_object": { "fields": { @@ -4007,7 +3968,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Employee_response": { "description": "Responses from the 'v1_insert_Employee' procedure", @@ -4029,7 +3991,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Genre_object": { "fields": { @@ -4048,7 +4011,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Genre_response": { "description": "Responses from the 'v1_insert_Genre' procedure", @@ -4070,7 +4034,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_InvoiceLine_object": { "fields": { @@ -4104,7 +4069,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "v1_insert_InvoiceLine_response": { "description": "Responses from the 'v1_insert_InvoiceLine' procedure", @@ -4126,7 +4092,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Invoice_object": { "fields": { @@ -4199,7 +4166,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "v1_insert_Invoice_response": { "description": "Responses from the 'v1_insert_Invoice' procedure", @@ -4221,7 +4189,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_MediaType_object": { "fields": { @@ -4240,7 +4209,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_MediaType_response": { "description": "Responses from the 'v1_insert_MediaType' procedure", @@ -4262,7 +4232,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_PlaylistTrack_object": { "fields": { @@ -4278,7 +4249,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "v1_insert_PlaylistTrack_response": { "description": "Responses from the 'v1_insert_PlaylistTrack' procedure", @@ -4300,7 +4272,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Playlist_object": { "fields": { @@ -4319,7 +4292,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "v1_insert_Playlist_response": { "description": "Responses from the 'v1_insert_Playlist' procedure", @@ -4341,7 +4315,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Track_object": { "fields": { @@ -4411,7 +4386,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "v1_insert_Track_response": { "description": "Responses from the 'v1_insert_Track' procedure", @@ -4433,7 +4409,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_deck_of_cards_object": { "fields": { @@ -4449,7 +4426,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 +4449,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_discoverable_types_root_occurrence_object": { "fields": { @@ -4484,7 +4463,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 +4486,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_even_numbers_object": { "fields": { @@ -4516,7 +4497,8 @@ expression: result "name": "even_number" } } - } + }, + "foreign_keys": {} }, "v1_insert_even_numbers_response": { "description": "Responses from the 'v1_insert_even_numbers' procedure", @@ -4538,7 +4520,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_group_leader_object": { "fields": { @@ -4569,7 +4552,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_group_leader_response": { "description": "Responses from the 'v1_insert_group_leader' procedure", @@ -4591,7 +4575,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_phone_numbers_object": { "fields": { @@ -4601,7 +4586,8 @@ expression: result "name": "Phone" } } - } + }, + "foreign_keys": {} }, "v1_insert_phone_numbers_response": { "description": "Responses from the 'v1_insert_phone_numbers' procedure", @@ -4623,7 +4609,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "value_types": { "fields": { @@ -4771,7 +4758,8 @@ expression: result } } } - } + }, + "foreign_keys": {} } }, "collections": [ @@ -4786,14 +4774,6 @@ expression: result "AlbumId" ] } - }, - "foreign_keys": { - "FK_AlbumArtistId": { - "column_mapping": { - "ArtistId": "ArtistId" - }, - "foreign_collection": "Artist" - } } }, { @@ -4807,8 +4787,7 @@ expression: result "ArtistId" ] } - }, - "foreign_keys": {} + } }, { "name": "Customer", @@ -4821,14 +4800,6 @@ expression: result "CustomerId" ] } - }, - "foreign_keys": { - "FK_CustomerSupportRepId": { - "column_mapping": { - "SupportRepId": "EmployeeId" - }, - "foreign_collection": "Employee" - } } }, { @@ -4841,14 +4812,6 @@ expression: result "EmployeeId" ] } - }, - "foreign_keys": { - "FK_EmployeeReportsTo": { - "column_mapping": { - "ReportsTo": "EmployeeId" - }, - "foreign_collection": "Employee" - } } }, { @@ -4861,8 +4824,7 @@ expression: result "GenreId" ] } - }, - "foreign_keys": {} + } }, { "name": "Invoice", @@ -4874,14 +4836,6 @@ expression: result "InvoiceId" ] } - }, - "foreign_keys": { - "FK_InvoiceCustomerId": { - "column_mapping": { - "CustomerId": "CustomerId" - }, - "foreign_collection": "Customer" - } } }, { @@ -4894,20 +4848,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 +4860,7 @@ expression: result "MediaTypeId" ] } - }, - "foreign_keys": {} + } }, { "name": "Playlist", @@ -4933,8 +4872,7 @@ expression: result "PlaylistId" ] } - }, - "foreign_keys": {} + } }, { "name": "PlaylistTrack", @@ -4947,20 +4885,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 +4897,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 +4944,7 @@ expression: result } }, "type": "address_identity_function", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "album_by_title", @@ -5071,8 +4969,7 @@ expression: result } }, "type": "album_by_title", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "array_reverse", @@ -5093,8 +4990,7 @@ expression: result } }, "type": "array_reverse", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "array_series", @@ -5120,15 +5016,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 +5038,7 @@ expression: result } }, "type": "artist_below_id", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "count_elements", @@ -5168,8 +5061,7 @@ expression: result } }, "type": "count_elements", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "make_person", @@ -5195,8 +5087,7 @@ expression: result } }, "type": "make_person", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "organization_identity_function", @@ -5213,8 +5104,7 @@ expression: result } }, "type": "organization_identity_function", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "summarize_organizations", @@ -5237,8 +5127,7 @@ expression: result } }, "type": "summarize_organizations", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "value_types", @@ -5389,8 +5278,7 @@ expression: result } }, "type": "value_types", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} } ], "functions": [], @@ -5895,5 +5783,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..f1e9de6ac 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,8 @@ --- source: crates/tests/databases-tests/src/cockroach/schema_tests.rs +assertion_line: 7 expression: result +snapshot_kind: text --- { "scalar_types": { @@ -10,6 +12,7 @@ expression: result }, "aggregate_functions": { "bool_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -19,6 +22,7 @@ expression: result } }, "bool_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -28,6 +32,7 @@ expression: result } }, "every": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -93,22 +98,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 +154,7 @@ expression: result }, "aggregate_functions": { "concat_agg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -367,6 +361,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -376,6 +371,7 @@ expression: result } }, "sqrdiff": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -385,6 +381,7 @@ expression: result } }, "stddev": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -394,6 +391,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -403,6 +401,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -412,15 +411,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 +425,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -439,6 +435,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -498,6 +495,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -507,6 +505,7 @@ expression: result } }, "sqrdiff": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -516,6 +515,7 @@ expression: result } }, "stddev": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -525,6 +525,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -534,6 +535,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -543,15 +545,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 +559,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -570,6 +569,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -629,6 +629,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -638,6 +639,7 @@ expression: result } }, "bit_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -647,6 +649,7 @@ expression: result } }, "bit_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -656,6 +659,7 @@ expression: result } }, "sqrdiff": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -665,6 +669,7 @@ expression: result } }, "stddev": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -674,6 +679,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -683,6 +689,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -692,15 +699,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 +713,7 @@ expression: result } }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -719,6 +723,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -728,6 +733,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -737,6 +743,7 @@ expression: result } }, "xor_agg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -796,6 +803,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -805,6 +813,7 @@ expression: result } }, "bit_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -814,6 +823,7 @@ expression: result } }, "bit_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -823,6 +833,7 @@ expression: result } }, "sqrdiff": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -832,6 +843,7 @@ expression: result } }, "stddev": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -841,6 +853,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -850,6 +863,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -859,15 +873,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 +887,7 @@ expression: result } }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -886,6 +897,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -895,6 +907,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -904,6 +917,7 @@ expression: result } }, "xor_agg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -963,6 +977,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -972,6 +987,7 @@ expression: result } }, "bit_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -981,6 +997,7 @@ expression: result } }, "bit_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -990,6 +1007,7 @@ expression: result } }, "sqrdiff": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -999,6 +1017,7 @@ expression: result } }, "stddev": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1008,6 +1027,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1017,6 +1037,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1026,15 +1047,11 @@ expression: result } }, "sum": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "numeric" - } - } + "type": "sum", + "result_type": "numeric" }, "sum_int": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1044,6 +1061,7 @@ expression: result } }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1053,6 +1071,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1062,6 +1081,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1071,6 +1091,7 @@ expression: result } }, "xor_agg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1125,8 +1146,12 @@ expression: result } }, "interval": { + "representation": { + "type": "json" + }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1136,13 +1161,8 @@ expression: result } }, "sum": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "interval" - } - } + "type": "sum", + "result_type": "interval" } }, "comparison_operators": { @@ -1195,6 +1215,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1204,6 +1225,7 @@ expression: result } }, "sqrdiff": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1213,6 +1235,7 @@ expression: result } }, "stddev": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1222,6 +1245,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1231,6 +1255,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1240,15 +1265,11 @@ expression: result } }, "sum": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "numeric" - } - } + "type": "sum", + "result_type": "numeric" }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1258,6 +1279,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1267,6 +1289,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1326,6 +1349,7 @@ expression: result }, "aggregate_functions": { "concat_agg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1483,6 +1507,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1492,13 +1517,8 @@ expression: result } }, "sum": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "interval" - } - } + "type": "sum", + "result_type": "interval" } }, "comparison_operators": { @@ -1747,6 +1767,7 @@ expression: result }, "aggregate_functions": { "concat_agg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1924,6 +1945,16 @@ expression: result "name": "varchar" } } + }, + "foreign_keys": { + "FK_AlbumArtistId": { + "column_mapping": { + "ArtistId": [ + "ArtistId" + ] + }, + "foreign_collection": "Artist" + } } }, "Artist": { @@ -1946,7 +1977,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "Customer": { "description": "The record of all customers", @@ -2059,6 +2091,16 @@ expression: result } } } + }, + "foreign_keys": { + "FK_CustomerSupportRepId": { + "column_mapping": { + "SupportRepId": [ + "EmployeeId" + ] + }, + "foreign_collection": "Employee" + } } }, "Employee": { @@ -2189,6 +2231,16 @@ expression: result } } } + }, + "foreign_keys": { + "FK_EmployeeReportsTo": { + "column_mapping": { + "ReportsTo": [ + "EmployeeId" + ] + }, + "foreign_collection": "Employee" + } } }, "Genre": { @@ -2208,7 +2260,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "Invoice": { "fields": { @@ -2281,6 +2334,16 @@ expression: result "name": "numeric" } } + }, + "foreign_keys": { + "FK_InvoiceCustomerId": { + "column_mapping": { + "CustomerId": [ + "CustomerId" + ] + }, + "foreign_collection": "Customer" + } } }, "InvoiceLine": { @@ -2315,6 +2378,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 +2415,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "Playlist": { "fields": { @@ -2353,7 +2435,8 @@ expression: result "name": "int8" } } - } + }, + "foreign_keys": {} }, "PlaylistTrack": { "fields": { @@ -2369,6 +2452,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 +2540,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 +2580,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "album_by_title": { "fields": { @@ -2484,7 +2612,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "array_reverse": { "description": "A native query used to test support for arrays as inputs", @@ -2505,7 +2634,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "array_series": { "description": "A native query used to test support for arrays", @@ -2534,7 +2664,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "artist": { "fields": { @@ -2556,7 +2687,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "artist_below_id": { "fields": { @@ -2578,7 +2710,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "count_elements": { "description": "A native query used to test support array-valued variables", @@ -2592,7 +2725,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "deck_of_cards": { "fields": { @@ -2614,7 +2748,8 @@ expression: result "name": "card_suit" } } - } + }, + "foreign_keys": {} }, "delete_playlist_track": { "fields": { @@ -2636,7 +2771,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_playlist_track_response": { "description": "Responses from the 'delete_playlist_track' procedure", @@ -2658,7 +2794,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "discoverable_types_root_occurrence": { "fields": { @@ -2677,7 +2814,8 @@ expression: result "name": "int8" } } - } + }, + "foreign_keys": {} }, "insert_album": { "fields": { @@ -2708,7 +2846,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_album_response": { "description": "Responses from the 'insert_album' procedure", @@ -2730,7 +2869,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_artist": { "fields": { @@ -2752,7 +2892,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_artist_response": { "description": "Responses from the 'insert_artist' procedure", @@ -2774,7 +2915,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 +2966,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Album_by_AlbumId_response": { "description": "Responses from the 'v1_delete_Album_by_AlbumId' procedure", @@ -2846,7 +2989,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Artist_by_ArtistId_response": { "description": "Responses from the 'v1_delete_Artist_by_ArtistId' procedure", @@ -2868,7 +3012,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Customer_by_CustomerId_response": { "description": "Responses from the 'v1_delete_Customer_by_CustomerId' procedure", @@ -2890,7 +3035,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Employee_by_EmployeeId_response": { "description": "Responses from the 'v1_delete_Employee_by_EmployeeId' procedure", @@ -2912,7 +3058,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Genre_by_GenreId_response": { "description": "Responses from the 'v1_delete_Genre_by_GenreId' procedure", @@ -2934,7 +3081,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_InvoiceLine_by_InvoiceLineId_response": { "description": "Responses from the 'v1_delete_InvoiceLine_by_InvoiceLineId' procedure", @@ -2956,7 +3104,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Invoice_by_InvoiceId_response": { "description": "Responses from the 'v1_delete_Invoice_by_InvoiceId' procedure", @@ -2978,7 +3127,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_MediaType_by_MediaTypeId_response": { "description": "Responses from the 'v1_delete_MediaType_by_MediaTypeId' procedure", @@ -3000,7 +3150,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Playlist_by_PlaylistId_response": { "description": "Responses from the 'v1_delete_Playlist_by_PlaylistId' procedure", @@ -3022,7 +3173,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_delete_Track_by_TrackId_response": { "description": "Responses from the 'v1_delete_Track_by_TrackId' procedure", @@ -3044,7 +3196,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 +3219,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 +3242,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Album_object": { "fields": { @@ -3113,7 +3268,8 @@ expression: result "name": "varchar" } } - } + }, + "foreign_keys": {} }, "v1_insert_Album_response": { "description": "Responses from the 'v1_insert_Album' procedure", @@ -3135,7 +3291,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Artist_object": { "fields": { @@ -3156,7 +3313,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Artist_response": { "description": "Responses from the 'v1_insert_Artist' procedure", @@ -3178,7 +3336,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Customer_object": { "fields": { @@ -3290,7 +3449,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Customer_response": { "description": "Responses from the 'v1_insert_Customer' procedure", @@ -3312,7 +3472,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Employee_object": { "fields": { @@ -3442,7 +3603,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Employee_response": { "description": "Responses from the 'v1_insert_Employee' procedure", @@ -3464,7 +3626,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Genre_object": { "fields": { @@ -3483,7 +3646,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Genre_response": { "description": "Responses from the 'v1_insert_Genre' procedure", @@ -3505,7 +3669,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_InvoiceLine_object": { "fields": { @@ -3539,7 +3704,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "v1_insert_InvoiceLine_response": { "description": "Responses from the 'v1_insert_InvoiceLine' procedure", @@ -3561,7 +3727,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Invoice_object": { "fields": { @@ -3634,7 +3801,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "v1_insert_Invoice_response": { "description": "Responses from the 'v1_insert_Invoice' procedure", @@ -3656,7 +3824,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_MediaType_object": { "fields": { @@ -3675,7 +3844,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_MediaType_response": { "description": "Responses from the 'v1_insert_MediaType' procedure", @@ -3697,7 +3867,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_PlaylistTrack_object": { "fields": { @@ -3713,7 +3884,8 @@ expression: result "name": "int8" } } - } + }, + "foreign_keys": {} }, "v1_insert_PlaylistTrack_response": { "description": "Responses from the 'v1_insert_PlaylistTrack' procedure", @@ -3735,7 +3907,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Playlist_object": { "fields": { @@ -3754,7 +3927,8 @@ expression: result "name": "int8" } } - } + }, + "foreign_keys": {} }, "v1_insert_Playlist_response": { "description": "Responses from the 'v1_insert_Playlist' procedure", @@ -3776,7 +3950,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_Track_object": { "fields": { @@ -3846,7 +4021,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "v1_insert_Track_response": { "description": "Responses from the 'v1_insert_Track' procedure", @@ -3868,7 +4044,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_deck_of_cards_object": { "fields": { @@ -3893,7 +4070,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 +4093,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_discoverable_types_root_occurrence_object": { "fields": { @@ -3937,7 +4116,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 +4139,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "v1_insert_pg_extension_spatial_ref_sys_object": { "fields": { @@ -4008,7 +4189,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 +4212,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "value_types": { "fields": { @@ -4178,7 +4361,8 @@ expression: result } } } - } + }, + "foreign_keys": {} } }, "collections": [ @@ -4193,14 +4377,6 @@ expression: result "AlbumId" ] } - }, - "foreign_keys": { - "FK_AlbumArtistId": { - "column_mapping": { - "ArtistId": "ArtistId" - }, - "foreign_collection": "Artist" - } } }, { @@ -4214,8 +4390,7 @@ expression: result "ArtistId" ] } - }, - "foreign_keys": {} + } }, { "name": "Customer", @@ -4228,14 +4403,6 @@ expression: result "CustomerId" ] } - }, - "foreign_keys": { - "FK_CustomerSupportRepId": { - "column_mapping": { - "SupportRepId": "EmployeeId" - }, - "foreign_collection": "Employee" - } } }, { @@ -4248,14 +4415,6 @@ expression: result "EmployeeId" ] } - }, - "foreign_keys": { - "FK_EmployeeReportsTo": { - "column_mapping": { - "ReportsTo": "EmployeeId" - }, - "foreign_collection": "Employee" - } } }, { @@ -4268,8 +4427,7 @@ expression: result "GenreId" ] } - }, - "foreign_keys": {} + } }, { "name": "Invoice", @@ -4281,14 +4439,6 @@ expression: result "InvoiceId" ] } - }, - "foreign_keys": { - "FK_InvoiceCustomerId": { - "column_mapping": { - "CustomerId": "CustomerId" - }, - "foreign_collection": "Customer" - } } }, { @@ -4301,20 +4451,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 +4463,7 @@ expression: result "MediaTypeId" ] } - }, - "foreign_keys": {} + } }, { "name": "Playlist", @@ -4340,8 +4475,7 @@ expression: result "PlaylistId" ] } - }, - "foreign_keys": {} + } }, { "name": "PlaylistTrack", @@ -4354,20 +4488,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 +4500,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 +4512,7 @@ expression: result "rowid" ] } - }, - "foreign_keys": {} + } }, { "name": "discoverable_types_root_occurrence", @@ -4425,16 +4524,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 +4548,7 @@ expression: result } }, "type": "address_identity_function", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "album_by_title", @@ -4477,8 +4573,7 @@ expression: result } }, "type": "album_by_title", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "array_reverse", @@ -4499,8 +4594,7 @@ expression: result } }, "type": "array_reverse", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "array_series", @@ -4526,15 +4620,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 +4642,7 @@ expression: result } }, "type": "artist_below_id", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "count_elements", @@ -4574,8 +4665,7 @@ expression: result } }, "type": "count_elements", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "value_types", @@ -4726,8 +4816,7 @@ expression: result } }, "type": "value_types", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} } ], "functions": [], @@ -5232,5 +5321,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__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..adc78d09d 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 @@ -1,5 +1,6 @@ --- source: crates/tests/databases-tests/src/postgres/schema_tests.rs +assertion_line: 7 expression: result --- { @@ -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": { @@ -176,6 +165,7 @@ expression: result }, "aggregate_functions": { "bool_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -185,6 +175,7 @@ expression: result } }, "bool_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -194,6 +185,7 @@ expression: result } }, "every": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -259,22 +251,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 +307,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 +456,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 +559,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 +615,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -677,6 +625,7 @@ expression: result } }, "bit_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -686,6 +635,7 @@ expression: result } }, "bit_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -695,6 +645,7 @@ expression: result } }, "bit_xor": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -704,24 +655,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 +671,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -740,6 +681,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -749,15 +691,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 +705,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -776,6 +715,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -835,6 +775,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -844,24 +785,13 @@ expression: result } }, "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 +801,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -880,6 +811,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -889,15 +821,11 @@ expression: result } }, "sum": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float4" - } - } + "type": "sum", + "result_type": "float4" }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -907,6 +835,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -916,6 +845,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -975,6 +905,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -984,24 +915,13 @@ expression: result } }, "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 +931,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1020,6 +941,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1029,15 +951,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 +965,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1056,6 +975,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1110,24 +1030,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 +1133,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1231,6 +1143,7 @@ expression: result } }, "bit_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1240,6 +1153,7 @@ expression: result } }, "bit_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1249,6 +1163,7 @@ expression: result } }, "bit_xor": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1258,24 +1173,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 +1189,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1294,6 +1199,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1303,15 +1209,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 +1223,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1330,6 +1233,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1389,6 +1293,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1398,6 +1303,7 @@ expression: result } }, "bit_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1407,6 +1313,7 @@ expression: result } }, "bit_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1416,6 +1323,7 @@ expression: result } }, "bit_xor": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1425,24 +1333,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 +1349,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1461,6 +1359,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1470,15 +1369,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 +1383,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1497,6 +1393,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1556,6 +1453,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1565,6 +1463,7 @@ expression: result } }, "bit_and": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1574,6 +1473,7 @@ expression: result } }, "bit_or": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1583,6 +1483,7 @@ expression: result } }, "bit_xor": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1592,24 +1493,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 +1509,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1628,6 +1519,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1637,15 +1529,11 @@ expression: result } }, "sum": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "numeric" - } - } + "type": "sum", + "result_type": "numeric" }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1655,6 +1543,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1664,6 +1553,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1718,8 +1608,12 @@ expression: result } }, "interval": { + "representation": { + "type": "json" + }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1729,31 +1623,14 @@ 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": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "interval" - } - } + "type": "sum", + "result_type": "interval" } }, "comparison_operators": { @@ -1806,6 +1683,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1815,24 +1693,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 +1709,7 @@ expression: result } }, "stddev_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1851,6 +1719,7 @@ expression: result } }, "stddev_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1860,15 +1729,11 @@ expression: result } }, "sum": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "numeric" - } - } + "type": "sum", + "result_type": "numeric" }, "var_pop": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1878,6 +1743,7 @@ expression: result } }, "var_samp": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1887,6 +1753,7 @@ expression: result } }, "variance": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -1942,26 +1809,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 +1967,7 @@ expression: result }, "aggregate_functions": { "avg": { + "type": "custom", "result_type": { "type": "nullable", "underlying_type": { @@ -2121,31 +1977,14 @@ 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": { - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "interval" - } - } + "type": "sum", + "result_type": "interval" } }, "comparison_operators": { @@ -2198,22 +2037,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 +2093,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 +2149,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 +2254,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 +2428,16 @@ expression: result "name": "varchar" } } + }, + "foreign_keys": { + "FK_AlbumArtistId": { + "column_mapping": { + "ArtistId": [ + "ArtistId" + ] + }, + "foreign_collection": "Artist" + } } }, "Artist": { @@ -2659,7 +2460,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "Customer": { "description": "The record of all customers", @@ -2772,6 +2574,16 @@ expression: result } } } + }, + "foreign_keys": { + "FK_CustomerSupportRepId": { + "column_mapping": { + "SupportRepId": [ + "EmployeeId" + ] + }, + "foreign_collection": "Employee" + } } }, "Employee": { @@ -2902,6 +2714,16 @@ expression: result } } } + }, + "foreign_keys": { + "FK_EmployeeReportsTo": { + "column_mapping": { + "ReportsTo": [ + "EmployeeId" + ] + }, + "foreign_collection": "Employee" + } } }, "Genre": { @@ -2921,7 +2743,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "Invoice": { "fields": { @@ -2994,6 +2817,16 @@ expression: result "name": "numeric" } } + }, + "foreign_keys": { + "FK_InvoiceCustomerId": { + "column_mapping": { + "CustomerId": [ + "CustomerId" + ] + }, + "foreign_collection": "Customer" + } } }, "InvoiceLine": { @@ -3028,6 +2861,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 +2898,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "Playlist": { "fields": { @@ -3066,7 +2918,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "PlaylistTrack": { "fields": { @@ -3082,6 +2935,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 +3023,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 +3063,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "album_by_title": { "fields": { @@ -3197,7 +3095,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "array_reverse": { "description": "A native query used to test support for arrays as inputs", @@ -3218,7 +3117,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "array_series": { "description": "A native query used to test support for arrays", @@ -3247,7 +3147,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "artist": { "fields": { @@ -3269,7 +3170,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "artist_below_id": { "fields": { @@ -3291,7 +3193,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "chara": { "fields": { @@ -3313,7 +3216,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "characters": { "fields": { @@ -3341,7 +3245,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "committee": { "fields": { @@ -3369,7 +3274,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "count_elements": { "description": "A native query used to test support array-valued variables", @@ -3383,7 +3289,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "custom_defaults": { "fields": { @@ -3423,7 +3330,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "custom_dog": { "fields": { @@ -3469,7 +3377,8 @@ expression: result "name": "text" } } - } + }, + "foreign_keys": {} }, "custom_test_cidr": { "fields": { @@ -3491,7 +3400,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "deck_of_cards": { "fields": { @@ -3507,7 +3417,8 @@ expression: result "name": "card_suit" } } - } + }, + "foreign_keys": {} }, "delete_Album_by_AlbumId_response": { "description": "Responses from the 'delete_Album_by_AlbumId' procedure", @@ -3529,7 +3440,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_Artist_by_ArtistId_response": { "description": "Responses from the 'delete_Artist_by_ArtistId' procedure", @@ -3551,7 +3463,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_Customer_by_CustomerId_response": { "description": "Responses from the 'delete_Customer_by_CustomerId' procedure", @@ -3573,7 +3486,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_Employee_by_EmployeeId_response": { "description": "Responses from the 'delete_Employee_by_EmployeeId' procedure", @@ -3595,7 +3509,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_Genre_by_GenreId_response": { "description": "Responses from the 'delete_Genre_by_GenreId' procedure", @@ -3617,7 +3532,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_InvoiceLine_by_InvoiceLineId_response": { "description": "Responses from the 'delete_InvoiceLine_by_InvoiceLineId' procedure", @@ -3639,7 +3555,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_Invoice_by_InvoiceId_response": { "description": "Responses from the 'delete_Invoice_by_InvoiceId' procedure", @@ -3661,7 +3578,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_MediaType_by_MediaTypeId_response": { "description": "Responses from the 'delete_MediaType_by_MediaTypeId' procedure", @@ -3683,7 +3601,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 +3624,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_Playlist_by_PlaylistId_response": { "description": "Responses from the 'delete_Playlist_by_PlaylistId' procedure", @@ -3727,7 +3647,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_Track_by_TrackId_response": { "description": "Responses from the 'delete_Track_by_TrackId' procedure", @@ -3749,7 +3670,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_custom_defaults_by_id_response": { "description": "Responses from the 'delete_custom_defaults_by_id' procedure", @@ -3771,7 +3693,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_custom_dog_by_id_response": { "description": "Responses from the 'delete_custom_dog_by_id' procedure", @@ -3793,7 +3716,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_institution_institution_by_id_response": { "description": "Responses from the 'delete_institution_institution_by_id' procedure", @@ -3815,7 +3739,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_playlist_track": { "fields": { @@ -3837,7 +3762,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_playlist_track_response": { "description": "Responses from the 'delete_playlist_track' procedure", @@ -3859,7 +3785,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 +3808,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 +3831,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 +3854,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_topology_topology_by_id_response": { "description": "Responses from the 'delete_topology_topology_by_id' procedure", @@ -3947,7 +3877,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "delete_topology_topology_by_name_response": { "description": "Responses from the 'delete_topology_topology_by_name' procedure", @@ -3969,7 +3900,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "discoverable_types": { "fields": { @@ -3982,7 +3914,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "discoverable_types_root_occurrence": { "fields": { @@ -3995,7 +3928,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "even_numbers": { "fields": { @@ -4005,7 +3939,8 @@ expression: result "name": "even_number" } } - } + }, + "foreign_keys": {} }, "group_leader": { "fields": { @@ -4036,7 +3971,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_Album_object": { "fields": { @@ -4061,7 +3997,8 @@ expression: result "name": "varchar" } } - } + }, + "foreign_keys": {} }, "insert_Album_response": { "description": "Responses from the 'insert_Album' procedure", @@ -4083,7 +4020,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_Artist_object": { "fields": { @@ -4104,7 +4042,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_Artist_response": { "description": "Responses from the 'insert_Artist' procedure", @@ -4126,7 +4065,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_Customer_object": { "fields": { @@ -4238,7 +4178,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_Customer_response": { "description": "Responses from the 'insert_Customer' procedure", @@ -4260,7 +4201,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_Employee_object": { "fields": { @@ -4390,7 +4332,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_Employee_response": { "description": "Responses from the 'insert_Employee' procedure", @@ -4412,7 +4355,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_Genre_object": { "fields": { @@ -4431,7 +4375,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_Genre_response": { "description": "Responses from the 'insert_Genre' procedure", @@ -4453,7 +4398,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_InvoiceLine_object": { "fields": { @@ -4487,7 +4433,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "insert_InvoiceLine_response": { "description": "Responses from the 'insert_InvoiceLine' procedure", @@ -4509,7 +4456,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_Invoice_object": { "fields": { @@ -4582,7 +4530,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "insert_Invoice_response": { "description": "Responses from the 'insert_Invoice' procedure", @@ -4604,7 +4553,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_MediaType_object": { "fields": { @@ -4623,7 +4573,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_MediaType_response": { "description": "Responses from the 'insert_MediaType' procedure", @@ -4645,7 +4596,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_PlaylistTrack_object": { "fields": { @@ -4661,7 +4613,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "insert_PlaylistTrack_response": { "description": "Responses from the 'insert_PlaylistTrack' procedure", @@ -4683,7 +4636,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_Playlist_object": { "fields": { @@ -4702,7 +4656,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "insert_Playlist_response": { "description": "Responses from the 'insert_Playlist' procedure", @@ -4724,7 +4679,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_Track_object": { "fields": { @@ -4794,7 +4750,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "insert_Track_response": { "description": "Responses from the 'insert_Track' procedure", @@ -4816,7 +4773,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_album": { "fields": { @@ -4847,7 +4805,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_album_response": { "description": "Responses from the 'insert_album' procedure", @@ -4869,7 +4828,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_artist": { "fields": { @@ -4891,7 +4851,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_artist_response": { "description": "Responses from the 'insert_artist' procedure", @@ -4913,7 +4874,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_custom_defaults_object": { "fields": { @@ -4944,7 +4906,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_custom_defaults_response": { "description": "Responses from the 'insert_custom_defaults' procedure", @@ -4966,7 +4929,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_custom_dog_object": { "fields": { @@ -5000,7 +4964,8 @@ expression: result "name": "text" } } - } + }, + "foreign_keys": {} }, "insert_custom_dog_response": { "description": "Responses from the 'insert_custom_dog' procedure", @@ -5022,7 +4987,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_custom_test_cidr_object": { "fields": { @@ -5044,7 +5010,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_custom_test_cidr_response": { "description": "Responses from the 'insert_custom_test_cidr' procedure", @@ -5066,7 +5033,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_deck_of_cards_object": { "fields": { @@ -5082,7 +5050,8 @@ expression: result "name": "card_suit" } } - } + }, + "foreign_keys": {} }, "insert_deck_of_cards_response": { "description": "Responses from the 'insert_deck_of_cards' procedure", @@ -5104,7 +5073,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_discoverable_types_root_occurrence_object": { "fields": { @@ -5117,7 +5087,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_discoverable_types_root_occurrence_response": { "description": "Responses from the 'insert_discoverable_types_root_occurrence' procedure", @@ -5139,7 +5110,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_even_numbers_object": { "fields": { @@ -5149,7 +5121,8 @@ expression: result "name": "even_number" } } - } + }, + "foreign_keys": {} }, "insert_even_numbers_response": { "description": "Responses from the 'insert_even_numbers' procedure", @@ -5171,7 +5144,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_genre": { "fields": { @@ -5243,7 +5217,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_group_leader_response": { "description": "Responses from the 'insert_group_leader' procedure", @@ -5265,7 +5240,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_institution_institution_object": { "fields": { @@ -5332,7 +5308,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_institution_institution_response": { "description": "Responses from the 'insert_institution_institution' procedure", @@ -5354,7 +5331,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_phone_numbers_object": { "fields": { @@ -5364,7 +5342,8 @@ expression: result "name": "Phone" } } - } + }, + "foreign_keys": {} }, "insert_phone_numbers_response": { "description": "Responses from the 'insert_phone_numbers' procedure", @@ -5386,7 +5365,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_spatial_ref_sys_object": { "fields": { @@ -5432,7 +5412,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_spatial_ref_sys_response": { "description": "Responses from the 'insert_spatial_ref_sys' procedure", @@ -5454,7 +5435,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_text_table_object": { "fields": { @@ -5476,7 +5458,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_text_table_response": { "description": "Responses from the 'insert_text_table' procedure", @@ -5498,7 +5481,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_topology_layer_object": { "fields": { @@ -5556,7 +5540,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "insert_topology_layer_response": { "description": "Responses from the 'insert_topology_layer' procedure", @@ -5578,7 +5563,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_topology_topology_object": { "fields": { @@ -5618,7 +5604,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "insert_topology_topology_response": { "description": "Responses from the 'insert_topology_topology' procedure", @@ -5640,7 +5627,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "institution_country": { "fields": { @@ -5662,7 +5650,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "institution_institution": { "fields": { @@ -5729,7 +5718,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "institution_institution_songs": { "fields": { @@ -5751,7 +5741,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "institution_location": { "fields": { @@ -5788,7 +5779,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "institution_staff": { "fields": { @@ -5834,7 +5826,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "make_person": { "description": "A native query used to test support for composite types", @@ -5848,7 +5841,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "organization": { "fields": { @@ -5876,7 +5870,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "organization_identity_function": { "description": "A native query used to test support for composite types", @@ -5890,7 +5885,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "person": { "fields": { @@ -5912,7 +5908,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "person_address": { "description": "The address of a person, obviously", @@ -5937,7 +5934,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "person_name": { "description": "The name of a person, obviously", @@ -5962,7 +5960,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "phone_numbers": { "fields": { @@ -5972,7 +5971,8 @@ expression: result "name": "Phone" } } - } + }, + "foreign_keys": {} }, "spatial_ref_sys": { "fields": { @@ -6018,7 +6018,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "summarize_organizations": { "description": "A native query used to test support array-valued variables", @@ -6032,7 +6033,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "text_table": { "fields": { @@ -6054,7 +6056,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "topology_layer": { "fields": { @@ -6109,6 +6112,16 @@ expression: result "name": "int4" } } + }, + "foreign_keys": { + "layer_topology_id_fkey": { + "column_mapping": { + "topology_id": [ + "id" + ] + }, + "foreign_collection": "topology_topology" + } } }, "topology_topology": { @@ -6143,7 +6156,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_Album_by_AlbumId_response": { "description": "Responses from the 'update_Album_by_AlbumId' procedure", @@ -6165,7 +6179,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Album_by_AlbumId_update_columns": { "description": "Update the columns of the 'Album' collection", @@ -6200,7 +6215,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Artist_by_ArtistId_response": { "description": "Responses from the 'update_Artist_by_ArtistId' procedure", @@ -6222,7 +6238,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Artist_by_ArtistId_update_columns": { "description": "Update the columns of the 'Artist' collection", @@ -6247,7 +6264,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Customer_by_CustomerId_response": { "description": "Responses from the 'update_Customer_by_CustomerId' procedure", @@ -6269,7 +6287,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Customer_by_CustomerId_update_columns": { "description": "Update the columns of the 'Customer' collection", @@ -6404,7 +6423,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Employee_by_EmployeeId_response": { "description": "Responses from the 'update_Employee_by_EmployeeId' procedure", @@ -6426,7 +6446,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Employee_by_EmployeeId_update_columns": { "description": "Update the columns of the 'Employee' collection", @@ -6581,7 +6602,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Genre_by_GenreId_response": { "description": "Responses from the 'update_Genre_by_GenreId' procedure", @@ -6603,7 +6625,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Genre_by_GenreId_update_columns": { "description": "Update the columns of the 'Genre' collection", @@ -6628,7 +6651,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_InvoiceLine_by_InvoiceLineId_response": { "description": "Responses from the 'update_InvoiceLine_by_InvoiceLineId' procedure", @@ -6650,7 +6674,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_InvoiceLine_by_InvoiceLineId_update_columns": { "description": "Update the columns of the 'InvoiceLine' collection", @@ -6705,7 +6730,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Invoice_by_InvoiceId_response": { "description": "Responses from the 'update_Invoice_by_InvoiceId' procedure", @@ -6727,7 +6753,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Invoice_by_InvoiceId_update_columns": { "description": "Update the columns of the 'Invoice' collection", @@ -6822,7 +6849,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_MediaType_by_MediaTypeId_response": { "description": "Responses from the 'update_MediaType_by_MediaTypeId' procedure", @@ -6844,7 +6872,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_MediaType_by_MediaTypeId_update_columns": { "description": "Update the columns of the 'MediaType' collection", @@ -6869,7 +6898,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 +6921,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_PlaylistTrack_by_PlaylistId_and_TrackId_update_columns": { "description": "Update the columns of the 'PlaylistTrack' collection", @@ -6916,7 +6947,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Playlist_by_PlaylistId_response": { "description": "Responses from the 'update_Playlist_by_PlaylistId' procedure", @@ -6938,7 +6970,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Playlist_by_PlaylistId_update_columns": { "description": "Update the columns of the 'Playlist' collection", @@ -6963,7 +6996,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Track_by_TrackId_response": { "description": "Responses from the 'update_Track_by_TrackId' procedure", @@ -6985,7 +7019,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_Track_by_TrackId_update_columns": { "description": "Update the columns of the 'Track' collection", @@ -7080,7 +7115,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Album_AlbumId": { "description": "Update the 'AlbumId' column in the 'Album' collection", @@ -7092,7 +7128,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_Album_ArtistId": { "description": "Update the 'ArtistId' column in the 'Album' collection", @@ -7104,7 +7141,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_Album_Title": { "description": "Update the 'Title' column in the 'Album' collection", @@ -7116,7 +7154,8 @@ expression: result "name": "varchar" } } - } + }, + "foreign_keys": {} }, "update_column_Artist_ArtistId": { "description": "Update the 'ArtistId' column in the 'Artist' collection", @@ -7128,7 +7167,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_Artist_Name": { "description": "Update the 'Name' column in the 'Artist' collection", @@ -7143,7 +7183,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Customer_Address": { "description": "Update the 'Address' column in the 'Customer' collection", @@ -7158,7 +7199,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Customer_City": { "description": "Update the 'City' column in the 'Customer' collection", @@ -7173,7 +7215,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Customer_Company": { "description": "Update the 'Company' column in the 'Customer' collection", @@ -7188,7 +7231,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Customer_Country": { "description": "Update the 'Country' column in the 'Customer' collection", @@ -7203,7 +7247,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Customer_CustomerId": { "description": "Update the 'CustomerId' column in the 'Customer' collection", @@ -7215,7 +7260,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_Customer_Email": { "description": "Update the 'Email' column in the 'Customer' collection", @@ -7227,7 +7273,8 @@ expression: result "name": "varchar" } } - } + }, + "foreign_keys": {} }, "update_column_Customer_Fax": { "description": "Update the 'Fax' column in the 'Customer' collection", @@ -7242,7 +7289,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Customer_FirstName": { "description": "Update the 'FirstName' column in the 'Customer' collection", @@ -7254,7 +7302,8 @@ expression: result "name": "varchar" } } - } + }, + "foreign_keys": {} }, "update_column_Customer_LastName": { "description": "Update the 'LastName' column in the 'Customer' collection", @@ -7266,7 +7315,8 @@ expression: result "name": "varchar" } } - } + }, + "foreign_keys": {} }, "update_column_Customer_Phone": { "description": "Update the 'Phone' column in the 'Customer' collection", @@ -7281,7 +7331,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Customer_PostalCode": { "description": "Update the 'PostalCode' column in the 'Customer' collection", @@ -7296,7 +7347,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Customer_State": { "description": "Update the 'State' column in the 'Customer' collection", @@ -7311,7 +7363,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Customer_SupportRepId": { "description": "Update the 'SupportRepId' column in the 'Customer' collection", @@ -7326,7 +7379,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Employee_Address": { "description": "Update the 'Address' column in the 'Employee' collection", @@ -7341,7 +7395,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Employee_BirthDate": { "description": "Update the 'BirthDate' column in the 'Employee' collection", @@ -7356,7 +7411,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Employee_City": { "description": "Update the 'City' column in the 'Employee' collection", @@ -7371,7 +7427,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Employee_Country": { "description": "Update the 'Country' column in the 'Employee' collection", @@ -7386,7 +7443,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Employee_Email": { "description": "Update the 'Email' column in the 'Employee' collection", @@ -7401,7 +7459,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Employee_EmployeeId": { "description": "Update the 'EmployeeId' column in the 'Employee' collection", @@ -7413,7 +7472,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_Employee_Fax": { "description": "Update the 'Fax' column in the 'Employee' collection", @@ -7428,7 +7488,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Employee_FirstName": { "description": "Update the 'FirstName' column in the 'Employee' collection", @@ -7440,7 +7501,8 @@ expression: result "name": "varchar" } } - } + }, + "foreign_keys": {} }, "update_column_Employee_HireDate": { "description": "Update the 'HireDate' column in the 'Employee' collection", @@ -7455,7 +7517,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Employee_LastName": { "description": "Update the 'LastName' column in the 'Employee' collection", @@ -7467,7 +7530,8 @@ expression: result "name": "varchar" } } - } + }, + "foreign_keys": {} }, "update_column_Employee_Phone": { "description": "Update the 'Phone' column in the 'Employee' collection", @@ -7482,7 +7546,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Employee_PostalCode": { "description": "Update the 'PostalCode' column in the 'Employee' collection", @@ -7497,7 +7562,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Employee_ReportsTo": { "description": "Update the 'ReportsTo' column in the 'Employee' collection", @@ -7512,7 +7578,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Employee_State": { "description": "Update the 'State' column in the 'Employee' collection", @@ -7527,7 +7594,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Employee_Title": { "description": "Update the 'Title' column in the 'Employee' collection", @@ -7542,7 +7610,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Genre_GenreId": { "description": "Update the 'GenreId' column in the 'Genre' collection", @@ -7554,7 +7623,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_Genre_Name": { "description": "Update the 'Name' column in the 'Genre' collection", @@ -7569,7 +7639,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_InvoiceLine_InvoiceId": { "description": "Update the 'InvoiceId' column in the 'InvoiceLine' collection", @@ -7581,7 +7652,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_InvoiceLine_InvoiceLineId": { "description": "Update the 'InvoiceLineId' column in the 'InvoiceLine' collection", @@ -7593,7 +7665,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_InvoiceLine_Quantity": { "description": "Update the 'Quantity' column in the 'InvoiceLine' collection", @@ -7605,7 +7678,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_InvoiceLine_TrackId": { "description": "Update the 'TrackId' column in the 'InvoiceLine' collection", @@ -7617,7 +7691,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_InvoiceLine_UnitPrice": { "description": "Update the 'UnitPrice' column in the 'InvoiceLine' collection", @@ -7629,7 +7704,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "update_column_Invoice_BillingAddress": { "description": "Update the 'BillingAddress' column in the 'Invoice' collection", @@ -7644,7 +7720,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Invoice_BillingCity": { "description": "Update the 'BillingCity' column in the 'Invoice' collection", @@ -7659,7 +7736,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Invoice_BillingCountry": { "description": "Update the 'BillingCountry' column in the 'Invoice' collection", @@ -7674,7 +7752,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Invoice_BillingPostalCode": { "description": "Update the 'BillingPostalCode' column in the 'Invoice' collection", @@ -7689,7 +7768,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Invoice_BillingState": { "description": "Update the 'BillingState' column in the 'Invoice' collection", @@ -7704,7 +7784,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Invoice_CustomerId": { "description": "Update the 'CustomerId' column in the 'Invoice' collection", @@ -7716,7 +7797,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_Invoice_InvoiceDate": { "description": "Update the 'InvoiceDate' column in the 'Invoice' collection", @@ -7728,7 +7810,8 @@ expression: result "name": "timestamp" } } - } + }, + "foreign_keys": {} }, "update_column_Invoice_InvoiceId": { "description": "Update the 'InvoiceId' column in the 'Invoice' collection", @@ -7740,7 +7823,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_Invoice_Total": { "description": "Update the 'Total' column in the 'Invoice' collection", @@ -7752,7 +7836,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "update_column_MediaType_MediaTypeId": { "description": "Update the 'MediaTypeId' column in the 'MediaType' collection", @@ -7764,7 +7849,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_MediaType_Name": { "description": "Update the 'Name' column in the 'MediaType' collection", @@ -7779,7 +7865,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_PlaylistTrack_PlaylistId": { "description": "Update the 'PlaylistId' column in the 'PlaylistTrack' collection", @@ -7791,7 +7878,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_PlaylistTrack_TrackId": { "description": "Update the 'TrackId' column in the 'PlaylistTrack' collection", @@ -7803,7 +7891,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_Playlist_Name": { "description": "Update the 'Name' column in the 'Playlist' collection", @@ -7818,7 +7907,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Playlist_PlaylistId": { "description": "Update the 'PlaylistId' column in the 'Playlist' collection", @@ -7830,7 +7920,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_Track_AlbumId": { "description": "Update the 'AlbumId' column in the 'Track' collection", @@ -7845,7 +7936,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Track_Bytes": { "description": "Update the 'Bytes' column in the 'Track' collection", @@ -7860,7 +7952,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Track_Composer": { "description": "Update the 'Composer' column in the 'Track' collection", @@ -7875,7 +7968,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Track_GenreId": { "description": "Update the 'GenreId' column in the 'Track' collection", @@ -7890,7 +7984,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_Track_MediaTypeId": { "description": "Update the 'MediaTypeId' column in the 'Track' collection", @@ -7902,7 +7997,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_Track_Milliseconds": { "description": "Update the 'Milliseconds' column in the 'Track' collection", @@ -7914,7 +8010,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_Track_Name": { "description": "Update the 'Name' column in the 'Track' collection", @@ -7926,7 +8023,8 @@ expression: result "name": "varchar" } } - } + }, + "foreign_keys": {} }, "update_column_Track_TrackId": { "description": "Update the 'TrackId' column in the 'Track' collection", @@ -7938,7 +8036,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_Track_UnitPrice": { "description": "Update the 'UnitPrice' column in the 'Track' collection", @@ -7950,7 +8049,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "update_column_custom_defaults_birthday": { "description": "Update the 'birthday' column in the 'custom_defaults' collection", @@ -7962,7 +8062,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 +8075,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "update_column_custom_defaults_name": { "description": "Update the 'name' column in the 'custom_defaults' collection", @@ -7989,7 +8091,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_custom_dog_adopter_name": { "description": "Update the 'adopter_name' column in the 'custom_dog' collection", @@ -8004,7 +8107,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_custom_dog_birthday": { "description": "Update the 'birthday' column in the 'custom_dog' collection", @@ -8016,7 +8120,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 +8133,8 @@ expression: result "name": "numeric" } } - } + }, + "foreign_keys": {} }, "update_column_custom_dog_name": { "description": "Update the 'name' column in the 'custom_dog' collection", @@ -8040,7 +8146,8 @@ expression: result "name": "text" } } - } + }, + "foreign_keys": {} }, "update_column_institution_institution_departments": { "description": "Update the 'departments' column in the 'institution_institution' collection", @@ -8061,7 +8168,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_institution_institution_id": { "description": "Update the 'id' column in the 'institution_institution' collection", @@ -8073,7 +8181,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_institution_institution_location": { "description": "Update the 'location' column in the 'institution_institution' collection", @@ -8088,7 +8197,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_institution_institution_name": { "description": "Update the 'name' column in the 'institution_institution' collection", @@ -8103,7 +8213,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_institution_institution_songs": { "description": "Update the 'songs' column in the 'institution_institution' collection", @@ -8118,7 +8229,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_institution_institution_staff": { "description": "Update the 'staff' column in the 'institution_institution' collection", @@ -8139,7 +8251,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 +8267,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 +8283,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_spatial_ref_sys_proj4text": { "description": "Update the 'proj4text' column in the 'spatial_ref_sys' collection", @@ -8184,7 +8299,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_spatial_ref_sys_srid": { "description": "Update the 'srid' column in the 'spatial_ref_sys' collection", @@ -8196,7 +8312,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 +8328,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_topology_layer_child_id": { "description": "Update the 'child_id' column in the 'topology_layer' collection", @@ -8226,7 +8344,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_column_topology_layer_feature_column": { "description": "Update the 'feature_column' column in the 'topology_layer' collection", @@ -8238,7 +8357,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 +8370,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 +8383,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_topology_layer_level": { "description": "Update the 'level' column in the 'topology_layer' collection", @@ -8274,7 +8396,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 +8409,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 +8422,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 +8435,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_topology_topology_hasz": { "description": "Update the 'hasz' column in the 'topology_topology' collection", @@ -8322,7 +8448,8 @@ expression: result "name": "bool" } } - } + }, + "foreign_keys": {} }, "update_column_topology_topology_id": { "description": "Update the 'id' column in the 'topology_topology' collection", @@ -8334,7 +8461,8 @@ expression: result "name": "int4" } } - } + }, + "foreign_keys": {} }, "update_column_topology_topology_name": { "description": "Update the 'name' column in the 'topology_topology' collection", @@ -8346,7 +8474,8 @@ expression: result "name": "varchar" } } - } + }, + "foreign_keys": {} }, "update_column_topology_topology_precision": { "description": "Update the 'precision' column in the 'topology_topology' collection", @@ -8358,7 +8487,8 @@ expression: result "name": "float8" } } - } + }, + "foreign_keys": {} }, "update_column_topology_topology_srid": { "description": "Update the 'srid' column in the 'topology_topology' collection", @@ -8370,7 +8500,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 +8523,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_custom_defaults_by_id_update_columns": { "description": "Update the columns of the 'custom_defaults' collection", @@ -8427,7 +8559,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_custom_dog_by_id_response": { "description": "Responses from the 'update_custom_dog_by_id' procedure", @@ -8449,7 +8582,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_custom_dog_by_id_update_columns": { "description": "Update the columns of the 'custom_dog' collection", @@ -8494,7 +8628,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_institution_institution_by_id_response": { "description": "Responses from the 'update_institution_institution_by_id' procedure", @@ -8516,7 +8651,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_institution_institution_by_id_update_columns": { "description": "Update the columns of the 'institution_institution' collection", @@ -8581,7 +8717,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 +8740,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 +8796,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 +8819,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 +8905,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 +8928,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 +9014,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_topology_topology_by_id_response": { "description": "Responses from the 'update_topology_topology_by_id' procedure", @@ -8894,7 +9037,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_topology_topology_by_id_update_columns": { "description": "Update the columns of the 'topology_topology' collection", @@ -8949,7 +9093,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_topology_topology_by_name_response": { "description": "Responses from the 'update_topology_topology_by_name' procedure", @@ -8971,7 +9116,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "update_topology_topology_by_name_update_columns": { "description": "Update the columns of the 'topology_topology' collection", @@ -9026,7 +9172,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "value_types": { "fields": { @@ -9174,7 +9321,8 @@ expression: result } } } - } + }, + "foreign_keys": {} } }, "collections": [ @@ -9189,14 +9337,6 @@ expression: result "AlbumId" ] } - }, - "foreign_keys": { - "FK_AlbumArtistId": { - "column_mapping": { - "ArtistId": "ArtistId" - }, - "foreign_collection": "Artist" - } } }, { @@ -9210,8 +9350,7 @@ expression: result "ArtistId" ] } - }, - "foreign_keys": {} + } }, { "name": "Customer", @@ -9224,14 +9363,6 @@ expression: result "CustomerId" ] } - }, - "foreign_keys": { - "FK_CustomerSupportRepId": { - "column_mapping": { - "SupportRepId": "EmployeeId" - }, - "foreign_collection": "Employee" - } } }, { @@ -9244,14 +9375,6 @@ expression: result "EmployeeId" ] } - }, - "foreign_keys": { - "FK_EmployeeReportsTo": { - "column_mapping": { - "ReportsTo": "EmployeeId" - }, - "foreign_collection": "Employee" - } } }, { @@ -9264,8 +9387,7 @@ expression: result "GenreId" ] } - }, - "foreign_keys": {} + } }, { "name": "Invoice", @@ -9277,14 +9399,6 @@ expression: result "InvoiceId" ] } - }, - "foreign_keys": { - "FK_InvoiceCustomerId": { - "column_mapping": { - "CustomerId": "CustomerId" - }, - "foreign_collection": "Customer" - } } }, { @@ -9297,20 +9411,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 +9423,7 @@ expression: result "MediaTypeId" ] } - }, - "foreign_keys": {} + } }, { "name": "Playlist", @@ -9336,8 +9435,7 @@ expression: result "PlaylistId" ] } - }, - "foreign_keys": {} + } }, { "name": "PlaylistTrack", @@ -9350,20 +9448,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 +9460,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 +9472,7 @@ expression: result "id" ] } - }, - "foreign_keys": {} + } }, { "name": "custom_dog", @@ -9421,43 +9484,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 +9526,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 +9544,13 @@ expression: result "srid" ] } - }, - "foreign_keys": {} + } }, { "name": "text_table", "arguments": {}, "type": "text_table", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "topology_layer", @@ -9517,14 +9570,6 @@ expression: result "table_name" ] } - }, - "foreign_keys": { - "layer_topology_id_fkey": { - "column_mapping": { - "topology_id": "id" - }, - "foreign_collection": "topology_topology" - } } }, { @@ -9542,8 +9587,7 @@ expression: result "id" ] } - }, - "foreign_keys": {} + } }, { "name": "address_identity_function", @@ -9560,8 +9604,7 @@ expression: result } }, "type": "address_identity_function", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "album_by_title", @@ -9586,8 +9629,7 @@ expression: result } }, "type": "album_by_title", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "array_reverse", @@ -9608,8 +9650,7 @@ expression: result } }, "type": "array_reverse", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "array_series", @@ -9635,15 +9676,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 +9698,7 @@ expression: result } }, "type": "artist_below_id", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "count_elements", @@ -9683,8 +9721,7 @@ expression: result } }, "type": "count_elements", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "make_person", @@ -9710,8 +9747,7 @@ expression: result } }, "type": "make_person", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "organization_identity_function", @@ -9728,8 +9764,7 @@ expression: result } }, "type": "organization_identity_function", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "summarize_organizations", @@ -9752,8 +9787,7 @@ expression: result } }, "type": "summarize_organizations", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} }, { "name": "value_types", @@ -9904,8 +9938,7 @@ expression: result } }, "type": "value_types", - "uniqueness_constraints": {}, - "foreign_keys": {} + "uniqueness_constraints": {} } ], "functions": [], @@ -12057,5 +12090,12 @@ expression: result "name": "update_topology_topology_by_name_response" } } - ] + ], + "capabilities": { + "query": { + "aggregates": { + "count_scalar_type": "int8" + } + } + } } From 8fae6604c30587528f4c48d72e32602330bc3a58 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Tue, 31 Dec 2024 17:24:56 -0400 Subject: [PATCH 23/49] use exists instead of left-handed path --- ..._tests__mutation__delete_invoice_line.snap | 55 +++++------- ...ests__query__duplicate_filter_results.snap | 35 +++----- ...uery__duplicate_filter_results_nested.snap | 88 ++++++++----------- 3 files changed, 74 insertions(+), 104 deletions(-) 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 62d9ffd50..4a7f3a941 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 @@ -1,6 +1,8 @@ --- source: crates/tests/databases-tests/src/postgres/explain_tests.rs +assertion_line: 191 expression: "result.details.get(\"0 delete_InvoiceLine_by_InvoiceLineId SQL Mutation\").unwrap()" +snapshot_kind: text --- EXPLAIN WITH "%0_generated_mutation" AS ( DELETE FROM @@ -10,25 +12,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 +29,7 @@ EXPLAIN WITH "%0_generated_mutation" AS ( SELECT ( SELECT - json_build_object('result', row_to_json("%7_universe"), 'type', $1) AS "universe" + json_build_object('result', row_to_json("%6_universe"), 'type', $1) AS "universe" FROM ( SELECT @@ -44,37 +37,37 @@ SELECT FROM ( SELECT - coalesce(json_agg(row_to_json("%8_returning")), '[]') AS "returning" + coalesce(json_agg(row_to_json("%7_returning")), '[]') AS "returning" FROM ( SELECT - "%4_InvoiceLine"."InvoiceLineId" AS "invoice_line_id", - "%4_InvoiceLine"."Quantity" AS "quantity" + "%3_InvoiceLine"."InvoiceLineId" AS "invoice_line_id", + "%3_InvoiceLine"."Quantity" AS "quantity" FROM - "%0_generated_mutation" AS "%4_InvoiceLine" - ) AS "%8_returning" - ) AS "%8_returning" + "%0_generated_mutation" AS "%3_InvoiceLine" + ) AS "%7_returning" + ) AS "%7_returning" CROSS JOIN ( SELECT COUNT(*) AS "affected_rows" FROM ( SELECT - "%5_InvoiceLine".* + "%4_InvoiceLine".* FROM - "%0_generated_mutation" AS "%5_InvoiceLine" - ) AS "%6_InvoiceLine" - ) AS "%9_aggregates" - ) AS "%7_universe" + "%0_generated_mutation" AS "%4_InvoiceLine" + ) AS "%5_InvoiceLine" + ) AS "%8_aggregates" + ) AS "%6_universe" ) AS "%results", ( SELECT coalesce( bool_and( - "%10_delete_InvoiceLine_by_InvoiceLineId"."%check__constraint" + "%9_delete_InvoiceLine_by_InvoiceLineId"."%check__constraint" ), true ) AS "%check__constraint" FROM - "%0_generated_mutation" AS "%10_delete_InvoiceLine_by_InvoiceLineId" + "%0_generated_mutation" AS "%9_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 5a18435c8..85b300374 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 @@ -1,10 +1,12 @@ --- source: crates/tests/databases-tests/src/postgres/explain_tests.rs +assertion_line: 46 expression: result.details.query +snapshot_kind: text --- EXPLAIN SELECT - coalesce(json_agg(row_to_json("%3_universe")), '[]') AS "universe" + coalesce(json_agg(row_to_json("%2_universe")), '[]') AS "universe" FROM ( SELECT @@ -12,7 +14,7 @@ FROM FROM ( SELECT - coalesce(json_agg(row_to_json("%4_rows")), '[]') AS "rows" + coalesce(json_agg(row_to_json("%3_rows")), '[]') AS "rows" FROM ( SELECT @@ -22,32 +24,21 @@ 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 "%4_rows" - ) AS "%4_rows" - ) AS "%3_universe" + ) AS "%3_rows" + ) AS "%3_rows" + ) AS "%2_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 db423a753..8cbc250a9 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 @@ -1,10 +1,12 @@ --- source: crates/tests/databases-tests/src/postgres/explain_tests.rs +assertion_line: 61 expression: result.details.query +snapshot_kind: text --- EXPLAIN SELECT - coalesce(json_agg(row_to_json("%6_universe")), '[]') AS "universe" + coalesce(json_agg(row_to_json("%4_universe")), '[]') AS "universe" FROM ( SELECT @@ -12,7 +14,7 @@ FROM FROM ( SELECT - coalesce(json_agg(row_to_json("%7_rows")), '[]') AS "rows" + coalesce(json_agg(row_to_json("%5_rows")), '[]') AS "rows" FROM ( SELECT @@ -20,64 +22,48 @@ 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 "%7_rows" - ) AS "%7_rows" - ) AS "%6_universe" + ) AS "%5_rows" + ) AS "%5_rows" + ) AS "%4_universe" From 706ff968a315f5a77864f79297af78b3ff42436f Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 1 Jan 2025 16:07:32 -0400 Subject: [PATCH 24/49] right-hand side of relationship column mapping is now an array --- .../goldenfiles/aggregate_count_artist_albums.json | 2 +- .../goldenfiles/aggregate_count_artist_albums_plus_field.json | 2 +- .../tests-common/goldenfiles/dup_array_relationship.json | 2 +- .../tests-common/goldenfiles/duplicate_filter_results.json | 2 +- .../goldenfiles/duplicate_filter_results_nested.json | 4 ++-- .../goldenfiles/mutations/delete_invoice_line.json | 2 +- .../goldenfiles/mutations/insert_artist_album.json | 2 +- .../goldenfiles/mutations/insert_artist_album_bad.json | 2 +- ...ect_artist_with_album_by_title_relationship_arguments.json | 2 +- .../native_queries/select_order_by_artist_album_count.json | 2 +- .../goldenfiles/native_queries/select_sort_relationship.json | 2 +- .../goldenfiles/native_queries/select_where_relationship.json | 2 +- .../tests-common/goldenfiles/nested_array_relationships.json | 4 ++-- .../tests-common/goldenfiles/nested_field_relationship.json | 2 +- .../tests-common/goldenfiles/nested_object_relationships.json | 4 ++-- .../select_album_object_relationship_to_artist.json | 2 +- .../select_artist_array_relationship_to_album.json | 2 +- .../goldenfiles/select_order_by_album_artist_name.json | 4 ++-- .../goldenfiles/select_order_by_artist_album_count.json | 2 +- .../goldenfiles/select_order_by_artist_album_count_agg.json | 2 +- .../tests-common/goldenfiles/select_order_by_artist_name.json | 2 +- .../goldenfiles/select_order_by_artist_name_with_name.json | 2 +- .../select_track_order_by_artist_id_and_album_title.json | 2 +- ...where_album_id_equals_self_nested_object_relationship.json | 4 ++-- .../goldenfiles/select_where_array_relationship.json | 2 +- .../tests-common/goldenfiles/select_where_related_exists.json | 2 +- .../sorting_by_nested_relationship_column_with_predicate.json | 4 ++-- ...g_by_nested_relationship_column_with_predicate_exists.json | 4 ++-- .../goldenfiles/sorting_by_nested_relationship_count.json | 4 ++-- .../sorting_by_relationship_count_with_predicate.json | 4 ++-- .../goldenfiles/very_nested_recursive_relationship.json | 4 ++-- 31 files changed, 41 insertions(+), 41 deletions(-) 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..526212a5a 100644 --- a/crates/tests/tests-common/goldenfiles/duplicate_filter_results.json +++ b/crates/tests/tests-common/goldenfiles/duplicate_filter_results.json @@ -50,7 +50,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..7065dd784 100644 --- a/crates/tests/tests-common/goldenfiles/duplicate_filter_results_nested.json +++ b/crates/tests/tests-common/goldenfiles/duplicate_filter_results_nested.json @@ -85,7 +85,7 @@ "Artist_Albums": { "arguments": {}, "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album" @@ -93,7 +93,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..970089cd6 100644 --- a/crates/tests/tests-common/goldenfiles/mutations/delete_invoice_line.json +++ b/crates/tests/tests-common/goldenfiles/mutations/delete_invoice_line.json @@ -59,7 +59,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..29d876fae 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 @@ -74,7 +74,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..06e9e724c 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 @@ -57,7 +57,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..7f2e6931e 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 @@ -35,7 +35,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..4ff90c6b6 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 @@ -37,7 +37,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_nested_object_relationship.json b/crates/tests/tests-common/goldenfiles/select_where_album_id_equals_self_nested_object_relationship.json index 3aea7084f..3f2f95cd6 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 @@ -108,7 +108,7 @@ "collection_relationships": { "TrackToAlbum": { "column_mapping": { - "AlbumId": "AlbumId" + "AlbumId": ["AlbumId"] }, "relationship_type": "object", "target_collection": "Album", @@ -116,7 +116,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..805a93b83 100644 --- a/crates/tests/tests-common/goldenfiles/select_where_array_relationship.json +++ b/crates/tests/tests-common/goldenfiles/select_where_array_relationship.json @@ -75,7 +75,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_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/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..2160ac87a 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 @@ -107,7 +107,7 @@ "collection_relationships": { "ArtistAlbums": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album", @@ -115,7 +115,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..9189eab81 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 @@ -65,7 +65,7 @@ "collection_relationships": { "ArtistAlbums": { "column_mapping": { - "ArtistId": "ArtistId" + "ArtistId": ["ArtistId"] }, "relationship_type": "array", "target_collection": "Album", @@ -73,7 +73,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", From 3c5de3890052121f5b628afbfb58353719319844 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 1 Jan 2025 16:08:54 -0400 Subject: [PATCH 25/49] use exists instead of left-hand side path --- .../goldenfiles/duplicate_filter_results.json | 34 ++++---- .../duplicate_filter_results_nested.json | 82 +++++++++---------- .../mutations/delete_invoice_line.json | 30 +++---- .../select_where_relationship.json | 34 ++++---- .../select_where_array_relationship.json | 34 ++++---- 5 files changed, 103 insertions(+), 111 deletions(-) diff --git a/crates/tests/tests-common/goldenfiles/duplicate_filter_results.json b/crates/tests/tests-common/goldenfiles/duplicate_filter_results.json index 526212a5a..9b88862f1 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": { 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 7065dd784..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%" + } } } ] 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 970089cd6..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 + } } } }, 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 06e9e724c..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%" + } } } }, 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 805a93b83..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": { From 11511ed042c3d95098c1b31355e5b35f9c43db62 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 1 Jan 2025 16:11:09 -0400 Subject: [PATCH 26/49] aggregates have changed --- .../select_order_by_artist_album_count.json | 5 ++++- .../goldenfiles/select_order_by_artist_album_count.json | 5 ++++- .../select_order_by_artist_album_count_agg.json | 9 ++++++--- .../sorting_by_nested_relationship_count.json | 5 ++++- .../sorting_by_relationship_count_with_predicate.json | 5 ++++- 5 files changed, 22 insertions(+), 7 deletions(-) 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 29d876fae..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", 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 7f2e6931e..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", 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 4ff90c6b6..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", 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 2160ac87a..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", 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 9189eab81..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", From d0052c6e0348c30054363b2d595eb62b348c109e Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 1 Jan 2025 16:12:26 -0400 Subject: [PATCH 27/49] comparison target columns have been simplified --- .../select_where_album_id_equals_self.json | 7 +--- ...quals_self_nested_object_relationship.json | 39 +++++++++---------- .../goldenfiles/select_where_in_column.json | 7 +--- 3 files changed, 22 insertions(+), 31 deletions(-) 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 3f2f95cd6..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": [] + } + } + ] } } }, 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": [] } } }, From 0a15b79c0b24e0b11a1ae12b603e2454763ac69a Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 1 Jan 2025 16:13:04 -0400 Subject: [PATCH 28/49] root column comparison now replaced with scopes --- .../goldenfiles/select_where_unrelated_exists.json | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) 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 } } ] From fb69607ec92262b5de6f44e37f9ad0941acdf31f Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 1 Jan 2025 16:17:28 -0400 Subject: [PATCH 29/49] update tests to new sdk --- crates/tests/tests-common/src/router.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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) } From 6832dd9a6a220e97f487494325e8e17066eaa888 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 1 Jan 2025 16:18:54 -0400 Subject: [PATCH 30/49] add manually triggered tests to generate schema files for test file validation --- crates/tests/tests-common/Cargo.toml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) 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"] } From 37595914817aa673207d8dc3ff109bdeaac372e4 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Thu, 2 Jan 2025 17:09:42 -0400 Subject: [PATCH 31/49] remove debug print statement --- .../query-engine/translation/src/translation/query/filtering.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/query-engine/translation/src/translation/query/filtering.rs b/crates/query-engine/translation/src/translation/query/filtering.rs index 53e37e88e..8a1add751 100644 --- a/crates/query-engine/translation/src/translation/query/filtering.rs +++ b/crates/query-engine/translation/src/translation/query/filtering.rs @@ -874,8 +874,6 @@ fn get_comparison_target_type( .lookup_fields_info(&root_and_current_tables.current_table.source)? .lookup_column(name)?; - println!("Field name: {name:?}, Column Info: {column:?}"); - get_column_scalar_type_name(env, &column.r#type, &mut field_path) } ndc_models::ComparisonTarget::Aggregate { path, aggregate } => { From 35832ef1bd2c1d0d6236ab333c3f1b8a28056080 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Sat, 4 Jan 2025 19:23:37 -0400 Subject: [PATCH 32/49] Fix aggregates for 0.2.0 ndc spec expects sum aggregates return a scalar represented as either return f64 or i64 Because ndc-postgres represents i64 as a string, we only mark sum aggregates returning a f64 any other sum aggregate will function as a custom aggregate and have no special meaning additionally, we wrap SUM with `COALESCE(SUM(col), 0)` to ensure we return 0 when aggregating over no rows. similarly, we only mark avg functions returning a f64, and treat any other avg as a custom aggregate --- .../connectors/ndc-postgres/src/schema/mod.rs | 20 ++-- .../src/translation/query/aggregates.rs | 16 ++- ...ests__aggregate_limit_offset_order_by.snap | 3 +- ...schema_tests__schema_test__get_schema.snap | 101 ++++++++++++------ ...schema_tests__schema_test__get_schema.snap | 81 +++++++------- ...schema_tests__schema_test__get_schema.snap | 101 ++++++++++++------ 6 files changed, 207 insertions(+), 115 deletions(-) diff --git a/crates/connectors/ndc-postgres/src/schema/mod.rs b/crates/connectors/ndc-postgres/src/schema/mod.rs index df0da1bde..11e8e95ff 100644 --- a/crates/connectors/ndc-postgres/src/schema/mod.rs +++ b/crates/connectors/ndc-postgres/src/schema/mod.rs @@ -37,16 +37,24 @@ pub fn get_schema( .map(|(function_name, function_definition)| { ( function_name.clone(), - match function_name.as_str() { - "max" => models::AggregateFunctionDefinition::Max, - "min" => models::AggregateFunctionDefinition::Min, - "sum" => models::AggregateFunctionDefinition::Sum { + match ( + function_name.as_str(), + function_definition.return_type.as_str(), + ) { + // Mark SUM aggregations returning a f64 (float8) with the meaning tag. + // The spec wants SUM aggregations to return scalars represented as either f64 or i64 + // i64 (int8) is represented as a string, so we omit it here + ("sum", "float8") => models::AggregateFunctionDefinition::Sum { result_type: function_definition.return_type.clone().into(), }, - "average" => models::AggregateFunctionDefinition::Average { + ("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 + ("avg", "float8") => models::AggregateFunctionDefinition::Average { result_type: function_definition.return_type.clone().into(), }, - _ => models::AggregateFunctionDefinition::Custom { + (_, _) => 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. diff --git a/crates/query-engine/translation/src/translation/query/aggregates.rs b/crates/query-engine/translation/src/translation/query/aggregates.rs index 2cf75e10a..9e736d446 100644 --- a/crates/query-engine/translation/src/translation/query/aggregates.rs +++ b/crates/query-engine/translation/src/translation/query/aggregates.rs @@ -55,9 +55,23 @@ pub fn translate( }, ), ); - sql::ast::Expression::FunctionCall { + 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 {} => { 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 4be4591b6..f5921fec0 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 @@ -1,6 +1,7 @@ --- source: crates/query-engine/translation/tests/tests.rs expression: result +snapshot_kind: text --- SELECT coalesce(json_agg(row_to_json("%3_universe")), '[]') AS "universe" @@ -23,7 +24,7 @@ FROM COUNT("%2_Invoice"."InvoiceId") AS "InvoiceId_count", min("%2_Invoice"."Total") AS "Total__min", max("%2_Invoice"."Total") AS "Total__max", - sum("%2_Invoice"."Total") AS "Total__sum", + coalesce(sum("%2_Invoice"."Total"), 0) AS "Total__sum", stddev("%2_Invoice"."Total") AS "Total__stddev", COUNT(*) AS "count_all" FROM 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 4eefcfa61..e3cd1a6c5 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,5 @@ --- source: crates/tests/databases-tests/src/citus/schema_tests.rs -assertion_line: 7 expression: result snapshot_kind: text --- @@ -538,8 +537,14 @@ snapshot_kind: text } }, "sum": { - "type": "sum", - "result_type": "int8" + "type": "custom", + "result_type": { + "type": "nullable", + "underlying_type": { + "type": "named", + "name": "int8" + } + } }, "var_pop": { "type": "custom", @@ -622,14 +627,8 @@ snapshot_kind: text }, "aggregate_functions": { "avg": { - "type": "custom", - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float8" - } - } + "type": "average", + "result_type": "float8" }, "max": { "type": "max" @@ -668,8 +667,14 @@ snapshot_kind: text } }, "sum": { - "type": "sum", - "result_type": "float4" + "type": "custom", + "result_type": { + "type": "nullable", + "underlying_type": { + "type": "named", + "name": "float4" + } + } }, "var_pop": { "type": "custom", @@ -752,14 +757,8 @@ snapshot_kind: text }, "aggregate_functions": { "avg": { - "type": "custom", - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float8" - } - } + "type": "average", + "result_type": "float8" }, "max": { "type": "max" @@ -958,8 +957,14 @@ snapshot_kind: text } }, "sum": { - "type": "sum", - "result_type": "int8" + "type": "custom", + "result_type": { + "type": "nullable", + "underlying_type": { + "type": "named", + "name": "int8" + } + } }, "var_pop": { "type": "custom", @@ -1118,8 +1123,14 @@ snapshot_kind: text } }, "sum": { - "type": "sum", - "result_type": "int8" + "type": "custom", + "result_type": { + "type": "nullable", + "underlying_type": { + "type": "named", + "name": "int8" + } + } }, "var_pop": { "type": "custom", @@ -1278,8 +1289,14 @@ snapshot_kind: text } }, "sum": { - "type": "sum", - "result_type": "numeric" + "type": "custom", + "result_type": { + "type": "nullable", + "underlying_type": { + "type": "named", + "name": "numeric" + } + } }, "var_pop": { "type": "custom", @@ -1378,8 +1395,14 @@ snapshot_kind: text "type": "min" }, "sum": { - "type": "sum", - "result_type": "interval" + "type": "custom", + "result_type": { + "type": "nullable", + "underlying_type": { + "type": "named", + "name": "interval" + } + } } }, "comparison_operators": { @@ -1478,8 +1501,14 @@ snapshot_kind: text } }, "sum": { - "type": "sum", - "result_type": "numeric" + "type": "custom", + "result_type": { + "type": "nullable", + "underlying_type": { + "type": "named", + "name": "numeric" + } + } }, "var_pop": { "type": "custom", @@ -1704,8 +1733,14 @@ snapshot_kind: text "type": "min" }, "sum": { - "type": "sum", - "result_type": "interval" + "type": "custom", + "result_type": { + "type": "nullable", + "underlying_type": { + "type": "named", + "name": "interval" + } + } } }, "comparison_operators": { 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 f1e9de6ac..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,5 @@ --- source: crates/tests/databases-tests/src/cockroach/schema_tests.rs -assertion_line: 7 expression: result snapshot_kind: text --- @@ -361,14 +360,8 @@ snapshot_kind: text }, "aggregate_functions": { "avg": { - "type": "custom", - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float8" - } - } + "type": "average", + "result_type": "float8" }, "sqrdiff": { "type": "custom", @@ -495,14 +488,8 @@ snapshot_kind: text }, "aggregate_functions": { "avg": { - "type": "custom", - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float8" - } - } + "type": "average", + "result_type": "float8" }, "sqrdiff": { "type": "custom", @@ -629,14 +616,8 @@ snapshot_kind: text }, "aggregate_functions": { "avg": { - "type": "custom", - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float8" - } - } + "type": "average", + "result_type": "float8" }, "bit_and": { "type": "custom", @@ -803,14 +784,8 @@ snapshot_kind: text }, "aggregate_functions": { "avg": { - "type": "custom", - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float8" - } - } + "type": "average", + "result_type": "float8" }, "bit_and": { "type": "custom", @@ -1047,8 +1022,14 @@ snapshot_kind: text } }, "sum": { - "type": "sum", - "result_type": "numeric" + "type": "custom", + "result_type": { + "type": "nullable", + "underlying_type": { + "type": "named", + "name": "numeric" + } + } }, "sum_int": { "type": "custom", @@ -1161,8 +1142,14 @@ snapshot_kind: text } }, "sum": { - "type": "sum", - "result_type": "interval" + "type": "custom", + "result_type": { + "type": "nullable", + "underlying_type": { + "type": "named", + "name": "interval" + } + } } }, "comparison_operators": { @@ -1265,8 +1252,14 @@ snapshot_kind: text } }, "sum": { - "type": "sum", - "result_type": "numeric" + "type": "custom", + "result_type": { + "type": "nullable", + "underlying_type": { + "type": "named", + "name": "numeric" + } + } }, "var_pop": { "type": "custom", @@ -1517,8 +1510,14 @@ snapshot_kind: text } }, "sum": { - "type": "sum", - "result_type": "interval" + "type": "custom", + "result_type": { + "type": "nullable", + "underlying_type": { + "type": "named", + "name": "interval" + } + } } }, "comparison_operators": { 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 adc78d09d..9401ae387 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 @@ -1,6 +1,5 @@ --- source: crates/tests/databases-tests/src/postgres/schema_tests.rs -assertion_line: 7 expression: result --- { @@ -691,8 +690,14 @@ expression: result } }, "sum": { - "type": "sum", - "result_type": "int8" + "type": "custom", + "result_type": { + "type": "nullable", + "underlying_type": { + "type": "named", + "name": "int8" + } + } }, "var_pop": { "type": "custom", @@ -775,14 +780,8 @@ expression: result }, "aggregate_functions": { "avg": { - "type": "custom", - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float8" - } - } + "type": "average", + "result_type": "float8" }, "max": { "type": "max" @@ -821,8 +820,14 @@ expression: result } }, "sum": { - "type": "sum", - "result_type": "float4" + "type": "custom", + "result_type": { + "type": "nullable", + "underlying_type": { + "type": "named", + "name": "float4" + } + } }, "var_pop": { "type": "custom", @@ -905,14 +910,8 @@ expression: result }, "aggregate_functions": { "avg": { - "type": "custom", - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "float8" - } - } + "type": "average", + "result_type": "float8" }, "max": { "type": "max" @@ -1209,8 +1208,14 @@ expression: result } }, "sum": { - "type": "sum", - "result_type": "int8" + "type": "custom", + "result_type": { + "type": "nullable", + "underlying_type": { + "type": "named", + "name": "int8" + } + } }, "var_pop": { "type": "custom", @@ -1369,8 +1374,14 @@ expression: result } }, "sum": { - "type": "sum", - "result_type": "int8" + "type": "custom", + "result_type": { + "type": "nullable", + "underlying_type": { + "type": "named", + "name": "int8" + } + } }, "var_pop": { "type": "custom", @@ -1529,8 +1540,14 @@ expression: result } }, "sum": { - "type": "sum", - "result_type": "numeric" + "type": "custom", + "result_type": { + "type": "nullable", + "underlying_type": { + "type": "named", + "name": "numeric" + } + } }, "var_pop": { "type": "custom", @@ -1629,8 +1646,14 @@ expression: result "type": "min" }, "sum": { - "type": "sum", - "result_type": "interval" + "type": "custom", + "result_type": { + "type": "nullable", + "underlying_type": { + "type": "named", + "name": "interval" + } + } } }, "comparison_operators": { @@ -1729,8 +1752,14 @@ expression: result } }, "sum": { - "type": "sum", - "result_type": "numeric" + "type": "custom", + "result_type": { + "type": "nullable", + "underlying_type": { + "type": "named", + "name": "numeric" + } + } }, "var_pop": { "type": "custom", @@ -1983,8 +2012,14 @@ expression: result "type": "min" }, "sum": { - "type": "sum", - "result_type": "interval" + "type": "custom", + "result_type": { + "type": "nullable", + "underlying_type": { + "type": "named", + "name": "interval" + } + } } }, "comparison_operators": { From 80f483138505c4fb273cde6e8d145cf81bc0af5f Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Mon, 6 Jan 2025 19:30:04 -0400 Subject: [PATCH 33/49] fix: sums that return int8 should be marked with the meaning field --- crates/connectors/ndc-postgres/src/schema/mod.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/crates/connectors/ndc-postgres/src/schema/mod.rs b/crates/connectors/ndc-postgres/src/schema/mod.rs index 11e8e95ff..2518c1f51 100644 --- a/crates/connectors/ndc-postgres/src/schema/mod.rs +++ b/crates/connectors/ndc-postgres/src/schema/mod.rs @@ -41,12 +41,11 @@ pub fn get_schema( function_name.as_str(), function_definition.return_type.as_str(), ) { - // Mark SUM aggregations returning a f64 (float8) with the meaning tag. - // The spec wants SUM aggregations to return scalars represented as either f64 or i64 - // i64 (int8) is represented as a string, so we omit it here - ("sum", "float8") => models::AggregateFunctionDefinition::Sum { - result_type: function_definition.return_type.clone().into(), - }, + ("sum", "float8" | "int8") => { + models::AggregateFunctionDefinition::Sum { + result_type: function_definition.return_type.clone().into(), + } + } ("max", _) => models::AggregateFunctionDefinition::Max, ("min", _) => models::AggregateFunctionDefinition::Min, // Mark AVG aggregations returning a f64 (float8) with the meaning tag From f93b9439e3cd57634e368891a69f19f579ed9d23 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Wed, 8 Jan 2025 18:17:00 -0400 Subject: [PATCH 34/49] We'll need to implement filtering by aggregates later --- .../translation/src/translation/error.rs | 2 + .../src/translation/query/filtering.rs | 72 ++----------------- 2 files changed, 6 insertions(+), 68 deletions(-) diff --git a/crates/query-engine/translation/src/translation/error.rs b/crates/query-engine/translation/src/translation/error.rs index 0c13171a3..b042f255d 100644 --- a/crates/query-engine/translation/src/translation/error.rs +++ b/crates/query-engine/translation/src/translation/error.rs @@ -74,6 +74,7 @@ pub enum UnsupportedCapabilities { NestedArrays, ArrayComparison, NestedScalarCollection, + FilterByAggregate, } impl std::fmt::Display for UnsupportedCapabilities { @@ -91,6 +92,7 @@ impl std::fmt::Display for UnsupportedCapabilities { UnsupportedCapabilities::NestedScalarCollection => { write!(f, "Nested Scalar Collection") } + UnsupportedCapabilities::FilterByAggregate => write!(f, "Filter By Aggregate"), } } } diff --git a/crates/query-engine/translation/src/translation/query/filtering.rs b/crates/query-engine/translation/src/translation/query/filtering.rs index 8a1add751..f01684293 100644 --- a/crates/query-engine/translation/src/translation/query/filtering.rs +++ b/crates/query-engine/translation/src/translation/query/filtering.rs @@ -458,7 +458,7 @@ fn translate_comparison_pathelements( /// translate a comparison target. fn translate_comparison_target( env: &Env, - state: &mut State, + _state: &mut State, root_and_current_tables: &RootAndCurrentTables, column: &models::ComparisonTarget, ) -> Result<(sql::ast::Expression, Vec), Error> { @@ -485,73 +485,9 @@ fn translate_comparison_target( joins, )) } - ndc_models::ComparisonTarget::Aggregate { path, aggregate } => { - let (table_ref, joins) = - translate_comparison_pathelements(env, state, root_and_current_tables, path)?; - - match aggregate { - ndc_models::Aggregate::ColumnCount { - column, - arguments: _, - field_path, - distinct, - } => { - let collection_info = env.lookup_fields_info(&table_ref.source)?; - let ColumnInfo { name, .. } = collection_info.lookup_column(column)?; - - let column_reference = wrap_in_field_path( - &field_path.into(), - sql::ast::Expression::ColumnReference( - sql::ast::ColumnReference::TableColumn { - table: table_ref.reference.clone(), - name, - }, - ), - ); - - Ok(( - sql::ast::Expression::Count(if *distinct { - sql::ast::CountType::Distinct(Box::new(column_reference)) - } else { - sql::ast::CountType::Simple(Box::new(column_reference)) - }), - joins, - )) - } - ndc_models::Aggregate::SingleColumn { - column, - arguments: _, - field_path, - function, - } => { - let collection_info = env.lookup_fields_info(&table_ref.source)?; - let ColumnInfo { name, .. } = collection_info.lookup_column(column)?; - - let column_reference = wrap_in_field_path( - &field_path.into(), - sql::ast::Expression::ColumnReference( - sql::ast::ColumnReference::TableColumn { - table: table_ref.reference.clone(), - name, - }, - ), - ); - - Ok(( - sql::ast::Expression::FunctionCall { - function: sql::ast::Function::Unknown(function.to_string()), - args: vec![column_reference], - }, - joins, - )) - } - // todo: is this sound? this count is not targeted, but maybe that is fine? - ndc_models::Aggregate::StarCount {} => Ok(( - sql::ast::Expression::Count(sql::ast::CountType::Star), - joins, - )), - } - } + ndc_models::ComparisonTarget::Aggregate { .. } => Err(Error::CapabilityNotSupported( + UnsupportedCapabilities::FilterByAggregate, + )), } } From b38a5a16fa888602c606e2187735ef5fd9981d62 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Thu, 16 Jan 2025 12:56:56 -0400 Subject: [PATCH 35/49] add standard comparison operators, make no changes to defaults --- .../configuration/src/version3/metadata/database.rs | 4 ++++ crates/configuration/src/version3/mod.rs | 10 ++++++++++ .../configuration/src/version4/metadata/database.rs | 4 ++++ .../src/version4/to_runtime_configuration.rs | 10 ++++++++++ crates/configuration/src/version4/upgrade_from_v3.rs | 8 ++++++++ .../configuration/src/version5/metadata/database.rs | 4 ++++ .../src/version5/to_runtime_configuration.rs | 10 ++++++++++ crates/configuration/src/version5/upgrade_from_v4.rs | 8 ++++++++ crates/connectors/ndc-postgres/src/schema/mod.rs | 12 ++++++++++++ .../query-engine/metadata/src/metadata/database.rs | 4 ++++ 10 files changed, 74 insertions(+) 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 08a2155bb..9f3a0c896 100644 --- a/crates/configuration/src/version3/mod.rs +++ b/crates/configuration/src/version3/mod.rs @@ -1054,6 +1054,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/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 46d1b205e..0908d524e 100644 --- a/crates/configuration/src/version4/to_runtime_configuration.rs +++ b/crates/configuration/src/version4/to_runtime_configuration.rs @@ -349,6 +349,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/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 00457f850..483df2a19 100644 --- a/crates/configuration/src/version5/to_runtime_configuration.rs +++ b/crates/configuration/src/version5/to_runtime_configuration.rs @@ -346,6 +346,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/schema/mod.rs b/crates/connectors/ndc-postgres/src/schema/mod.rs index 2518c1f51..0ac22649b 100644 --- a/crates/connectors/ndc-postgres/src/schema/mod.rs +++ b/crates/connectors/ndc-postgres/src/schema/mod.rs @@ -81,6 +81,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 { diff --git a/crates/query-engine/metadata/src/metadata/database.rs b/crates/query-engine/metadata/src/metadata/database.rs index 20ac3682c..33298e9a1 100644 --- a/crates/query-engine/metadata/src/metadata/database.rs +++ b/crates/query-engine/metadata/src/metadata/database.rs @@ -77,6 +77,10 @@ pub struct ComparisonOperator { pub enum OperatorKind { Equal, In, + LessThan, + LessThanOrEqual, + GreaterThan, + GreaterThanOrEqual, Custom, } From 361a926646bbc3c78f64f4de77952a34b4d6a3f7 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Thu, 16 Jan 2025 12:59:19 -0400 Subject: [PATCH 36/49] schema snapshots updated to reflect changes in sum aggregates definition --- ...schema_tests__schema_test__get_schema.snap | 30 ++++--------------- ...schema_tests__schema_test__get_schema.snap | 30 ++++--------------- ..._capabilities_tests__get_capabilities.snap | 4 ++- 3 files changed, 15 insertions(+), 49 deletions(-) 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 e3cd1a6c5..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 @@ -537,14 +537,8 @@ snapshot_kind: text } }, "sum": { - "type": "custom", - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int8" - } - } + "type": "sum", + "result_type": "int8" }, "var_pop": { "type": "custom", @@ -957,14 +951,8 @@ snapshot_kind: text } }, "sum": { - "type": "custom", - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int8" - } - } + "type": "sum", + "result_type": "int8" }, "var_pop": { "type": "custom", @@ -1123,14 +1111,8 @@ snapshot_kind: text } }, "sum": { - "type": "custom", - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int8" - } - } + "type": "sum", + "result_type": "int8" }, "var_pop": { "type": "custom", 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 9401ae387..7f8834876 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 @@ -690,14 +690,8 @@ expression: result } }, "sum": { - "type": "custom", - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int8" - } - } + "type": "sum", + "result_type": "int8" }, "var_pop": { "type": "custom", @@ -1208,14 +1202,8 @@ expression: result } }, "sum": { - "type": "custom", - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int8" - } - } + "type": "sum", + "result_type": "int8" }, "var_pop": { "type": "custom", @@ -1374,14 +1362,8 @@ expression: result } }, "sum": { - "type": "custom", - "result_type": { - "type": "nullable", - "underlying_type": { - "type": "named", - "name": "int8" - } - } + "type": "sum", + "result_type": "int8" }, "var_pop": { "type": "custom", 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..66f37ed1d 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 @@ -1,6 +1,7 @@ --- source: crates/tests/databases-tests/src/capabilities_tests.rs expression: "ndc_postgres::capabilities::get_capabilities()" +snapshot_kind: text --- { "query": { @@ -9,7 +10,8 @@ expression: "ndc_postgres::capabilities::get_capabilities()" "explain": {}, "nested_fields": { "filter_by": {}, - "order_by": {} + "order_by": {}, + "aggregates": {} }, "exists": { "nested_collections": {} From 4c8bad3b7da55dd2f8117a0f4df0dd06060f0804 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Thu, 16 Jan 2025 13:00:27 -0400 Subject: [PATCH 37/49] Replace RootAndCurrentTables with TableScope, which keeps track of any tables in scope for an exists, instead of only root and current. (#674) ### What `ComparisonTarget::RootCollectionColumn` was removed, to be replaced by [named scopes](https://github.com/hasura/ndc-spec/blob/36855ff20dcbd7d129427794aee9746b895390af/rfcs/0015-named-scopes.md). This PR implements the replacement functionality. ### How This PR replaces RootAndCurrentTables, with TableScope, a struct that keeps track of the current table and any tables in scope for exists expression. See the accompanying review for details on the code itself. --- .../translation/src/translation/error.rs | 25 ++++ .../translation/src/translation/helpers.rs | 64 ++++++++- .../src/translation/mutation/v2/delete.rs | 5 +- .../src/translation/mutation/v2/insert.rs | 5 +- .../src/translation/mutation/v2/update.rs | 5 +- .../src/translation/query/filtering.rs | 135 +++++++----------- .../translation/src/translation/query/root.rs | 18 +-- .../src/translation/query/sorting.rs | 79 +++++----- ...sts__it_select_where_unrelated_exists.snap | 3 +- 9 files changed, 174 insertions(+), 165 deletions(-) diff --git a/crates/query-engine/translation/src/translation/error.rs b/crates/query-engine/translation/src/translation/error.rs index b042f255d..8c2d11ece 100644 --- a/crates/query-engine/translation/src/translation/error.rs +++ b/crates/query-engine/translation/src/translation/error.rs @@ -63,6 +63,11 @@ pub enum Error { scalar: models::ScalarTypeName, function: models::AggregateFunctionName, }, + ScopeOutOfBounds { + current_collection_name: String, + tables_in_scope_names: Vec, + scope: usize, + }, } /// Capabilities we don't currently support. @@ -237,6 +242,26 @@ impl std::fmt::Display for Error { 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 6cc936643..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 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/filtering.rs b/crates/query-engine/translation/src/translation/query/filtering.rs index f01684293..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,12 +104,12 @@ 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 { @@ -122,14 +118,11 @@ pub fn translate_expression_with_joins( name, arguments: _, field_path, - scope: _, + scope, } => { - let (table_ref, right_joins) = translate_comparison_pathelements( - env, - state, - root_and_current_tables, - path, - )?; + 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)?; @@ -169,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(), }, @@ -199,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, )?; @@ -220,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()), )?; @@ -262,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, )?, @@ -272,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 { @@ -331,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(), @@ -376,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, )?, }; @@ -414,7 +402,7 @@ fn translate_comparison_pathelements( }, )); - Ok(new_root_and_current_tables.current_table) + Ok(table) }, )?; @@ -440,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 @@ -459,7 +446,7 @@ fn translate_comparison_pathelements( fn translate_comparison_target( env: &Env, _state: &mut State, - root_and_current_tables: &RootAndCurrentTables, + current_table_scope: &TableScope, column: &models::ComparisonTarget, ) -> Result<(sql::ast::Expression, Vec), Error> { match column { @@ -468,7 +455,7 @@ fn translate_comparison_target( field_path, arguments: _, } => { - let (table_ref, joins) = (root_and_current_tables.current_table.clone(), vec![]); + 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)?; @@ -495,7 +482,7 @@ fn translate_comparison_target( fn translate_comparison_value( env: &Env, state: &mut State, - root_and_current_tables: &RootAndCurrentTables, + current_table_scope: &TableScope, value: &models::ComparisonValue, typ: &database::Type, ) -> Result<(sql::ast::Expression, Vec), Error> { @@ -505,10 +492,12 @@ fn translate_comparison_value( name, arguments: _, field_path, - scope: _, + scope, } => { + let table_source_and_reference = current_table_scope.scoped_table(scope)?; + let (table_ref, joins) = - translate_comparison_pathelements(env, state, root_and_current_tables, path)?; + 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)?; @@ -541,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 { @@ -573,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; @@ -635,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, @@ -680,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)?; @@ -746,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( @@ -782,7 +745,7 @@ pub fn translate_exists_in_collection( /// 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 { @@ -807,7 +770,7 @@ fn get_comparison_target_type( Some(field_path) => field_path.iter().collect(), }; let column = env - .lookup_fields_info(&root_and_current_tables.current_table.source)? + .lookup_fields_info(¤t_table_scope.current_table().source)? .lookup_column(name)?; get_column_scalar_type_name(env, &column.r#type, &mut field_path) @@ -832,7 +795,7 @@ fn get_comparison_target_type( let scalar_type_name = match path.last() { None => { let column = env - .lookup_fields_info(&root_and_current_tables.current_table.source)? + .lookup_fields_info(¤t_table_scope.current_table().source)? .lookup_column(column)?; get_column_scalar_type_name(env, &column.r#type, &mut field_path)? diff --git a/crates/query-engine/translation/src/translation/query/root.rs b/crates/query-engine/translation/src/translation/query/root.rs index debbb53ae..7dfba5339 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; @@ -173,26 +173,18 @@ 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); // translate where let filter = match &query.predicate { None => Ok(sql::helpers::true_expr()), - Some(predicate) => filtering::translate(env, state, &root_and_current_tables, predicate), + Some(predicate) => filtering::translate(env, state, ¤t_table_scope, predicate), }?; // Apply a join predicate if we want one. diff --git a/crates/query-engine/translation/src/translation/query/sorting.rs b/crates/query-engine/translation/src/translation/query/sorting.rs index f2a019c64..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, ) @@ -267,16 +267,12 @@ fn group_elements(elements: &[models::OrderByElement]) -> 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. @@ -303,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(), @@ -381,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" @@ -415,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)) } } @@ -448,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![]), @@ -456,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)), @@ -601,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. @@ -677,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()), @@ -841,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, @@ -852,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/snapshots/tests__it_select_where_unrelated_exists.snap b/crates/query-engine/translation/tests/snapshots/tests__it_select_where_unrelated_exists.snap index c82c9d5e7..cc00a33ce 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 @@ -1,6 +1,7 @@ --- source: crates/query-engine/translation/tests/tests.rs expression: result +snapshot_kind: text --- SELECT coalesce(json_agg(row_to_json("%2_universe")), '[]') AS "universe" @@ -29,7 +30,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 "%3_rows" From 92bb23df8c820295a1b390976d66bf394c373e53 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Thu, 16 Jan 2025 17:52:55 -0400 Subject: [PATCH 38/49] change default introspection settings to include meaning for gt(e),lt(e) operators --- .../configuration/src/version3/comparison.rs | 8 +- .../configuration/src/version4/comparison.rs | 8 +- .../configuration/src/version5/comparison.rs | 8 +- ...re_initial_configuration_is_unchanged.snap | 120 ++++++++-------- ...re_initial_configuration_is_unchanged.snap | 128 +++++++++--------- ...re_initial_configuration_is_unchanged.snap | 128 +++++++++--------- 6 files changed, 200 insertions(+), 200 deletions(-) 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/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/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/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": "<>", From c2f518e5c55ecde5139381c7d00f8e9d7a328fcb Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Mon, 20 Jan 2025 14:07:28 -0400 Subject: [PATCH 39/49] update benchmark ndc request --- benchmarks/component/benchmarks/select-order-by.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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", From 3f5e42c52554031653975846b8d743472e0c50e8 Mon Sep 17 00:00:00 2001 From: Benoit Ranque Date: Mon, 20 Jan 2025 14:18:06 -0400 Subject: [PATCH 40/49] make prettier happy --- .../configuration.json | 4 +--- .../select_array_column_reverse/request.json | 6 +----- .../configuration.json | 4 +--- .../configuration.json | 12 +++--------- .../very_nested_recursive_relationship/request.json | 2 +- .../goldenfiles/duplicate_filter_results.json | 2 +- 6 files changed, 8 insertions(+), 22 deletions(-) diff --git a/crates/query-engine/translation/tests/goldenfiles/aggregate_limit_offset_order_by/configuration.json b/crates/query-engine/translation/tests/goldenfiles/aggregate_limit_offset_order_by/configuration.json index 511337cf9..9101ba72c 100644 --- a/crates/query-engine/translation/tests/goldenfiles/aggregate_limit_offset_order_by/configuration.json +++ b/crates/query-engine/translation/tests/goldenfiles/aggregate_limit_offset_order_by/configuration.json @@ -94,9 +94,7 @@ } }, "uniquenessConstraints": { - "PK_Invoice": [ - "InvoiceId" - ] + "PK_Invoice": ["InvoiceId"] }, "foreignRelations": { "FK_InvoiceCustomerId": { diff --git a/crates/query-engine/translation/tests/goldenfiles/select_array_column_reverse/request.json b/crates/query-engine/translation/tests/goldenfiles/select_array_column_reverse/request.json index 96b772e33..460586d50 100644 --- a/crates/query-engine/translation/tests/goldenfiles/select_array_column_reverse/request.json +++ b/crates/query-engine/translation/tests/goldenfiles/select_array_column_reverse/request.json @@ -13,11 +13,7 @@ "arguments": { "array": { "type": "literal", - "value": [ - "a", - "b", - "c" - ] + "value": ["a", "b", "c"] } }, "collection_relationships": {} 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 index 5f4f47180..423a3bd98 100644 --- 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 @@ -148,9 +148,7 @@ "columnar", "columnar_internal" ], - "unqualifiedSchemasForTables": [ - "public" - ], + "unqualifiedSchemasForTables": ["public"], "unqualifiedSchemasForTypesAndProcedures": [ "public", "pg_catalog", diff --git a/crates/query-engine/translation/tests/goldenfiles/select_where_album_id_equals_self_nested_object_relationship/configuration.json b/crates/query-engine/translation/tests/goldenfiles/select_where_album_id_equals_self_nested_object_relationship/configuration.json index bb83921ef..d704c0ab8 100644 --- a/crates/query-engine/translation/tests/goldenfiles/select_where_album_id_equals_self_nested_object_relationship/configuration.json +++ b/crates/query-engine/translation/tests/goldenfiles/select_where_album_id_equals_self_nested_object_relationship/configuration.json @@ -46,9 +46,7 @@ } }, "uniquenessConstraints": { - "PK_Album": [ - "AlbumId" - ] + "PK_Album": ["AlbumId"] }, "foreignRelations": { "FK_AlbumArtistId": { @@ -82,9 +80,7 @@ } }, "uniquenessConstraints": { - "PK_Artist": [ - "ArtistId" - ] + "PK_Artist": ["ArtistId"] }, "foreignRelations": {}, "description": null @@ -167,9 +163,7 @@ } }, "uniquenessConstraints": { - "PK_Track": [ - "TrackId" - ] + "PK_Track": ["TrackId"] }, "foreignRelations": { "FK_TrackAlbumId": { 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 c2b81aa64..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 @@ -18,7 +18,7 @@ "name": { "type": "column", "column": "Name", - "arguments": {} + "arguments": {} }, "Albums": { diff --git a/crates/tests/tests-common/goldenfiles/duplicate_filter_results.json b/crates/tests/tests-common/goldenfiles/duplicate_filter_results.json index 9b88862f1..d2536fa73 100644 --- a/crates/tests/tests-common/goldenfiles/duplicate_filter_results.json +++ b/crates/tests/tests-common/goldenfiles/duplicate_filter_results.json @@ -16,7 +16,7 @@ "relationship": "Artist_Albums", "arguments": {} }, - "predicate": { + "predicate": { "type": "binary_comparison_operator", "column": { "type": "column", From 1dd91a073deac915366724870f85afc5e01c6b46 Mon Sep 17 00:00:00 2001 From: benoit Date: Sat, 1 Feb 2025 05:49:42 +0000 Subject: [PATCH 41/49] default to JSON representation if missing, instead of attempting to infer based on scalar type name --- crates/configuration/src/version3/mod.rs | 42 +++---------------- .../src/version4/to_runtime_configuration.rs | 29 ++----------- .../src/version5/to_runtime_configuration.rs | 29 ++----------- 3 files changed, 14 insertions(+), 86 deletions(-) diff --git a/crates/configuration/src/version3/mod.rs b/crates/configuration/src/version3/mod.rs index 9f3a0c896..b4c38492e 100644 --- a/crates/configuration/src/version3/mod.rs +++ b/crates/configuration/src/version3/mod.rs @@ -5,7 +5,7 @@ pub mod connection_settings; pub mod metadata; pub(crate) mod options; -use ndc_models::{self as models, CollectionName, ScalarTypeName, TypeName}; +use ndc_models::{self as models, CollectionName, TypeName}; use std::borrow::Cow; use std::collections::{BTreeMap, BTreeSet, HashSet}; use std::path::Path; @@ -714,10 +714,11 @@ fn convert_scalar_types( .cloned() .unwrap_or(BTreeMap::new()), - type_representation: convert_or_infer_type_representation( - representations.0.get(&t).cloned(), - &t, - ), + type_representation: representations + .0 + .get(&t) + .cloned() + .unwrap_or(query_engine_metadata::metadata::TypeRepresentation::Json), }, ) }) @@ -725,37 +726,6 @@ fn convert_scalar_types( ) } -/// Infer scalar type representation from scalar type name, if necessary. Defaults to JSON representation -fn convert_or_infer_type_representation( - representation: Option, - scalar_type_name: &ScalarTypeName, -) -> query_engine_metadata::metadata::TypeRepresentation { - if let Some(representation) = representation { - representation - } else { - match scalar_type_name.as_str() { - "bit" => query_engine_metadata::metadata::TypeRepresentation::String, - "bool" => query_engine_metadata::metadata::TypeRepresentation::Boolean, - "bpchar" | "char" | "varchar" | "text" => { - query_engine_metadata::metadata::TypeRepresentation::String - } - "date" => query_engine_metadata::metadata::TypeRepresentation::Date, - "float4" => query_engine_metadata::metadata::TypeRepresentation::Float32, - "float8" => query_engine_metadata::metadata::TypeRepresentation::Float64, - "int2" => query_engine_metadata::metadata::TypeRepresentation::Int16, - "int4" => query_engine_metadata::metadata::TypeRepresentation::Int32, - "int8" => query_engine_metadata::metadata::TypeRepresentation::Int64AsString, - "numeric" => query_engine_metadata::metadata::TypeRepresentation::BigDecimalAsString, - "time" => query_engine_metadata::metadata::TypeRepresentation::Time, - "timestamp" => query_engine_metadata::metadata::TypeRepresentation::Timestamp, - "timestamptz" => query_engine_metadata::metadata::TypeRepresentation::Timestamptz, - "timetz" => query_engine_metadata::metadata::TypeRepresentation::Timetz, - "uuid" => query_engine_metadata::metadata::TypeRepresentation::UUID, - _ => query_engine_metadata::metadata::TypeRepresentation::Json, - } - } -} - fn convert_aggregate_functions( aggregate_functions: metadata::AggregateFunctions, ) -> BTreeMap< diff --git a/crates/configuration/src/version4/to_runtime_configuration.rs b/crates/configuration/src/version4/to_runtime_configuration.rs index 0908d524e..9a893d19f 100644 --- a/crates/configuration/src/version4/to_runtime_configuration.rs +++ b/crates/configuration/src/version4/to_runtime_configuration.rs @@ -3,10 +3,7 @@ use std::collections::BTreeMap; -use ndc_models::ScalarTypeName; - use super::metadata; -use super::options::IntrospectionOptions; use super::ParsedConfiguration; use crate::environment::Environment; use crate::error::MakeRuntimeConfigurationError; @@ -61,7 +58,7 @@ fn convert_scalar_types( .into_iter() .map(|(scalar_type_name, scalar_type)| { ( - scalar_type_name.clone(), + scalar_type_name, query_engine_metadata::metadata::ScalarType { type_name: scalar_type.type_name, schema_name: Some(scalar_type.schema_name), @@ -76,9 +73,9 @@ fn convert_scalar_types( .into_iter() .map(|(k, v)| (k, convert_comparison_operator(v))) .collect(), - type_representation: convert_or_infer_type_representation( - scalar_type.type_representation, - &scalar_type_name, + type_representation: scalar_type.type_representation.map_or( + query_engine_metadata::metadata::TypeRepresentation::Json, + convert_type_representation, ), }, ) @@ -87,24 +84,6 @@ fn convert_scalar_types( ) } -/// Infer scalar type representation from scalar type name, if necessary. Defaults to JSON representation -fn convert_or_infer_type_representation( - representation: Option, - scalar_type_name: &ScalarTypeName, -) -> query_engine_metadata::metadata::TypeRepresentation { - if let Some(representation) = representation { - convert_type_representation(representation) - } else if let Some(representation) = IntrospectionOptions::default() - .type_representations - .0 - .get(scalar_type_name) - { - convert_type_representation(representation.to_owned()) - } else { - query_engine_metadata::metadata::TypeRepresentation::Json - } -} - fn convert_aggregate_function( aggregate_function: metadata::AggregateFunction, ) -> query_engine_metadata::metadata::AggregateFunction { diff --git a/crates/configuration/src/version5/to_runtime_configuration.rs b/crates/configuration/src/version5/to_runtime_configuration.rs index 483df2a19..4a2c733f2 100644 --- a/crates/configuration/src/version5/to_runtime_configuration.rs +++ b/crates/configuration/src/version5/to_runtime_configuration.rs @@ -3,10 +3,7 @@ use std::collections::BTreeMap; -use ndc_models::ScalarTypeName; - use super::metadata; -use super::options::IntrospectionOptions; use super::ParsedConfiguration; use crate::environment::Environment; use crate::error::MakeRuntimeConfigurationError; @@ -61,7 +58,7 @@ fn convert_scalar_types( .into_iter() .map(|(scalar_type_name, scalar_type)| { ( - scalar_type_name.clone(), + scalar_type_name, query_engine_metadata::metadata::ScalarType { type_name: scalar_type.type_name, schema_name: Some(scalar_type.schema_name), @@ -76,9 +73,9 @@ fn convert_scalar_types( .into_iter() .map(|(k, v)| (k, convert_comparison_operator(v))) .collect(), - type_representation: convert_or_infer_type_representation( - scalar_type.type_representation, - &scalar_type_name, + type_representation: scalar_type.type_representation.map_or( + query_engine_metadata::metadata::TypeRepresentation::Json, + convert_type_representation, ), }, ) @@ -87,24 +84,6 @@ fn convert_scalar_types( ) } -/// Infer scalar type representation from scalar type name, if necessary. Defaults to JSON representation -fn convert_or_infer_type_representation( - representation: Option, - scalar_type_name: &ScalarTypeName, -) -> query_engine_metadata::metadata::TypeRepresentation { - if let Some(representation) = representation { - convert_type_representation(representation) - } else if let Some(representation) = IntrospectionOptions::default() - .type_representations - .0 - .get(scalar_type_name) - { - convert_type_representation(representation.to_owned()) - } else { - query_engine_metadata::metadata::TypeRepresentation::Json - } -} - fn convert_aggregate_function( aggregate_function: metadata::AggregateFunction, ) -> query_engine_metadata::metadata::AggregateFunction { From 00d1c18a1a240f6251432937f66400850502aaec Mon Sep 17 00:00:00 2001 From: benoit Date: Sat, 1 Feb 2025 07:17:27 +0000 Subject: [PATCH 42/49] use scalar type representation instead of scalar type name when deciding whether we can mark aggregate functions --- .../connectors/ndc-postgres/src/schema/mod.rs | 42 +++++++++++++------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/crates/connectors/ndc-postgres/src/schema/mod.rs b/crates/connectors/ndc-postgres/src/schema/mod.rs index 0ac22649b..219e2cab0 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. @@ -35,24 +37,40 @@ pub fn get_schema( .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(), - match ( - function_name.as_str(), - function_definition.return_type.as_str(), - ) { - ("sum", "float8" | "int8") => { - models::AggregateFunctionDefinition::Sum { - result_type: function_definition.return_type.clone().into(), - } - } + 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), + ) => 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 - ("avg", "float8") => models::AggregateFunctionDefinition::Average { - result_type: function_definition.return_type.clone().into(), - }, + // 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 From de590f11feb14726f2574403cce23e842d77ce7b Mon Sep 17 00:00:00 2001 From: benoit Date: Sun, 2 Feb 2025 07:35:16 +0000 Subject: [PATCH 43/49] add test for returning object relationship after insert --- .../configuration.json | 379 ++++++++++++++++++ .../request.json | 72 ++++ ..._v2_insert_return_object_relationship.snap | 85 ++++ .../query-engine/translation/tests/tests.rs | 11 + 4 files changed, 547 insertions(+) create mode 100644 crates/query-engine/translation/tests/goldenfiles/mutations/v2_insert_return_object_relationship/configuration.json create mode 100644 crates/query-engine/translation/tests/goldenfiles/mutations/v2_insert_return_object_relationship/request.json create mode 100644 crates/query-engine/translation/tests/snapshots/tests__mutations__v2_insert_return_object_relationship.snap 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..920a6f010 --- /dev/null +++ b/crates/query-engine/translation/tests/goldenfiles/mutations/v2_insert_return_object_relationship/configuration.json @@ -0,0 +1,379 @@ +{ + "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 +} \ No newline at end of file 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..d641ac58f --- /dev/null +++ b/crates/query-engine/translation/tests/goldenfiles/mutations/v2_insert_return_object_relationship/request.json @@ -0,0 +1,72 @@ +{ + "$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" + } + } +} \ No newline at end of file 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..845fce967 --- /dev/null +++ b/crates/query-engine/translation/tests/snapshots/tests__mutations__v2_insert_return_object_relationship.snap @@ -0,0 +1,85 @@ +--- +source: crates/query-engine/translation/tests/tests.rs +expression: result +snapshot_kind: text +--- +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("%8_universe"), 'type', $2) AS "universe" + FROM + ( + SELECT + * + FROM + ( + SELECT + coalesce(json_agg(row_to_json("%9_returning")), '[]') AS "returning" + FROM + ( + SELECT + "%1_Album"."Title" AS "Title", + "%2_RELATIONSHIP_Artist"."Artist" AS "Artist" + FROM + "%0_generated_mutation" AS "%1_Album" + LEFT OUTER JOIN LATERAL ( + SELECT + row_to_json("%2_RELATIONSHIP_Artist") AS "Artist" + FROM + ( + SELECT + * + FROM + ( + SELECT + coalesce(json_agg(row_to_json("%4_rows")), '[]') AS "rows" + FROM + ( + SELECT + "%3_Artist"."Name" AS "Name" + FROM + "public"."Artist" AS "%3_Artist" + WHERE + ("%1_Album"."ArtistId" = "%3_Artist"."ArtistId") + ) AS "%4_rows" + ) AS "%4_rows" + ) AS "%2_RELATIONSHIP_Artist" + ) AS "%2_RELATIONSHIP_Artist" ON ('true') + ) AS "%9_returning" + ) AS "%9_returning" + CROSS JOIN ( + SELECT + COUNT(*) AS "affected_rows" + FROM + ( + SELECT + "%6_Album".* + FROM + "%0_generated_mutation" AS "%6_Album" + ) AS "%7_Album" + ) AS "%10_aggregates" + ) AS "%8_universe" + ) AS "%results", + ( + SELECT + coalesce( + bool_and("%11_v2_insert_Album"."%check__constraint"), + true + ) AS "%check__constraint" + FROM + "%0_generated_mutation" AS "%11_v2_insert_Album" + ) AS "%check__constraint"; + +COMMIT; + +[[(1, String("Lake Mannion")), (2, String("procedure"))]] diff --git a/crates/query-engine/translation/tests/tests.rs b/crates/query-engine/translation/tests/tests.rs index 3e233d598..0e02b72b2 100644 --- a/crates/query-engine/translation/tests/tests.rs +++ b/crates/query-engine/translation/tests/tests.rs @@ -447,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); + } } From a8e07e382439be4a14e37f35b3df586df4fb2acc Mon Sep 17 00:00:00 2001 From: benoit Date: Mon, 3 Feb 2025 00:30:14 +0000 Subject: [PATCH 44/49] add nested/nested array relationships to postgres, required for returning block of mutations --- crates/connectors/ndc-postgres/src/capabilities.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/connectors/ndc-postgres/src/capabilities.rs b/crates/connectors/ndc-postgres/src/capabilities.rs index 0564c7636..78646439e 100644 --- a/crates/connectors/ndc-postgres/src/capabilities.rs +++ b/crates/connectors/ndc-postgres/src/capabilities.rs @@ -37,7 +37,9 @@ pub fn get_capabilities() -> models::Capabilities { relationships: Some(models::RelationshipCapabilities { relation_comparisons: Some(models::LeafCapability {}), order_by_aggregate: Some(models::LeafCapability {}), - nested: None, + nested: Some(models::NestedRelationshipCapabilities { + array: Some(models::LeafCapability {}), + }), }), } } From eb7dce69b51b21b01ac45ac4f5090eabc4d646f6 Mon Sep 17 00:00:00 2001 From: benoit Date: Mon, 3 Feb 2025 22:54:23 +0000 Subject: [PATCH 45/49] mark nested array relationships as supported --- ...tabases_tests__capabilities_tests__get_capabilities.snap | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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 66f37ed1d..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 @@ -1,7 +1,6 @@ --- source: crates/tests/databases-tests/src/capabilities_tests.rs expression: "ndc_postgres::capabilities::get_capabilities()" -snapshot_kind: text --- { "query": { @@ -23,6 +22,9 @@ snapshot_kind: text }, "relationships": { "relation_comparisons": {}, - "order_by_aggregate": {} + "order_by_aggregate": {}, + "nested": { + "array": {} + } } } From bea5b17b495281252be042090466b1554490bf61 Mon Sep 17 00:00:00 2001 From: benoit Date: Mon, 3 Feb 2025 22:55:28 +0000 Subject: [PATCH 46/49] include types returning Int64AsString in sum functions --- crates/connectors/ndc-postgres/src/schema/mod.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/connectors/ndc-postgres/src/schema/mod.rs b/crates/connectors/ndc-postgres/src/schema/mod.rs index 219e2cab0..e26c5eafa 100644 --- a/crates/connectors/ndc-postgres/src/schema/mod.rs +++ b/crates/connectors/ndc-postgres/src/schema/mod.rs @@ -55,7 +55,11 @@ pub fn get_schema( // any other will simply be a custom sum function. eg. sum over intervals ( "sum", - Some(TypeRepresentation::Float64 | TypeRepresentation::Int64), + Some( + TypeRepresentation::Float64 + | TypeRepresentation::Int64 + | TypeRepresentation::Int64AsString, + ), ) => models::AggregateFunctionDefinition::Sum { result_type: function_definition.return_type.clone().into(), }, From 7330acc6213ed9c9a112a8c19fc9732f0910bca7 Mon Sep 17 00:00:00 2001 From: benoit Date: Mon, 3 Feb 2025 22:58:47 +0000 Subject: [PATCH 47/49] fix formating --- .../v2_insert_return_object_relationship/configuration.json | 6 ++---- .../v2_insert_return_object_relationship/request.json | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) 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 index 920a6f010..4ddcc6077 100644 --- 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 @@ -110,9 +110,7 @@ "columnar", "columnar_internal" ], - "unqualifiedSchemasForTables": [ - "public" - ], + "unqualifiedSchemasForTables": ["public"], "unqualifiedSchemasForTypesAndProcedures": [ "public", "pg_catalog", @@ -376,4 +374,4 @@ }, "mutationsVersion": "v2", "mutationsPrefix": null -} \ No newline at end of file +} 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 index d641ac58f..0c4166d87 100644 --- 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 @@ -61,12 +61,10 @@ "Album_Artist": { "arguments": {}, "column_mapping": { - "ArtistId": [ - "ArtistId" - ] + "ArtistId": ["ArtistId"] }, "relationship_type": "object", "target_collection": "Artist" } } -} \ No newline at end of file +} From 1161d5b1d63343a21535fc8317ed0f5e175782d0 Mon Sep 17 00:00:00 2001 From: Daniel Harvey Date: Fri, 14 Feb 2025 13:23:48 -0800 Subject: [PATCH 48/49] Run 0.2.0 e2e tests --- .github/workflows/e2e-tests.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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() From dfeab826bf9de6a8163fb5ea592545c585d90fa6 Mon Sep 17 00:00:00 2001 From: benoit Date: Mon, 17 Mar 2025 20:56:23 +0000 Subject: [PATCH 49/49] update snapshots --- ..._v2_insert_return_object_relationship.snap | 64 +++++++++++-------- ...t_composite_column_nested_field_count.snap | 20 +++--- ...schema_tests__schema_test__get_schema.snap | 6 +- 3 files changed, 52 insertions(+), 38 deletions(-) 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 index 845fce967..c7b0ce1b3 100644 --- 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 @@ -1,7 +1,6 @@ --- source: crates/query-engine/translation/tests/tests.rs expression: result -snapshot_kind: text --- BEGIN ISOLATION LEVEL READ COMMITTED READ WRITE; @@ -16,7 +15,12 @@ WITH "%0_generated_mutation" AS ( SELECT ( SELECT - json_build_object('result', row_to_json("%8_universe"), 'type', $2) AS "universe" + json_build_object( + 'result', + row_to_json("%10_universe"), + 'type', + $2 + ) AS "universe" FROM ( SELECT @@ -24,17 +28,22 @@ SELECT FROM ( SELECT - coalesce(json_agg(row_to_json("%9_returning")), '[]') AS "returning" + coalesce(json_agg(row_to_json("%11_returning")), '[]') AS "returning" FROM ( SELECT - "%1_Album"."Title" AS "Title", - "%2_RELATIONSHIP_Artist"."Artist" AS "Artist" + "%2_Album"."Title" AS "Title", + "%3_RELATIONSHIP_Artist"."Artist" AS "Artist" FROM - "%0_generated_mutation" AS "%1_Album" + ( + SELECT + "%1_Album".* + FROM + "%0_generated_mutation" AS "%1_Album" + ) AS "%2_Album" LEFT OUTER JOIN LATERAL ( SELECT - row_to_json("%2_RELATIONSHIP_Artist") AS "Artist" + row_to_json("%3_RELATIONSHIP_Artist") AS "Artist" FROM ( SELECT @@ -42,42 +51,47 @@ SELECT FROM ( SELECT - coalesce(json_agg(row_to_json("%4_rows")), '[]') AS "rows" + coalesce(json_agg(row_to_json("%6_rows")), '[]') AS "rows" FROM ( SELECT - "%3_Artist"."Name" AS "Name" + "%5_Artist"."Name" AS "Name" FROM - "public"."Artist" AS "%3_Artist" - WHERE - ("%1_Album"."ArtistId" = "%3_Artist"."ArtistId") - ) AS "%4_rows" - ) AS "%4_rows" - ) AS "%2_RELATIONSHIP_Artist" - ) AS "%2_RELATIONSHIP_Artist" ON ('true') - ) AS "%9_returning" - ) AS "%9_returning" + ( + 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 - "%6_Album".* + "%8_Album".* FROM - "%0_generated_mutation" AS "%6_Album" - ) AS "%7_Album" - ) AS "%10_aggregates" - ) AS "%8_universe" + "%0_generated_mutation" AS "%8_Album" + ) AS "%9_Album" + ) AS "%12_aggregates" + ) AS "%10_universe" ) AS "%results", ( SELECT coalesce( - bool_and("%11_v2_insert_Album"."%check__constraint"), + bool_and("%13_v2_insert_Album"."%check__constraint"), true ) AS "%check__constraint" FROM - "%0_generated_mutation" AS "%11_v2_insert_Album" + "%0_generated_mutation" AS "%13_v2_insert_Album" ) AS "%check__constraint"; COMMIT; 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 index 16d66bf98..5802cf467 100644 --- 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 @@ -1,11 +1,9 @@ --- source: crates/query-engine/translation/tests/tests.rs -assertion_line: 62 expression: result -snapshot_kind: text --- SELECT - coalesce(json_agg(row_to_json("%3_universe")), '[]') AS "universe" + coalesce(json_agg(row_to_json("%4_universe")), '[]') AS "universe" FROM ( SELECT @@ -13,20 +11,20 @@ FROM FROM ( SELECT - coalesce(row_to_json("%5_aggregates"), '[]') AS "aggregates" + coalesce(row_to_json("%6_aggregates"), '[]') AS "aggregates" FROM ( SELECT - COUNT(DISTINCT ("%2_persons"."person")."age") AS "different ages" + COUNT(DISTINCT ("%3_persons"."person")."age") AS "different ages" FROM ( SELECT - "%1_persons".* + "%2_persons".* FROM - "public"."persons" AS "%1_persons" - ) AS "%2_persons" - ) AS "%5_aggregates" - ) AS "%5_aggregates" - ) AS "%3_universe"; + "public"."persons" AS "%2_persons" + ) AS "%3_persons" + ) AS "%6_aggregates" + ) AS "%6_aggregates" + ) AS "%4_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 7f8834876..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 @@ -5181,7 +5181,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_genre_response": { "description": "Responses from the 'insert_genre' procedure", @@ -5203,7 +5204,8 @@ expression: result } } } - } + }, + "foreign_keys": {} }, "insert_group_leader_object": { "fields": {