Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions ir/queries/queries.sql
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,13 @@ WITH column_base AS (
END
WHEN dt.typtype = 'b' THEN
-- Non-array base types: qualify if not in pg_catalog or table's schema
-- Use format_type to preserve typmod for extension types (e.g., vector(384) for pgvector)
CASE
WHEN dn.nspname = 'pg_catalog' THEN c.udt_name
WHEN dn.nspname = c.table_schema THEN dt.typname
ELSE dn.nspname || '.' || dt.typname
WHEN dn.nspname = c.table_schema THEN
dt.typname || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '')
ELSE
dn.nspname || '.' || dt.typname || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '')
END
ELSE c.udt_name
END AS resolved_type,
Expand Down Expand Up @@ -201,10 +204,13 @@ WITH column_base AS (
END
WHEN dt.typtype = 'b' THEN
-- Non-array base types: qualify if not in pg_catalog or table's schema
-- Use format_type to preserve typmod for extension types (e.g., vector(384) for pgvector)
CASE
WHEN dn.nspname = 'pg_catalog' THEN c.udt_name
WHEN dn.nspname = c.table_schema THEN dt.typname
ELSE dn.nspname || '.' || dt.typname
WHEN dn.nspname = c.table_schema THEN
dt.typname || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '')
ELSE
dn.nspname || '.' || dt.typname || COALESCE(substring(format_type(a.atttypid, a.atttypmod) FROM '\([^)]*\)'), '')
END
ELSE c.udt_name
END AS resolved_type,
Expand Down
14 changes: 10 additions & 4 deletions ir/queries/queries.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions testdata/diff/create_table/issue_295_pgvector_typmod/diff.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE activity ADD COLUMN embedding halfvec(384);
CREATE INDEX IF NOT EXISTS activity_embedding_idx ON activity USING hnsw (embedding halfvec_cosine_ops);
9 changes: 9 additions & 0 deletions testdata/diff/create_table/issue_295_pgvector_typmod/new.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-- Desired state: add pgvector columns with dimensions (typmod)
-- Reproduces GitHub issue #295 where vector(384)/halfvec(384) dimensions were dropped
CREATE TABLE public.activity (
id bigserial PRIMARY KEY,
embedding halfvec(384)
);

CREATE INDEX activity_embedding_idx
ON activity USING hnsw (embedding halfvec_cosine_ops);
4 changes: 4 additions & 0 deletions testdata/diff/create_table/issue_295_pgvector_typmod/old.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- Initial state: table without vector columns
CREATE TABLE public.activity (
id bigserial PRIMARY KEY
);
44 changes: 44 additions & 0 deletions testdata/diff/create_table/issue_295_pgvector_typmod/plan.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"version": "1.0.0",
"pgschema_version": "1.7.1",
"created_at": "1970-01-01T00:00:00Z",
"source_fingerprint": {
"hash": "0000000000000000000000000000000000000000000000000000000000000000"
},
"groups": [
{
"steps": [
{
"sql": "ALTER TABLE activity ADD COLUMN embedding halfvec(384);",
"type": "table.column",
"operation": "create",
"path": "public.activity.embedding"
}
]
},
{
"steps": [
{
"sql": "CREATE INDEX CONCURRENTLY IF NOT EXISTS activity_embedding_idx ON activity USING hnsw (embedding halfvec_cosine_ops);",
"type": "table.index",
"operation": "create",
"path": "public.activity.activity_embedding_idx"
}
]
},
{
"steps": [
{
"sql": "SELECT \n COALESCE(i.indisvalid, false) as done,\n CASE \n WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total\n ELSE 0\n END as progress\nFROM pg_class c\nLEFT JOIN pg_index i ON c.oid = i.indexrelid\nLEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid\nWHERE c.relname = 'activity_embedding_idx';",
"directive": {
"type": "wait",
"message": "Creating index activity_embedding_idx"
},
"type": "table.index",
"operation": "create",
"path": "public.activity.activity_embedding_idx"
}
]
}
]
}
15 changes: 15 additions & 0 deletions testdata/diff/create_table/issue_295_pgvector_typmod/plan.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
ALTER TABLE activity ADD COLUMN embedding halfvec(384);

CREATE INDEX CONCURRENTLY IF NOT EXISTS activity_embedding_idx ON activity USING hnsw (embedding halfvec_cosine_ops);

-- pgschema:wait
SELECT
COALESCE(i.indisvalid, false) as done,
CASE
WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total
ELSE 0
END as progress
FROM pg_class c
LEFT JOIN pg_index i ON c.oid = i.indexrelid
LEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid
WHERE c.relname = 'activity_embedding_idx';
28 changes: 28 additions & 0 deletions testdata/diff/create_table/issue_295_pgvector_typmod/plan.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
Plan: 1 to modify.

Summary by type:
tables: 1 to modify

Tables:
~ activity
+ embedding (column)
+ activity_embedding_idx (index)

DDL to be executed:
--------------------------------------------------

ALTER TABLE activity ADD COLUMN embedding halfvec(384);

CREATE INDEX CONCURRENTLY IF NOT EXISTS activity_embedding_idx ON activity USING hnsw (embedding halfvec_cosine_ops);

-- pgschema:wait
SELECT
COALESCE(i.indisvalid, false) as done,
CASE
WHEN p.blocks_total > 0 THEN p.blocks_done * 100 / p.blocks_total
ELSE 0
END as progress
FROM pg_class c
LEFT JOIN pg_index i ON c.oid = i.indexrelid
LEFT JOIN pg_stat_progress_create_index p ON c.oid = p.index_relid
WHERE c.relname = 'activity_embedding_idx';
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- Setup: Requires pgvector extension
-- This test is skipped in CI (embedded-postgres doesn't include pgvector).
-- To run manually, install pgvector and remove from skipListRequiresExtension.
CREATE EXTENSION IF NOT EXISTS vector;
16 changes: 16 additions & 0 deletions testutil/skip_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ var skipListPG14_15 = []string{
"TestIncludeIntegration",
}

// skipListRequiresExtension defines test cases that require third-party extensions
// not available in embedded-postgres (e.g., pgvector, PostGIS).
// These tests are skipped on all PostgreSQL versions in CI but can be run manually
// against a database with the required extensions installed.
var skipListRequiresExtension = []string{
"create_table/issue_295_pgvector_typmod",
}

// skipListForVersion maps PostgreSQL major versions to their skip lists.
var skipListForVersion = map[int][]string{
14: skipListPG14_15,
Expand All @@ -70,6 +78,14 @@ var skipListForVersion = map[int][]string{
func ShouldSkipTest(t *testing.T, testName string, majorVersion int) {
t.Helper()

// Check extension-required skip list (applies to all versions)
for _, pattern := range skipListRequiresExtension {
patternNormalized := strings.ReplaceAll(pattern, "/", "_")
if testName == patternNormalized || testName == pattern {
t.Skipf("Skipping test %q: requires third-party extension not available in embedded-postgres", testName)
}
}

// Get skip patterns for this version
skipPatterns, exists := skipListForVersion[majorVersion]
if !exists {
Expand Down