Skip to content

Commit

Permalink
qe/ci: add env var for default relation load strategy (#4746)
Browse files Browse the repository at this point in the history
* add env var for forcing relation strategy

* Default to RLS::Join if no env set

* add relation_load_strategy to qe ci tests matrix

---------

Co-authored-by: Alexey Orlenko <alex@aqrln.net>
  • Loading branch information
Druue and aqrln committed Mar 8, 2024
1 parent 0b70883 commit 3d9a0d6
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 6 deletions.
12 changes: 11 additions & 1 deletion .github/workflows/test-query-engine.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ concurrency:

jobs:
rust-query-engine-tests:
name: "${{ matrix.database.name }} - ${{ matrix.engine_protocol }} ${{ matrix.partition }}"
name: "${{ matrix.database.name }} - ${{ matrix.engine_protocol }} ${{ matrix.relation_load_strategy }} ${{ matrix.partition }}"

strategy:
fail-fast: false
Expand Down Expand Up @@ -60,7 +60,16 @@ jobs:
connector: "cockroachdb"
version: "22.1"
engine_protocol: [graphql, json]
relation_load_strategy: [join, query]
partition: ["1/4", "2/4", "3/4", "4/4"]
exclude:
- relation_load_strategy: join
database:
[
{ "connector": "mongodb" },
{ "connector": "sqlite" },
{ "connector": "mssql_2022" },
]

env:
LOG_LEVEL: "info"
Expand All @@ -75,6 +84,7 @@ jobs:
TEST_CONNECTOR: ${{ matrix.database.connector }}
TEST_CONNECTOR_VERSION: ${{ matrix.database.version }}
PRISMA_ENGINE_PROTOCOL: ${{ matrix.engine_protocol }}
PRISMA_RELATION_LOAD_STRATEGY: ${{ matrix.relation_load_strategy }}

runs-on: ubuntu-latest
steps:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ mod m2m {
schema.to_owned()
}

// https://github.com/prisma/prisma/issues/16390
// ! (https://github.com/prisma/prisma/issues/16390) - Skip on RLS::Query
#[connector_test(schema(schema_16390), relation_mode = "prisma", only(Postgres))]
async fn repro_16390(runner: Runner) -> TestResult<()> {
run_query!(&runner, r#"mutation { createOneCategory(data: {}) { id } }"#);
Expand All @@ -225,12 +225,18 @@ mod m2m {
run_query!(&runner, r#"mutation { deleteOneItem(where: { id: 1 }) { id } }"#);

insta::assert_snapshot!(
run_query!(&runner, r#"{ findUniqueItem(where: { id: 1 }) { id categories { id } } }"#),
run_query!(&runner, r#"{
findUniqueItem(relationLoadStrategy: join, where: { id: 1 })
{ id categories { id } }
}"#),
@r###"{"data":{"findUniqueItem":null}}"###
);

insta::assert_snapshot!(
run_query!(&runner, r#"{ findUniqueCategory(where: { id: 1 }) { id items { id } } }"#),
run_query!(&runner, r#"{
findUniqueCategory(relationLoadStrategy: join, where: { id: 1 })
{ id items { id } }
}"#),
@r###"{"data":{"findUniqueCategory":{"id":1,"items":[]}}}"###
);

Expand Down
16 changes: 14 additions & 2 deletions query-engine/core/src/query_graph_builder/read/utils.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::*;
use crate::{ArgumentListLookup, FieldPair, ParsedField, ReadQuery};
use once_cell::sync::Lazy;
use psl::datamodel_connector::{ConnectorCapability, JoinStrategySupport};
use query_structure::{native_distinct_compatible_with_order_by, prelude::*, RelationLoadStrategy};
use schema::{
Expand Down Expand Up @@ -259,6 +260,12 @@ pub(crate) fn get_relation_load_strategy(
nested_queries: &[ReadQuery],
query_schema: &QuerySchema,
) -> QueryGraphBuilderResult<RelationLoadStrategy> {
static DEFAULT_RELATION_LOAD_STRATEGY: Lazy<Option<RelationLoadStrategy>> = Lazy::new(|| {
std::env::var("PRISMA_RELATION_LOAD_STRATEGY")
.map(|e| e.as_str().try_into().unwrap())
.ok()
});

match query_schema.join_strategy_support() {
// Connector and database version supports the `Join` strategy...
JoinStrategySupport::Yes => match requested_strategy {
Expand All @@ -269,8 +276,13 @@ pub(crate) fn get_relation_load_strategy(
}
// But requested strategy is `Query`.
Some(RelationLoadStrategy::Query) => Ok(RelationLoadStrategy::Query),
// And requested strategy is `Join` or there's none selected, in which case the default is still `Join`.
Some(RelationLoadStrategy::Join) | None => Ok(RelationLoadStrategy::Join),
// Or requested strategy is `Join`.
Some(RelationLoadStrategy::Join) => Ok(RelationLoadStrategy::Join),
// or there's none selected, in which case we check for an envar else `Join`.
None => match *DEFAULT_RELATION_LOAD_STRATEGY {
Some(rls) => Ok(rls),
None => Ok(RelationLoadStrategy::Join),
},
},
// Connector supports `Join` strategy but database version does not...
JoinStrategySupport::UnsupportedDbVersion => match requested_strategy {
Expand Down
16 changes: 16 additions & 0 deletions query-engine/query-structure/src/query_arguments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,22 @@ impl RelationLoadStrategy {
}
}

impl TryFrom<&str> for RelationLoadStrategy {
type Error = crate::error::DomainError;

fn try_from(value: &str) -> crate::Result<Self> {
// todo(team-orm#947) We ideally use the `load_strategy` enum defined in schema/constants, but first we need to extract the `schema-constants` crate.
match value {
"join" => Ok(RelationLoadStrategy::Join),
"query" => Ok(RelationLoadStrategy::Query),
_ => Err(DomainError::ConversionFailure(
value.to_owned(),
"RelationLoadStrategy".to_owned(),
)),
}
}
}

impl std::fmt::Debug for QueryArguments {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("QueryArguments")
Expand Down

0 comments on commit 3d9a0d6

Please sign in to comment.