diff --git a/apps/studio/components/grid/MsSqlValidation.tsx b/apps/studio/components/grid/MsSqlValidation.tsx new file mode 100644 index 00000000000..b6951f4c514 --- /dev/null +++ b/apps/studio/components/grid/MsSqlValidation.tsx @@ -0,0 +1,77 @@ +import { isMsSqlForeignTable, type Entity } from 'data/table-editor/table-editor-types' +import type { ComponentType, ReactNode } from 'react' + +import { Admonition } from 'ui-patterns' +import type { Filter, Sort } from './types' + +type ValidateMsSqlSortingParams = { + filters: Filter[] + sorts: Sort[] + table: Entity +} + +type MsSqlWarning = 'ConflictingSort' | 'NoValidSortPossible' + +/** + * There is an edge case with the Postgres query planner and MS SQL foreign + * tables, where the Postgres query planner will drop sort clauses that are + * redundant with filters, resulting in invalid MS SQL syntax. We want to + * detect any conflicting or impossible sorts on filtered columns when the + * table is an MS SQL foreign table, and warn the user. + */ +export const validateMsSqlSorting = ({ + filters, + sorts, + table, +}: ValidateMsSqlSortingParams): + | { warning: MsSqlWarning; Component: ComponentType } + | { warning: null } => { + const isMsSql = isMsSqlForeignTable(table) + if (!isMsSql) return { warning: null } + + const equalityFilterColumns = new Set( + filters + .filter((filter) => filter.operator === '=' || filter.operator === 'is') + .map((filter) => filter.column) + ) + + const conflictingSort = + sorts.length > 0 && sorts.every((sort) => equalityFilterColumns.has(sort.column)) + const showMsSqlSortWarning = equalityFilterColumns.size > 0 && !!conflictingSort + if (showMsSqlSortWarning) + return { warning: 'ConflictingSort', Component: MsSqlSortWarningAdmonition } + + const noSortColumnsRemaining = + table.columns.length > 0 && + table.columns.every((col) => col.data_type === 'json' || equalityFilterColumns.has(col.name)) + const showMsSqlNoValidSortWarning = filters.length > 0 && noSortColumnsRemaining + if (showMsSqlNoValidSortWarning) + return { warning: 'NoValidSortPossible', Component: MsSqlNoValidSortAdmonition } + + return { warning: null } +} + +type MsSqlAdmonitionProps = { + title: string + children: string +} + +const MsSqlAdmonition = ({ title, children }: MsSqlAdmonitionProps): ReactNode => ( +