MsSqlValidation.tsx 2.7 KB

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