|
| 1 | +import { QueryCache } from '../../src'; |
| 2 | +import type { PreAggTableToTempTableNames } from '../../src'; |
| 3 | + |
| 4 | +describe('QueryCache.replacePreAggregationTableNames', () => { |
| 5 | + test('replaces a single table name', () => { |
| 6 | + const result = QueryCache.replacePreAggregationTableNames( |
| 7 | + 'SELECT * FROM dev_pre_aggregations.orders_rollup', |
| 8 | + [['dev_pre_aggregations.orders_rollup', { targetTableName: 'dev_pre_aggregations.orders_rollup_20250401_abc' }]], |
| 9 | + ); |
| 10 | + expect(result).toBe('SELECT * FROM dev_pre_aggregations.orders_rollup_20250401_abc'); |
| 11 | + }); |
| 12 | + |
| 13 | + test('does not corrupt names that are prefixes of other names (name1 vs name10)', () => { |
| 14 | + const baseName = 'dev_pre_aggregations.orders_rollup'; |
| 15 | + const entries: PreAggTableToTempTableNames[] = Array.from( |
| 16 | + { length: 12 }, |
| 17 | + (_, i): PreAggTableToTempTableNames => [ |
| 18 | + `${baseName}${i}`, |
| 19 | + { targetTableName: `(SELECT * FROM ${baseName}_20250401_part${i})` }, |
| 20 | + ], |
| 21 | + ); |
| 22 | + const query = entries |
| 23 | + .map(([tableName], i) => `SELECT * FROM ${tableName} AS "alias${i}"`) |
| 24 | + .join(' UNION ALL '); |
| 25 | + |
| 26 | + const result = QueryCache.replacePreAggregationTableNames(query, entries) as string; |
| 27 | + |
| 28 | + entries.forEach(([, { targetTableName }], i) => { |
| 29 | + expect(result).toContain(`${targetTableName} AS "alias${i}"`); |
| 30 | + }); |
| 31 | + // No stray suffix digits left behind, e.g. `...)0 AS "alias10"` |
| 32 | + expect(result).not.toMatch(/\)\d+ AS/); |
| 33 | + expect(result).not.toContain(`${baseName}10`); |
| 34 | + }); |
| 35 | + |
| 36 | + test('does not match source names inside already inserted target names', () => { |
| 37 | + // Real-world target shape: tableName + '_' + versions, so the target |
| 38 | + // of `rollup10` contains `rollup1` as a substring |
| 39 | + const entries: PreAggTableToTempTableNames[] = [ |
| 40 | + ['pa.rollup1', { targetTableName: 'pa.rollup1_aaa_bbb_111' }], |
| 41 | + ['pa.rollup10', { targetTableName: 'pa.rollup10_ccc_ddd_222' }], |
| 42 | + ]; |
| 43 | + const result = QueryCache.replacePreAggregationTableNames( |
| 44 | + 'SELECT * FROM pa.rollup10 JOIN pa.rollup1', |
| 45 | + entries, |
| 46 | + ); |
| 47 | + expect(result).toBe('SELECT * FROM pa.rollup10_ccc_ddd_222 JOIN pa.rollup1_aaa_bbb_111'); |
| 48 | + }); |
| 49 | + |
| 50 | + test('keeps params and query options for QueryWithParams input', () => { |
| 51 | + const result = QueryCache.replacePreAggregationTableNames( |
| 52 | + ['SELECT * FROM dev_pre_aggregations.orders_rollup WHERE id = ?', ['1'], { external: true }], |
| 53 | + [['dev_pre_aggregations.orders_rollup', { targetTableName: 'dev_pre_aggregations.orders_rollup_20250401_abc' }]], |
| 54 | + ); |
| 55 | + expect(result).toEqual([ |
| 56 | + 'SELECT * FROM dev_pre_aggregations.orders_rollup_20250401_abc WHERE id = ?', |
| 57 | + ['1'], |
| 58 | + { external: true }, |
| 59 | + ]); |
| 60 | + }); |
| 61 | + |
| 62 | + test('returns query as is for empty replacements', () => { |
| 63 | + const result = QueryCache.replacePreAggregationTableNames('SELECT 1', []); |
| 64 | + expect(result).toBe('SELECT 1'); |
| 65 | + }); |
| 66 | + |
| 67 | + test('treats $ in target names literally', () => { |
| 68 | + const result = QueryCache.replacePreAggregationTableNames( |
| 69 | + 'SELECT * FROM pa.rollup', |
| 70 | + [['pa.rollup', { targetTableName: 'pa.rollup_$&_$1' }]], |
| 71 | + ); |
| 72 | + expect(result).toBe('SELECT * FROM pa.rollup_$&_$1'); |
| 73 | + }); |
| 74 | + |
| 75 | + test('does not mutate the incoming array order', () => { |
| 76 | + const entries: PreAggTableToTempTableNames[] = [ |
| 77 | + ['name1', { targetTableName: 'target1' }], |
| 78 | + ['name10', { targetTableName: 'target10' }], |
| 79 | + ]; |
| 80 | + QueryCache.replacePreAggregationTableNames('SELECT * FROM name1, name10', entries); |
| 81 | + expect(entries.map(([tableName]) => tableName)).toEqual(['name1', 'name10']); |
| 82 | + }); |
| 83 | +}); |
0 commit comments