SQLishParser.spec.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import {SQLishParser} from 'sentry/views/starfish/utils/sqlish/SQLishParser';
  2. describe('SQLishParser', function () {
  3. describe('SQLishParser()', () => {
  4. const parser = new SQLishParser();
  5. it.each([
  6. 'SELECT;',
  7. 'SELECT hello;',
  8. 'SELECT *;', // Wildcards
  9. 'WHERE age = 10;', // Equality
  10. 'WHERE age != 10;', // Inequality
  11. 'total / time', // Division
  12. 'sum(age)::numeric(0, 5)', // Type casting
  13. 'WHERE age > 10 AND age < 20;', // Comparison
  14. "WHERE$1 ILIKE ' % ' || 'text'", // Conditionals
  15. 'SELECT id, name;', // Column lists
  16. 'columns AS `tags[column]`', // ClickHouse backtics
  17. 'SELECT * FROM #temp', // Temporary tables
  18. '# Fetches', // Comments
  19. 'SELECT id, nam*', // Truncation
  20. 'AND created >= :c1', // PHP-Style I
  21. 'LIMIT $2', // PHP-style II
  22. 'created >= %s', // Python-style
  23. 'created >= $1', // Rails-style
  24. '@@ to_tsquery', // Postgres full-text search
  25. 'flags & %s)', // Bitwise AND
  26. 'flags | %s)', // Bitwise OR
  27. 'flags ^ %s)', // Bitwise XOR
  28. 'flags ~ %s)', // Bitwise NOT
  29. 'FROM temp{%s}', // Relay integer stripping
  30. '+ %s as count', // Arithmetic I
  31. '- %s as count', // Arithmetic II
  32. "ILIKE '\\_')", // Backslash
  33. ])('Parses %s', sql => {
  34. expect(() => {
  35. parser.parse(sql);
  36. }).not.toThrow();
  37. });
  38. });
  39. describe('SQLishParser.parse', () => {
  40. const parser = new SQLishParser();
  41. it('Distinguishes between real keywords and interpolated words', () => {
  42. expect(parser.parse('SELECT country')).toEqual([
  43. {
  44. type: 'Keyword',
  45. content: 'SELECT',
  46. },
  47. {
  48. type: 'Whitespace',
  49. content: ' ',
  50. },
  51. {
  52. type: 'GenericToken',
  53. content: 'country',
  54. },
  55. ]);
  56. expect(parser.parse('SELECT discount')).toEqual([
  57. {
  58. type: 'Keyword',
  59. content: 'SELECT',
  60. },
  61. {
  62. type: 'Whitespace',
  63. content: ' ',
  64. },
  65. {
  66. type: 'GenericToken',
  67. content: 'discount',
  68. },
  69. ]);
  70. });
  71. it('Detects collapsed columns', () => {
  72. expect(parser.parse('select ..')).toEqual([
  73. {
  74. type: 'Keyword',
  75. content: 'SELECT',
  76. },
  77. {
  78. type: 'Whitespace',
  79. content: ' ',
  80. },
  81. {
  82. type: 'CollapsedColumns',
  83. content: '..',
  84. },
  85. ]);
  86. });
  87. it('Detects whitespace between generic tokens and JOIN commands', () => {
  88. expect(parser.parse('sentry_users INNER JOIN sentry_messages')).toEqual([
  89. {
  90. type: 'GenericToken',
  91. content: 'sentry_users',
  92. },
  93. {type: 'Whitespace', content: ' '},
  94. {type: 'Keyword', content: 'INNER'},
  95. {type: 'Whitespace', content: ' '},
  96. {type: 'Keyword', content: 'JOIN'},
  97. {type: 'Whitespace', content: ' '},
  98. {
  99. type: 'GenericToken',
  100. content: 'sentry_messages',
  101. },
  102. ]);
  103. });
  104. });
  105. });