From ca028238a5db4b7e7f84c43a8ed624d69c43a210 Mon Sep 17 00:00:00 2001 From: Julian Date: Sat, 24 May 2025 15:49:38 +0200 Subject: [PATCH 1/3] feat(completions): show data type for columns --- crates/pgt_completions/src/builder.rs | 2 ++ crates/pgt_completions/src/item.rs | 1 + crates/pgt_completions/src/providers/columns.rs | 1 + crates/pgt_completions/src/providers/functions.rs | 1 + crates/pgt_completions/src/providers/policies.rs | 1 + crates/pgt_completions/src/providers/schemas.rs | 1 + crates/pgt_completions/src/providers/tables.rs | 1 + crates/pgt_lsp/src/handlers/completions.rs | 5 ++++- crates/pgt_schema_cache/src/columns.rs | 1 + crates/pgt_schema_cache/src/queries/columns.sql | 2 ++ 10 files changed, 15 insertions(+), 1 deletion(-) diff --git a/crates/pgt_completions/src/builder.rs b/crates/pgt_completions/src/builder.rs index 40d29db4..96576053 100644 --- a/crates/pgt_completions/src/builder.rs +++ b/crates/pgt_completions/src/builder.rs @@ -12,6 +12,7 @@ pub(crate) struct PossibleCompletionItem<'a> { pub score: CompletionScore<'a>, pub filter: CompletionFilter<'a>, pub completion_text: Option, + pub detail: Option, } pub(crate) struct CompletionBuilder<'a> { @@ -70,6 +71,7 @@ impl<'a> CompletionBuilder<'a> { kind: item.kind, label: item.label, preselected, + detail: item.detail, // wonderous Rust syntax ftw sort_text: format!("{:0>padding$}", idx, padding = max_padding), diff --git a/crates/pgt_completions/src/item.rs b/crates/pgt_completions/src/item.rs index 702fc766..a7b1c9a0 100644 --- a/crates/pgt_completions/src/item.rs +++ b/crates/pgt_completions/src/item.rs @@ -52,6 +52,7 @@ pub struct CompletionItem { pub kind: CompletionItemKind, /// String used for sorting by LSP clients. pub sort_text: String, + pub detail: Option, pub completion_text: Option, } diff --git a/crates/pgt_completions/src/providers/columns.rs b/crates/pgt_completions/src/providers/columns.rs index 8109ba83..599b3604 100644 --- a/crates/pgt_completions/src/providers/columns.rs +++ b/crates/pgt_completions/src/providers/columns.rs @@ -20,6 +20,7 @@ pub fn complete_columns<'a>(ctx: &CompletionContext<'a>, builder: &mut Completio description: format!("Table: {}.{}", col.schema_name, col.table_name), kind: CompletionItemKind::Column, completion_text: None, + detail: Some(format!("{}", col.type_name)), }; // autocomplete with the alias in a join clause if we find one diff --git a/crates/pgt_completions/src/providers/functions.rs b/crates/pgt_completions/src/providers/functions.rs index 6bc04deb..9968a107 100644 --- a/crates/pgt_completions/src/providers/functions.rs +++ b/crates/pgt_completions/src/providers/functions.rs @@ -19,6 +19,7 @@ pub fn complete_functions<'a>(ctx: &'a CompletionContext, builder: &mut Completi filter: CompletionFilter::from(relevance), description: format!("Schema: {}", func.schema), kind: CompletionItemKind::Function, + detail: None, completion_text: get_completion_text_with_schema_or_alias( ctx, &func.name, diff --git a/crates/pgt_completions/src/providers/policies.rs b/crates/pgt_completions/src/providers/policies.rs index 2421f1f1..7fb06b23 100644 --- a/crates/pgt_completions/src/providers/policies.rs +++ b/crates/pgt_completions/src/providers/policies.rs @@ -48,6 +48,7 @@ pub fn complete_policies<'a>(ctx: &CompletionContext<'a>, builder: &mut Completi description: pol.table_name.to_string(), kind: CompletionItemKind::Policy, completion_text, + detail: None, }; builder.add_item(item); diff --git a/crates/pgt_completions/src/providers/schemas.rs b/crates/pgt_completions/src/providers/schemas.rs index aaa5ebe6..02d2fd0c 100644 --- a/crates/pgt_completions/src/providers/schemas.rs +++ b/crates/pgt_completions/src/providers/schemas.rs @@ -16,6 +16,7 @@ pub fn complete_schemas<'a>(ctx: &'a CompletionContext, builder: &mut Completion kind: crate::CompletionItemKind::Schema, score: CompletionScore::from(relevance.clone()), filter: CompletionFilter::from(relevance), + detail: None, completion_text: None, }; diff --git a/crates/pgt_completions/src/providers/tables.rs b/crates/pgt_completions/src/providers/tables.rs index 57195da7..e028e22b 100644 --- a/crates/pgt_completions/src/providers/tables.rs +++ b/crates/pgt_completions/src/providers/tables.rs @@ -19,6 +19,7 @@ pub fn complete_tables<'a>(ctx: &'a CompletionContext, builder: &mut CompletionB filter: CompletionFilter::from(relevance), description: format!("Schema: {}", table.schema), kind: CompletionItemKind::Table, + detail: None, completion_text: get_completion_text_with_schema_or_alias( ctx, &table.name, diff --git a/crates/pgt_lsp/src/handlers/completions.rs b/crates/pgt_lsp/src/handlers/completions.rs index ee13b26e..595e7e1a 100644 --- a/crates/pgt_lsp/src/handlers/completions.rs +++ b/crates/pgt_lsp/src/handlers/completions.rs @@ -39,7 +39,10 @@ pub fn get_completions( label: i.label, label_details: Some(CompletionItemLabelDetails { description: Some(i.description), - detail: Some(format!(" {}", i.kind)), + detail: i + .detail + .map(|s| format!(" {}", s)) + .or(Some(format!(" {}", i.kind))), }), preselect: Some(i.preselected), sort_text: Some(i.sort_text), diff --git a/crates/pgt_schema_cache/src/columns.rs b/crates/pgt_schema_cache/src/columns.rs index de7c2d4a..0eb64cc6 100644 --- a/crates/pgt_schema_cache/src/columns.rs +++ b/crates/pgt_schema_cache/src/columns.rs @@ -48,6 +48,7 @@ pub struct Column { pub schema_name: String, pub type_id: i64, + pub type_name: String, pub is_nullable: bool, pub is_primary_key: bool, diff --git a/crates/pgt_schema_cache/src/queries/columns.sql b/crates/pgt_schema_cache/src/queries/columns.sql index 86df7cf4..d0c09cd0 100644 --- a/crates/pgt_schema_cache/src/queries/columns.sql +++ b/crates/pgt_schema_cache/src/queries/columns.sql @@ -35,6 +35,7 @@ select ts.class_kind :: char as "class_kind!", ts.schema_name, atts.atttypid :: int8 as "type_id!", + tps.typname as "type_name", not atts.attnotnull as "is_nullable!", nullif( information_schema._pg_char_max_length (atts.atttypid, atts.atttypmod), @@ -51,6 +52,7 @@ from and atts.attnum = ix.attnum left join pg_catalog.pg_attrdef def on atts.attrelid = def.adrelid and atts.attnum = def.adnum + left join pg_catalog.pg_type tps on tps.oid = atts.atttypid where -- system columns, such as `cmax` or `tableoid`, have negative `attnum`s atts.attnum >= 0 From 5631e9a8537f111122821e15e90521fe9917b5d2 Mon Sep 17 00:00:00 2001 From: Julian Date: Sat, 24 May 2025 15:50:22 +0200 Subject: [PATCH 2/3] add sqlx query --- ...b0ce33a0002d170200d77afeee60a7977278.json} | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) rename .sqlx/{query-fc0a0aa6d2a06bf3103d26a0233ae86f456892fa9ce48854a8b960cdf2d11a45.json => query-97da37af0d64378cb622cab14bb3b0ce33a0002d170200d77afeee60a7977278.json} (67%) diff --git a/.sqlx/query-fc0a0aa6d2a06bf3103d26a0233ae86f456892fa9ce48854a8b960cdf2d11a45.json b/.sqlx/query-97da37af0d64378cb622cab14bb3b0ce33a0002d170200d77afeee60a7977278.json similarity index 67% rename from .sqlx/query-fc0a0aa6d2a06bf3103d26a0233ae86f456892fa9ce48854a8b960cdf2d11a45.json rename to .sqlx/query-97da37af0d64378cb622cab14bb3b0ce33a0002d170200d77afeee60a7977278.json index 01043a69..924369cd 100644 --- a/.sqlx/query-fc0a0aa6d2a06bf3103d26a0233ae86f456892fa9ce48854a8b960cdf2d11a45.json +++ b/.sqlx/query-97da37af0d64378cb622cab14bb3b0ce33a0002d170200d77afeee60a7977278.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "with\n available_tables as (\n select\n c.relname as table_name,\n c.oid as table_oid,\n c.relkind as class_kind,\n n.nspname as schema_name\n from\n pg_catalog.pg_class c\n join pg_catalog.pg_namespace n on n.oid = c.relnamespace\n where\n -- r: normal tables\n -- v: views\n -- m: materialized views\n -- f: foreign tables\n -- p: partitioned tables\n c.relkind in ('r', 'v', 'm', 'f', 'p')\n ),\n available_indexes as (\n select\n unnest (ix.indkey) as attnum,\n ix.indisprimary as is_primary,\n ix.indisunique as is_unique,\n ix.indrelid as table_oid\n from\n pg_catalog.pg_class c\n join pg_catalog.pg_index ix on c.oid = ix.indexrelid\n where\n c.relkind = 'i'\n )\nselect\n atts.attname as name,\n ts.table_name,\n ts.table_oid :: int8 as \"table_oid!\",\n ts.class_kind :: char as \"class_kind!\",\n ts.schema_name,\n atts.atttypid :: int8 as \"type_id!\",\n not atts.attnotnull as \"is_nullable!\",\n nullif(\n information_schema._pg_char_max_length (atts.atttypid, atts.atttypmod),\n -1\n ) as varchar_length,\n pg_get_expr (def.adbin, def.adrelid) as default_expr,\n coalesce(ix.is_primary, false) as \"is_primary_key!\",\n coalesce(ix.is_unique, false) as \"is_unique!\",\n pg_catalog.col_description (ts.table_oid, atts.attnum) as comment\nfrom\n pg_catalog.pg_attribute atts\n join available_tables ts on atts.attrelid = ts.table_oid\n left join available_indexes ix on atts.attrelid = ix.table_oid\n and atts.attnum = ix.attnum\n left join pg_catalog.pg_attrdef def on atts.attrelid = def.adrelid\n and atts.attnum = def.adnum\nwhere\n -- system columns, such as `cmax` or `tableoid`, have negative `attnum`s\n atts.attnum >= 0\norder by\n schema_name desc,\n table_name,\n atts.attnum;", + "query": "with\n available_tables as (\n select\n c.relname as table_name,\n c.oid as table_oid,\n c.relkind as class_kind,\n n.nspname as schema_name\n from\n pg_catalog.pg_class c\n join pg_catalog.pg_namespace n on n.oid = c.relnamespace\n where\n -- r: normal tables\n -- v: views\n -- m: materialized views\n -- f: foreign tables\n -- p: partitioned tables\n c.relkind in ('r', 'v', 'm', 'f', 'p')\n ),\n available_indexes as (\n select\n unnest (ix.indkey) as attnum,\n ix.indisprimary as is_primary,\n ix.indisunique as is_unique,\n ix.indrelid as table_oid\n from\n pg_catalog.pg_class c\n join pg_catalog.pg_index ix on c.oid = ix.indexrelid\n where\n c.relkind = 'i'\n )\nselect\n atts.attname as name,\n ts.table_name,\n ts.table_oid :: int8 as \"table_oid!\",\n ts.class_kind :: char as \"class_kind!\",\n ts.schema_name,\n atts.atttypid :: int8 as \"type_id!\",\n tps.typname as \"type_name\",\n not atts.attnotnull as \"is_nullable!\",\n nullif(\n information_schema._pg_char_max_length (atts.atttypid, atts.atttypmod),\n -1\n ) as varchar_length,\n pg_get_expr (def.adbin, def.adrelid) as default_expr,\n coalesce(ix.is_primary, false) as \"is_primary_key!\",\n coalesce(ix.is_unique, false) as \"is_unique!\",\n pg_catalog.col_description (ts.table_oid, atts.attnum) as comment\nfrom\n pg_catalog.pg_attribute atts\n join available_tables ts on atts.attrelid = ts.table_oid\n left join available_indexes ix on atts.attrelid = ix.table_oid\n and atts.attnum = ix.attnum\n left join pg_catalog.pg_attrdef def on atts.attrelid = def.adrelid\n and atts.attnum = def.adnum\n left join pg_catalog.pg_type tps on tps.oid = atts.atttypid\nwhere\n -- system columns, such as `cmax` or `tableoid`, have negative `attnum`s\n atts.attnum >= 0\norder by\n schema_name desc,\n table_name,\n atts.attnum;", "describe": { "columns": [ { @@ -35,31 +35,36 @@ }, { "ordinal": 6, + "name": "type_name", + "type_info": "Name" + }, + { + "ordinal": 7, "name": "is_nullable!", "type_info": "Bool" }, { - "ordinal": 7, + "ordinal": 8, "name": "varchar_length", "type_info": "Int4" }, { - "ordinal": 8, + "ordinal": 9, "name": "default_expr", "type_info": "Text" }, { - "ordinal": 9, + "ordinal": 10, "name": "is_primary_key!", "type_info": "Bool" }, { - "ordinal": 10, + "ordinal": 11, "name": "is_unique!", "type_info": "Bool" }, { - "ordinal": 11, + "ordinal": 12, "name": "comment", "type_info": "Text" } @@ -74,6 +79,7 @@ null, false, null, + false, null, null, null, @@ -82,5 +88,5 @@ null ] }, - "hash": "fc0a0aa6d2a06bf3103d26a0233ae86f456892fa9ce48854a8b960cdf2d11a45" + "hash": "97da37af0d64378cb622cab14bb3b0ce33a0002d170200d77afeee60a7977278" } From 7c722f314c3c785767e377f09d03e8709c1ca541 Mon Sep 17 00:00:00 2001 From: Julian Date: Sat, 24 May 2025 15:51:53 +0200 Subject: [PATCH 3/3] it linted --- crates/pgt_completions/src/providers/columns.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/pgt_completions/src/providers/columns.rs b/crates/pgt_completions/src/providers/columns.rs index 599b3604..1df6581d 100644 --- a/crates/pgt_completions/src/providers/columns.rs +++ b/crates/pgt_completions/src/providers/columns.rs @@ -20,7 +20,7 @@ pub fn complete_columns<'a>(ctx: &CompletionContext<'a>, builder: &mut Completio description: format!("Table: {}.{}", col.schema_name, col.table_name), kind: CompletionItemKind::Column, completion_text: None, - detail: Some(format!("{}", col.type_name)), + detail: Some(col.type_name.to_string()), }; // autocomplete with the alias in a join clause if we find one