Skip to content

Commit

Permalink
refactor(parserdb): improve validation of dbgenerated()
Browse files Browse the repository at this point in the history
  • Loading branch information
tomhoule committed Jun 1, 2022
1 parent b2c0912 commit 377d7ce
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 27 deletions.
Expand Up @@ -330,7 +330,7 @@ fn must_error_on_dbgenerated_default() {
let error = datamodel::parse_schema(schema).map(drop).unwrap_err();

let expected = expect![[r#"
[1;91merror[0m: [1mError parsing attribute "@default": The function `dbgenerated()` is not supported on composite fields.[0m
[1;91merror[0m: [1mError parsing attribute "@default": Fields of composite types cannot have dbgenerated() defaults.[0m
--> schema.prisma:3
 | 
 2 |  type User {
Expand Down
2 changes: 1 addition & 1 deletion libs/datamodel/core/tests/attributes/default_negative.rs
Expand Up @@ -373,7 +373,7 @@ fn must_error_if_scalar_default_on_unsupported() {
let error = datamodel::parse_schema(dml).map(drop).unwrap_err();

let expectation = expect![[r#"
[1;91merror[0m: [1mError parsing attribute "@default": Only @default(dbgenerated()) can be used for Unsupported types.[0m
[1;91merror[0m: [1mError parsing attribute "@default": Only @default(dbgenerated("...")) can be used for Unsupported types.[0m
--> schema.prisma:8
 | 
 7 |  id Int @id
Expand Down
51 changes: 26 additions & 25 deletions libs/datamodel/parser-database/src/attributes/default.rs
Expand Up @@ -33,6 +33,15 @@ pub(super) fn visit_model_field_default(
field_data.default = Some(default_value);
};

// @default(dbgenerated(...)) is always valid.
match value.value {
ast::Expression::Function(name, funcargs, _span) if name == FN_DBGENERATED => {
validate_dbgenerated_args(&funcargs.arguments, accept, ctx);
return;
}
_ => (),
}

// Resolve the default to a DefaultValue. We must loop in order to
// resolve type aliases.
let mut r#type = field_data.r#type;
Expand Down Expand Up @@ -61,13 +70,11 @@ pub(super) fn visit_model_field_default(
r#type = ctx.types.type_aliases[&alias_id];
continue;
}
ScalarFieldType::Unsupported(_) => match value.value {
ast::Expression::Function(funcname, funcargs, _) if funcname == FN_DBGENERATED => {
validate_dbgenerated_args(&funcargs.arguments, accept, ctx);
}
_ => ctx
.push_attribute_validation_error("Only @default(dbgenerated()) can be used for Unsupported types."),
},
ScalarFieldType::Unsupported(_) => {
ctx.push_attribute_validation_error(
"Only @default(dbgenerated(\"...\")) can be used for Unsupported types.",
);
}
}

break;
Expand Down Expand Up @@ -105,6 +112,15 @@ pub(super) fn visit_composite_field_default(
field_data.default = Some(default_value);
};

// @default(dbgenerated(...)) is never valid on a composite type's fields.
match value.value {
ast::Expression::Function(name, ..) if name == FN_DBGENERATED => {
ctx.push_attribute_validation_error("Fields of composite types cannot have dbgenerated() defaults.");
return;
}
_ => (),
}

// Resolve the default to a DefaultValue. We must loop in order to
// resolve type aliases.
match field_data.r#type {
Expand Down Expand Up @@ -192,10 +208,6 @@ fn validate_model_builtin_scalar_type_default(
validate_auto_args(&funcargs.arguments, accept, ctx)
}

(_, ast::Expression::Function(funcname, funcargs, _)) if funcname == FN_DBGENERATED => {
validate_dbgenerated_args(&funcargs.arguments, accept, ctx)
}

(_, ast::Expression::Function(funcname, _, _)) if !KNOWN_FUNCTIONS.contains(&funcname.as_str()) => {
ctx.types.unknown_function_defaults.push(field_id);
accept();
Expand Down Expand Up @@ -234,9 +246,7 @@ fn validate_composite_builtin_scalar_type_default(
(ScalarType::DateTime, ast::Expression::Function(funcname, funcargs, _)) if funcname == FN_NOW => {
validate_empty_function_args(FN_NOW, &funcargs.arguments, accept, ctx)
}
(_, ast::Expression::Function(funcname, _, _))
if funcname == FN_DBGENERATED || funcname == FN_AUTOINCREMENT || funcname == FN_AUTO =>
{
(_, ast::Expression::Function(funcname, _, _)) if funcname == FN_AUTOINCREMENT || funcname == FN_AUTO => {
ctx.push_attribute_validation_error(&format!(
"The function `{funcname}()` is not supported on composite fields.",
));
Expand Down Expand Up @@ -386,9 +396,6 @@ fn validate_enum_default(
validate_invalid_default_enum_value(enum_value, ctx);
}
}
ast::Expression::Function(funcname, funcargs, _) if funcname == FN_DBGENERATED => {
validate_dbgenerated_args(&funcargs.arguments, accept, ctx);
}
bad_value => validate_invalid_default_enum_expr(bad_value, ctx),
};
}
Expand All @@ -402,7 +409,7 @@ fn validate_enum_list_default(
match found_value {
ast::Expression::Array(values, _) => {
let mut valid = true;
let mut enum_values = values.into_iter();
let mut enum_values = values.iter();
while let (true, Some(enum_value)) = (valid, enum_values.next()) {
valid = false;
validate_enum_default(
Expand All @@ -419,9 +426,6 @@ fn validate_enum_list_default(
accept();
}
}
ast::Expression::Function(funcname, funcargs, _) if funcname == FN_DBGENERATED => {
validate_dbgenerated_args(&funcargs.arguments, accept, ctx);
}
bad_value => validate_invalid_default_enum_expr(bad_value, ctx),
};
}
Expand All @@ -435,7 +439,7 @@ fn validate_builtin_scalar_list_default(
match found_value {
ast::Expression::Array(values, _) => {
let mut valid = true;
let mut values = values.into_iter();
let mut values = values.iter();
while let (true, Some(value)) = (valid, values.next()) {
valid = false;
validate_scalar_default_literal(
Expand All @@ -452,9 +456,6 @@ fn validate_builtin_scalar_list_default(
accept()
}
}
ast::Expression::Function(funcname, funcargs, _) if funcname == FN_DBGENERATED => {
validate_dbgenerated_args(&funcargs.arguments, accept, ctx);
}
_bad_value => ctx.push_attribute_validation_error("The default value of a list field must be a list."),
}
}
Expand Down

0 comments on commit 377d7ce

Please sign in to comment.