MsSqlValidation.tsx78 lines · main
| 1 | // @ts-nocheck |
| 2 | import type { ComponentType, ReactNode } from 'react' |
| 3 | import { Admonition } from 'ui-patterns' |
| 4 | |
| 5 | import type { Filter, Sort } from './types' |
| 6 | import { isMsSqlForeignTable, type Entity } from '@/data/table-editor/table-editor-types' |
| 7 | |
| 8 | type ValidateMsSqlSortingParams = { |
| 9 | filters: Filter[] |
| 10 | sorts: Sort[] |
| 11 | table: Entity |
| 12 | } |
| 13 | |
| 14 | type MsSqlWarning = 'ConflictingSort' | 'NoValidSortPossible' |
| 15 | |
| 16 | /** |
| 17 | * There is an edge case with the Postgres query planner and MS SQL foreign |
| 18 | * tables, where the Postgres query planner will drop sort clauses that are |
| 19 | * redundant with filters, resulting in invalid MS SQL syntax. We want to |
| 20 | * detect any conflicting or impossible sorts on filtered columns when the |
| 21 | * table is an MS SQL foreign table, and warn the user. |
| 22 | */ |
| 23 | export const validateMsSqlSorting = ({ |
| 24 | filters, |
| 25 | sorts, |
| 26 | table, |
| 27 | }: ValidateMsSqlSortingParams): |
| 28 | | { warning: MsSqlWarning; Component: ComponentType } |
| 29 | | { warning: null } => { |
| 30 | const isMsSql = isMsSqlForeignTable(table) |
| 31 | if (!isMsSql) return { warning: null } |
| 32 | |
| 33 | const equalityFilterColumns = new Set( |
| 34 | filters |
| 35 | .filter((filter) => filter.operator === '=' || filter.operator === 'is') |
| 36 | .map((filter) => filter.column) |
| 37 | ) |
| 38 | |
| 39 | const conflictingSort = |
| 40 | sorts.length > 0 && sorts.every((sort) => equalityFilterColumns.has(sort.column)) |
| 41 | const showMsSqlSortWarning = equalityFilterColumns.size > 0 && !!conflictingSort |
| 42 | if (showMsSqlSortWarning) |
| 43 | return { warning: 'ConflictingSort', Component: MsSqlSortWarningAdmonition } |
| 44 | |
| 45 | const noSortColumnsRemaining = |
| 46 | table.columns.length > 0 && |
| 47 | table.columns.every((col) => col.data_type === 'json' || equalityFilterColumns.has(col.name)) |
| 48 | const showMsSqlNoValidSortWarning = filters.length > 0 && noSortColumnsRemaining |
| 49 | if (showMsSqlNoValidSortWarning) |
| 50 | return { warning: 'NoValidSortPossible', Component: MsSqlNoValidSortAdmonition } |
| 51 | |
| 52 | return { warning: null } |
| 53 | } |
| 54 | |
| 55 | type MsSqlAdmonitionProps = { |
| 56 | title: string |
| 57 | children: string |
| 58 | } |
| 59 | |
| 60 | const MsSqlAdmonition = ({ title, children }: MsSqlAdmonitionProps): ReactNode => ( |
| 61 | <div className="mt-2 px-3 pb-2"> |
| 62 | <Admonition type="warning" title={title} description={children} /> |
| 63 | </div> |
| 64 | ) |
| 65 | |
| 66 | const MsSqlSortWarningAdmonition = (): ReactNode => ( |
| 67 | <MsSqlAdmonition title="Cannot sort by filtered column"> |
| 68 | Sorting only by columns filtered with "=" or "is" doesn't work on MSSQL tables. Pick a different |
| 69 | sorting column, or add a column not in your filter. |
| 70 | </MsSqlAdmonition> |
| 71 | ) |
| 72 | |
| 73 | const MsSqlNoValidSortAdmonition = (): ReactNode => ( |
| 74 | <MsSqlAdmonition title="No valid sort column remaining"> |
| 75 | All columns that can be sorted have been filtered with "=" or "is", which doesn't work on MSSQL |
| 76 | tables. Remove a column from your filter to continue. |
| 77 | </MsSqlAdmonition> |
| 78 | ) |