Skip to content

Commit

Permalink
Merge branch 'main' into feat/query-engine-wasm32-unknown-unknown
Browse files Browse the repository at this point in the history
  • Loading branch information
jkomyno committed Dec 5, 2023
2 parents 4100e5b + 1964a5c commit c245720
Show file tree
Hide file tree
Showing 81 changed files with 2,316 additions and 226 deletions.
2 changes: 1 addition & 1 deletion .envrc
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export SIMPLE_TEST_MODE="yes" # Reduces the amount of generated `relation_link_t
### QE specific logging vars ###
export QE_LOG_LEVEL=debug # Set it to "trace" to enable query-graph debugging logs
# export PRISMA_RENDER_DOT_FILE=1 # Uncomment to enable rendering a dot file of the Query Graph from an executed query.
# export FMT_SQL=1 # Uncomment it to enable logging formatted SQL queries
export FMT_SQL=1 # Uncomment it to enable logging formatted SQL queries

### Uncomment to run driver adapters tests. See query-engine-driver-adapters.yml workflow for how tests run in CI.
# export EXTERNAL_TEST_EXECUTOR="napi"
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions libs/prisma-value/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,14 @@ impl PrismaValue {
_ => None,
}
}

pub fn as_json(&self) -> Option<&String> {
if let Self::Json(v) = self {
Some(v)
} else {
None
}
}
}

impl fmt::Display for PrismaValue {
Expand Down
3 changes: 2 additions & 1 deletion psl/builtin-connectors/src/cockroach_datamodel_connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ const CAPABILITIES: ConnectorCapabilities = enumflags2::make_bitflags!(Connector
FilteredInlineChildNestedToOneDisconnect |
InsertReturning |
UpdateReturning |
RowIn
RowIn |
LateralJoin
});

const SCALAR_TYPE_DEFAULTS: &[(ScalarType, CockroachType)] = &[
Expand Down
3 changes: 2 additions & 1 deletion psl/builtin-connectors/src/postgres_datamodel_connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ const CAPABILITIES: ConnectorCapabilities = enumflags2::make_bitflags!(Connector
InsertReturning |
UpdateReturning |
RowIn |
DistinctOn
DistinctOn |
LateralJoin
});

pub struct PostgresDatamodelConnector;
Expand Down
10 changes: 6 additions & 4 deletions psl/psl-core/src/common/preview_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ macro_rules! features {
};
}

