[Bug]: Incorrect parsing of default values when GQL context variables are used
Consider the table definition for type_table:
The column float_types is a column which has a default value of 1.1. Now, if we execute a GQL create mutation on this table and:
- Provide input using GQL context variables
- Omit value for the
float_typescolumn (since it has a default value so we don't need to specify it)
We get an error:
{
"errors": [
{
"message": "Float cannot parse the given literal of type `StringValueNode`.",
"path": [
"item",
"float_types"
],
"extensions": {
"field": "CreateSupportedTypeInput.float_types",
"fieldType": "Float"
}
}
]
}
Similar behavior was observed when int_types was given a default value.
The only way I got the request to succeed was to set the variable's content to:
{
"item": {
"int_types": 1,
"float_types": 3.1,
"uuid_types": "e4826b30-1cbb-4ee1-b09e-b76205a77074"
}
}
Exception stack trace which indicates that HotChocolate detects that only some of the fields of the mutation are provided and attempts to resolve default values for the remainder of the fields. This violates our assumption that nullable fields are left null. As a result, my current hypothesis is that our GraphQL schema creation may have added default values..
Yes our schema creation added default value directives. But the Types look inaccurate. I see "String" type which aligns with error message from hot chocolate:
SchemaConverter::CreateValueNodeFromDbObjectMetadata(object metadataValue) at fault
The caller passes in DatabasePrimitives.ColumnDefinition.DefaultValue which doesn't preserve the actual type of the value.
Then most likely hits the conversion for string before the actual number types:
We need to use the code written in #1883 to handle the following default values returned by sql and create a function to remove parenthesis in default values:
// Remove parens:
// 1. built_in funtions are surrounded by single parenthesis,i.e. (getdate())
// 2. string will be with parenthesis and single quotes, i.e. ('value')
// 3. int/float will be with double parenthesis, i.e. ((20))
The current form of default value looks to always be a string due to the parens. not sure why this doesn't fail requests that don't provide GraphQL parameters and provide field values for mutations directly in requests.
This change is more involved and would benefit from sufficient time to test and devise an appropriate solution for all database types because all database types utilize default values but their SDKs (SQL Client and mysql/pg equivalent may return default values differently).