diff --git a/packages/twenty-server/src/engine/api/common/common-query-runners/common-find-many-query-runner.service.ts b/packages/twenty-server/src/engine/api/common/common-query-runners/common-find-many-query-runner.service.ts index 27d69594cd..f1f0c13916 100644 --- a/packages/twenty-server/src/engine/api/common/common-query-runners/common-find-many-query-runner.service.ts +++ b/packages/twenty-server/src/engine/api/common/common-query-runners/common-find-many-query-runner.service.ts @@ -124,7 +124,7 @@ export class CommonFindManyQueryRunnerService extends CommonBaseQueryRunnerServi isForwardPagination, ); - appliedFilters = (args.filter + appliedFilters = (args.filter && Object.keys(args.filter).length > 0 ? { and: [args.filter, { or: cursorArgFilter }], } diff --git a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/compute-where-condition-parts.ts b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/compute-where-condition-parts.ts index 84a174b35d..957bf9efea 100644 --- a/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/compute-where-condition-parts.ts +++ b/packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/compute-where-condition-parts.ts @@ -1,6 +1,6 @@ import { randomBytes } from 'crypto'; -import { type FieldMetadataType } from 'twenty-shared/types'; +import { FieldMetadataType } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; import { type ObjectLiteral } from 'typeorm'; @@ -43,6 +43,8 @@ export const computeWhereConditionParts = ({ ? `"${key}"` : `"${objectNameSingular}"."${key}"`; + const isDateTimeField = fieldMetadataType === FieldMetadataType.DATE_TIME; + //TODO : Remove filter null equivalence injection once feature flag removed + null equivalence transformation added in ORM const nullEquivalentFieldValue = findPostgresDefaultNullEquivalentValue( value, @@ -59,16 +61,37 @@ export const computeWhereConditionParts = ({ params: {}, }; case 'eq': + if (isDateTimeField) { + return { + sql: `(${fieldReference} >= :${key}${paramSuffix} AND ${fieldReference} < :${key}${paramSuffix}::timestamptz + interval '1 millisecond')${hasNullEquivalentFieldValue ? ` OR ${fieldReference} IS NULL` : ''}`, + params: { [`${key}${paramSuffix}`]: value }, + }; + } + return { sql: `${fieldReference} = :${key}${paramSuffix}${hasNullEquivalentFieldValue ? ` OR ${fieldReference} IS NULL` : ''}`, params: { [`${key}${paramSuffix}`]: value }, }; case 'neq': + if (isDateTimeField) { + return { + sql: `(${fieldReference} < :${key}${paramSuffix} OR ${fieldReference} >= :${key}${paramSuffix}::timestamptz + interval '1 millisecond')${hasNullEquivalentFieldValue ? ` AND ${fieldReference} IS NOT NULL` : ''}`, + params: { [`${key}${paramSuffix}`]: value }, + }; + } + return { sql: `${fieldReference} != :${key}${paramSuffix}${hasNullEquivalentFieldValue ? ` AND ${fieldReference} IS NOT NULL` : ''}`, params: { [`${key}${paramSuffix}`]: value }, }; case 'gt': + if (isDateTimeField) { + return { + sql: `${fieldReference} >= :${key}${paramSuffix}::timestamptz + interval '1 millisecond'`, + params: { [`${key}${paramSuffix}`]: value }, + }; + } + return { sql: `${fieldReference} > :${key}${paramSuffix}`, params: { [`${key}${paramSuffix}`]: value }, @@ -84,6 +107,13 @@ export const computeWhereConditionParts = ({ params: { [`${key}${paramSuffix}`]: value }, }; case 'lte': + if (isDateTimeField) { + return { + sql: `${fieldReference} < :${key}${paramSuffix}::timestamptz + interval '1 millisecond'`, + params: { [`${key}${paramSuffix}`]: value }, + }; + } + return { sql: `${fieldReference} <= :${key}${paramSuffix}`, params: { [`${key}${paramSuffix}`]: value },