MsSqlValidation.tsx78 lines · main
1// @ts-nocheck
2import type { ComponentType, ReactNode } from 'react'
3import { Admonition } from 'ui-patterns'
4
5import type { Filter, Sort } from './types'
6import { isMsSqlForeignTable, type Entity } from '@/data/table-editor/table-editor-types'
7
8type ValidateMsSqlSortingParams = {
9 filters: Filter[]
10 sorts: Sort[]
11 table: Entity
12}
13
14type 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 */
23export 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
55type MsSqlAdmonitionProps = {
56 title: string
57 children: string
58}
59
60const 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
66const 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
73const 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)