// (Usually) Append-only list of features.
// (Usually) Append-only list of features. (alphabetically sorted)
features!(
AggregateApi,
AtomicNumberOperations,
Expand All @@ -43,7 +43,6 @@ features!(
ConnectOrCreate,
CreateMany,
DataProxy,
DistinctOn,
Deno,
Distinct,
DriverAdapters,
Expand All @@ -65,6 +64,7 @@ features!(
MultiSchema,
NamedConstraints,
NApi,
NativeDistinct,
NativeTypes,
OrderByAggregateGroup,
OrderByNulls,
Expand All @@ -77,21 +77,23 @@ features!(
TransactionApi,
UncheckedScalarInputs,
Views,
RelationJoins
);

/// Generator preview features
/// Generator preview features (alphabetically sorted)
pub const ALL_PREVIEW_FEATURES: FeatureMap = FeatureMap {
active: enumflags2::make_bitflags!(PreviewFeature::{
Deno
| DistinctOn
| DriverAdapters
| FullTextIndex
| FullTextSearch
| Metrics
| MultiSchema
| NativeDistinct
| PostgresqlExtensions
| Tracing
| Views
| RelationJoins
}),
deprecated: enumflags2::make_bitflags!(PreviewFeature::{
AtomicNumberOperations
Expand Down
3 changes: 2 additions & 1 deletion psl/psl-core/src/datamodel_connector/capabilities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ capabilities!(
InsertReturning,
UpdateReturning,
RowIn, // Connector supports (a, b) IN (c, d) expression.
DistinctOn // Connector supports DB-level distinct (e.g. postgres)
DistinctOn, // Connector supports DB-level distinct (e.g. postgres)
LateralJoin,
);

/// Contains all capabilities that the connector is able to serve.
Expand Down
2 changes: 1 addition & 1 deletion psl/psl/tests/config/generators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ fn nice_error_for_unknown_generator_preview_feature() {
.unwrap_err();

let expectation = expect![[r#"
[1;91merror[0m: [1mThe preview feature "foo" is not known. Expected one of: distinctOn, deno, driverAdapters, fullTextIndex, fullTextSearch, metrics, multiSchema, postgresqlExtensions, tracing, views[0m
[1;91merror[0m: [1mThe preview feature "foo" is not known. Expected one of: distinctOn, deno, driverAdapters, fullTextIndex, fullTextSearch, metrics, multiSchema, postgresqlExtensions, tracing, views, relationJoins[0m
--> schema.prisma:3
 | 
 2 |  provider = "prisma-client-js"
Expand Down
10 changes: 9 additions & 1 deletion quaint/src/ast/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ mod average;
mod coalesce;
mod concat;
mod count;
mod json_array_agg;
mod json_build_obj;
#[cfg(any(feature = "postgresql", feature = "mysql"))]
mod json_extract;
#[cfg(any(feature = "postgresql", feature = "mysql"))]
Expand All @@ -28,6 +30,8 @@ pub use average::*;
pub use coalesce::*;
pub use concat::*;
pub use count::*;
pub use json_array_agg::*;
pub use json_build_obj::*;
#[cfg(any(feature = "postgresql", feature = "mysql"))]
pub use json_extract::*;
#[cfg(any(feature = "postgresql", feature = "mysql"))]
Expand Down Expand Up @@ -98,6 +102,8 @@ pub(crate) enum FunctionType<'a> {
JsonExtractFirstArrayElem(JsonExtractFirstArrayElem<'a>),
#[cfg(any(feature = "postgresql", feature = "mysql"))]
JsonUnquote(JsonUnquote<'a>),
JsonArrayAgg(JsonArrayAgg<'a>),
JsonBuildObject(JsonBuildObject<'a>),
#[cfg(any(feature = "postgresql", feature = "mysql"))]
TextSearch(TextSearch<'a>),
#[cfg(any(feature = "postgresql", feature = "mysql"))]
Expand Down Expand Up @@ -154,5 +160,7 @@ function!(
Minimum,
Maximum,
Coalesce,
Concat
Concat,
JsonArrayAgg,
JsonBuildObject
);
18 changes: 18 additions & 0 deletions quaint/src/ast/function/json_array_agg.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use crate::prelude::*;

#[derive(Debug, Clone, PartialEq)]
pub struct JsonArrayAgg<'a> {
pub(crate) expr: Box<Expression<'a>>,
}

/// Builds a JSON array out of a list of values.
pub fn json_array_agg<'a, E>(expr: E) -> Function<'a>
where
E: Into<Expression<'a>>,
{
let fun = JsonArrayAgg {
expr: Box::new(expr.into()),
};

fun.into()
}
15 changes: 15 additions & 0 deletions quaint/src/ast/function/json_build_obj.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use std::borrow::Cow;

use crate::prelude::*;

#[derive(Debug, Clone, PartialEq)]
pub struct JsonBuildObject<'a> {
pub(crate) exprs: Vec<(Cow<'a, str>, Expression<'a>)>,
}

/// Builds a JSON object out of a list of key-value pairs.
pub fn json_build_object<'a>(exprs: Vec<(Cow<'a, str>, Expression<'a>)>) -> Function<'a> {
let fun = JsonBuildObject { exprs };

fun.into()
}
9 changes: 9 additions & 0 deletions quaint/src/ast/join.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::ast::{ConditionTree, Table};
pub struct JoinData<'a> {
pub(crate) table: Table<'a>,
pub(crate) conditions: ConditionTree<'a>,
pub(crate) lateral: bool,
}

impl<'a> JoinData<'a> {
Expand All @@ -13,8 +14,14 @@ impl<'a> JoinData<'a> {
Self {
table: table.into(),
conditions: ConditionTree::NoCondition,
lateral: false,
}
}

pub fn lateral(mut self) -> Self {
self.lateral = true;
self
}
}

impl<'a, T> From<T> for JoinData<'a>
Expand Down Expand Up @@ -73,6 +80,7 @@ where
JoinData {
table: self.into(),
conditions: conditions.into(),
lateral: false,
}
}
}
Expand All @@ -90,6 +98,7 @@ impl<'a> Joinable<'a> for JoinData<'a> {
JoinData {
table: self.table,
conditions,
lateral: false,
}
}
}
9 changes: 9 additions & 0 deletions quaint/src/ast/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,15 @@ impl<'a> Select<'a> {
self
}

pub fn left_join_lateral<J>(self, join: J) -> Self
where
J: Into<JoinData<'a>>,
{
let join_data: JoinData = join.into();

self.left_join(join_data.lateral())
}

/// Adds `RIGHT JOIN` clause to the query.
///
/// ```rust
Expand Down
9 changes: 9 additions & 0 deletions quaint/src/ast/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,15 @@ impl<'a> Table<'a> {
self
}

pub fn left_join_lateral<J>(self, join: J) -> Self
where
J: Into<JoinData<'a>>,
{
let join_data: JoinData = join.into();

self.left_join(join_data.lateral())
}

/// Adds an `INNER JOIN` clause to the query, specifically for that table.
/// Useful to positionally add a JOIN clause in case you are selecting from multiple tables.
///
Expand Down
41 changes: 41 additions & 0 deletions quaint/src/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,18 +188,38 @@ pub trait Visitor<'a> {
match j {
Join::Inner(data) => {
self.write(" INNER JOIN ")?;

if data.lateral {
self.write("LATERAL ")?;
}

self.visit_join_data(data)?;
}
Join::Left(data) => {
self.write(" LEFT JOIN ")?;

if data.lateral {
self.write("LATERAL ")?;
}

self.visit_join_data(data)?;
}
Join::Right(data) => {
self.write(" RIGHT JOIN ")?;

if data.lateral {
self.write("LATERAL ")?;
}

self.visit_join_data(data)?;
}
Join::Full(data) => {
self.write(" FULL JOIN ")?;

if data.lateral {
self.write("LATERAL ")?;
}

self.visit_join_data(data)?;
}
}
Expand Down Expand Up @@ -1112,6 +1132,27 @@ pub trait Visitor<'a> {
FunctionType::Concat(concat) => {
self.visit_concat(concat)?;
}
FunctionType::JsonArrayAgg(array_agg) => {
self.write("JSON_AGG")?;
self.surround_with("(", ")", |s| s.visit_expression(*array_agg.expr))?;
}
FunctionType::JsonBuildObject(build_obj) => {
let len = build_obj.exprs.len();

self.write("JSON_BUILD_OBJECT")?;
self.surround_with("(", ")", |s| {
for (i, (name, expr)) in build_obj.exprs.into_iter().enumerate() {
s.visit_raw_value(Value::text(name))?;
s.write(", ")?;
s.visit_expression(expr)?;
if i < (len - 1) {
s.write(", ")?;
}
}

Ok(())
})?;
}
};

if let Some(alias) = fun.alias {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ mod multi_schema {
insta::assert_snapshot!(
run_query!(&runner, r#"
query {
findManyCategoriesOnPosts(where: {postId: {gt: 0}}) {
findManyCategoriesOnPosts(orderBy: [{ postId: asc }, { categoryId: asc }], where: {postId: {gt: 0}}) {
category {
name
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ mod not_in_batching {
assert_error!(
runner,
"query { findManyTestModel(where: { id: { notIn: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] } }) { id }}",
2029,
"Parameter limits for this database provider require this query to be split into multiple queries, but the negation filters used prevent the query from being split. Please reduce the used values in the query."
2029 // QueryParameterLimitExceeded
);

Ok(())
Expand All @@ -30,8 +29,7 @@ mod not_in_batching_cockroachdb {
assert_error!(
runner,
"query { findManyTestModel(where: { id: { notIn: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] } }) { id }}",
2029,
"Parameter limits for this database provider require this query to be split into multiple queries, but the negation filters used prevent the query from being split. Please reduce the used values in the query."
2029 // QueryParameterLimitExceeded
);

Ok(())
Expand Down
Loading

0 comments on commit c245720

Please sign in to comment.