Add support for DateTime filters in PostgreSQL#3728
Draft
ArjunNarendra wants to merge 6 commits into
Draft
Conversation
…ately describe the source of the exception
Contributor
There was a problem hiding this comment.
Pull request overview
This PR aims to fix PostgreSQL GraphQL filter failures for date/time columns (issue #3094) by ensuring filter parameter values are converted from raw GraphQL string values into the appropriate .NET types (DateTime / DateTimeOffset) before being added as DB parameters, preventing PostgreSQL from treating them as text.
Changes:
- Override
BaseSqlQueryStructure.MakeDbConnectionParamto pre-parse PostgreSQL column parameters fromstringinto the column’s inferred .NET system type before delegating to the base parameter creation logic. - Minor GraphQL schema-generation refactors/cleanups (including primary key directive usage changes and DocumentNode composition changes).
- Improve/clarify several metadata-provider exception messages and update related comments/constants organization.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Service.GraphQLBuilder/Sql/SchemaConverter.cs | Adjusts schema generation docs and changes how the primaryKey directive is emitted for PK fields. |
| src/Service.GraphQLBuilder/GraphQLTypes/SupportedTypes.cs | Reorganizes date/time-related type constants and updates comments. |
| src/Core/Services/MetadataProviders/SqlMetadataProvider.cs | Improves exception messages and clarifies a schema-fill comment. |
| src/Core/Services/GraphQLSchemaCreator.cs | Refactors schema assembly and uses WithDefinitions when composing root DocumentNode. |
| src/Core/Resolvers/Sql Query Structures/BaseSqlQueryStructure.cs | Adds PostgreSQL-specific parameter type pre-processing in MakeDbConnectionParam to address date/time filter casting issues. |
Comment on lines
179
to
183
| List<DirectiveNode> directives = new(); | ||
| if (sourceDefinition.PrimaryKey.Contains(columnName)) | ||
| { | ||
| directives.Add(new DirectiveNode(PrimaryKeyDirectiveType.DirectiveName, new ArgumentNode("databaseType", column.SystemType.Name))); | ||
| directives.Add(new DirectiveNode(PrimaryKeyDirectiveType.DirectiveName)); | ||
| } |
Comment on lines
+89
to
+93
| public override string MakeDbConnectionParam(object? value, string? paramName = null, bool lengthOverride = false) | ||
| { | ||
| if (MetadataProvider.GetDatabaseType() is DatabaseType.PostgreSQL && | ||
| !string.IsNullOrEmpty(paramName) && | ||
| value is string stringValue && |
Comment on lines
45
to
+48
| public const string DATE_TYPE = "date"; | ||
| public const string SMALLDATETIME_TYPE = "smalldatetime"; | ||
| public const string DATETIME2_TYPE = "datetime2"; | ||
| public const string DATETIMEOFFSET_TYPE = "DateTimeOffset"; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why make this change?
This pull request is to address #3094, which is a bug that happens because certain date/time SQL parameters are not being parsed to their appropriate .NET type (
DateTimeorDateTimeOffset) and are instead being treated as raw text. This is leading to type conversion issues when executing the underlying SQL query.What is this change?
I have provided an overridden implementation of
MakeDbConnectionParaminBaseSqlQueryStructure.cs. This method does some extra pre-processing for PostgreSQL parameters specifically by parsing each parameter into its appropriate system type before calling the base class implementation ofMakeDbConnectionParaminBaseQueryStructure.cs. The system type of each parameter is retrieved from metadata of the underlying column that this parameter corresponds to via the methodGetColumnSystemType. This change fixes the relevant issue because now parameters which correspond to an underlyingdatetimecolumn in the schema are cast to their appropriate .NET type instead of falling through as text before building the final SQL query. Furthermore, this change is limited in scope to apply this parameter casting only when the underlying database is PostgreSQL. This ensures we do not see unexpected behavior with other database types where this sort of parameter casting may be unnecessary and/or erroneous.My original thought was to modify the method
ExtractValueFromIValueNodeinExecutionHelper.csto explicitly handle anIValueNodewith a GraphQL scalar type ofSupportedHotChocolateTypes.DATETIME_TYPEby parsing theIValueNodeas aDateTimesystem type before being returned. For all practical purposes, this has the same desired effect as parsing the parameter inMakeDbConnectionParam, but the call toExtractValueFromIValueNodehappens upstream of the call toMakeDbConnectionParam. However, I decided against this approach because it would be more difficult to make this change only apply to PostgreSQL here because we have no easy way to overrideExtractValueFromIValueNodein subclasses like we do withMakeDbConnectionParam. While it is still technically possible to add the mapping and then special case based on the database type, I thought this would not be as clear as the other approach.How was this tested?
Sample Request(s)
With query:
Before:
After: