From b80e798ecd88ef9185860f35b333395bc7187060 Mon Sep 17 00:00:00 2001 From: Joshen Lim Date: Tue, 22 Jul 2025 16:32:46 +0800 Subject: [PATCH] Table editor cast column type to text if filtering with like based filter (#37341) * Table editor cast column type to text if filtering with like based filter * Update pg-meta tests * Fix test cases for ~~ in advanced-query.test * Fix tests in table-row-query.test --- packages/pg-meta/src/query/Query.utils.ts | 13 +++++++++++-- packages/pg-meta/test/query/advanced-query.test.ts | 8 ++++---- packages/pg-meta/test/query/query.test.ts | 4 +++- packages/pg-meta/test/query/table-row-query.test.ts | 8 ++++---- 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/packages/pg-meta/src/query/Query.utils.ts b/packages/pg-meta/src/query/Query.utils.ts index ee39000b24d..47e2bb9f78f 100644 --- a/packages/pg-meta/src/query/Query.utils.ts +++ b/packages/pg-meta/src/query/Query.utils.ts @@ -1,5 +1,5 @@ -import { ident, literal, format } from '../pg-format' -import type { Filter, QueryPagination, QueryTable, Sort, Dictionary } from './types' +import { format, ident, literal } from '../pg-format' +import type { Dictionary, Filter, QueryPagination, QueryTable, Sort } from './types' export function countQuery( table: QueryTable, @@ -171,6 +171,11 @@ function applyFilters(query: string, filters: Filter[]) { return inFilterSql(filter) case 'is': return isFilterSql(filter) + case '~~': + case '~~*': + case '!~~': + case '!~~*': + return castColumnToText(filter) default: return `${ident(filter.column)} ${filter.operator} ${filterLiteral(filter.value)}` } @@ -203,6 +208,10 @@ function isFilterSql(filter: Filter) { } } +function castColumnToText(filter: Filter) { + return `${ident(filter.column)}::text ${filter.operator} ${filterLiteral(filter.value)}` +} + function filterLiteral(value: any) { if (typeof value === 'string') { if (value?.startsWith('ARRAY[') && value?.endsWith(']')) { diff --git a/packages/pg-meta/test/query/advanced-query.test.ts b/packages/pg-meta/test/query/advanced-query.test.ts index 0af6aac201c..3abaf6dad79 100644 --- a/packages/pg-meta/test/query/advanced-query.test.ts +++ b/packages/pg-meta/test/query/advanced-query.test.ts @@ -1,6 +1,6 @@ -import { expect, test, describe, afterAll } from 'vitest' +import { afterAll, describe, expect, test } from 'vitest' import { Query } from '../../src/query/Query' -import { createTestDatabase, cleanupRoot } from '../db/utils' +import { cleanupRoot, createTestDatabase } from '../db/utils' type TestDb = Awaited> @@ -343,7 +343,7 @@ describe('Advanced Query Tests', () => { .toSql() expect(sql).toMatchInlineSnapshot( - `"select id, name from public.normal_table where id > 10 and name ~~ '%John%' order by normal_table.name asc nulls last limit 10 offset 0;"` + `"select id, name from public.normal_table where id > 10 and name::text ~~ '%John%' order by normal_table.name asc nulls last limit 10 offset 0;"` ) const result = await validateSql(db, sql) @@ -444,7 +444,7 @@ describe('Advanced Query Tests', () => { .toSql() expect(sql).toMatchInlineSnapshot( - '"select count(*) from public.normal_table where name ~~ \'%John%\';"' + '"select count(*) from public.normal_table where name::text ~~ \'%John%\';"' ) const result = await validateSql(db, sql) diff --git a/packages/pg-meta/test/query/query.test.ts b/packages/pg-meta/test/query/query.test.ts index f149435977f..0302f41efc6 100644 --- a/packages/pg-meta/test/query/query.test.ts +++ b/packages/pg-meta/test/query/query.test.ts @@ -515,7 +515,9 @@ describe('End-to-end query chaining', () => { .filter('name', '~~', '%John%') .toSql() - expect(sql).toBe("select id, name, email from public.users where id > 10 and name ~~ '%John%';") + expect(sql).toBe( + "select id, name, email from public.users where id > 10 and name::text ~~ '%John%';" + ) }) test('should correctly build a select query with match criteria', () => { diff --git a/packages/pg-meta/test/query/table-row-query.test.ts b/packages/pg-meta/test/query/table-row-query.test.ts index c72c98546c2..62645f9012a 100644 --- a/packages/pg-meta/test/query/table-row-query.test.ts +++ b/packages/pg-meta/test/query/table-row-query.test.ts @@ -1,8 +1,8 @@ -import { expect, test, describe, afterAll, beforeAll } from 'vitest' -import { createTestDatabase, cleanupRoot } from '../db/utils' +import { afterAll, beforeAll, describe, expect, test } from 'vitest' import pgMeta from '../../src/index' +import { Filter, Sort } from '../../src/query' import { getDefaultOrderByColumns, getTableRowsSql } from '../../src/query/table-row-query' -import { Sort, Filter } from '../../src/query' +import { cleanupRoot, createTestDatabase } from '../db/utils' beforeAll(async () => { // Any global setup if needed @@ -1098,7 +1098,7 @@ describe('Table Row Query', () => { // Verify SQL generation with snapshot expect(sql).toMatchInlineSnapshot( ` - "with _base_query as (select * from public.test_sql_filter where name ~~ 'Test%' and category = 'A' order by test_sql_filter.id asc nulls last limit 10 offset 0) + "with _base_query as (select * from public.test_sql_filter where name::text ~~ 'Test%' and category = 'A' order by test_sql_filter.id asc nulls last limit 10 offset 0) select id,case when octet_length(name::text) > 10240 then left(name::text, 10240) || '...'