Skip to content

Commit f594f87

Browse files
ok fine
1 parent 7f61a05 commit f594f87

File tree

2 files changed

+62
-3
lines changed

2 files changed

+62
-3
lines changed

crates/pgt_completions/src/context.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ pub(crate) enum NodeText<'a> {
2626
Original(&'a str),
2727
}
2828

29+
#[derive(PartialEq, Eq, Hash, Debug)]
30+
pub(crate) struct MentionedColumn {
31+
pub(crate) column: String,
32+
pub(crate) alias: Option<String>,
33+
}
34+
2935
/// We can map a few nodes, such as the "update" node, to actual SQL clauses.
3036
/// That gives us a lot of insight for completions.
3137
/// Other nodes, such as the "relation" node, gives us less but still
@@ -108,8 +114,8 @@ pub(crate) struct CompletionContext<'a> {
108114
pub is_in_error_node: bool,
109115

110116
pub mentioned_relations: HashMap<Option<String>, HashSet<String>>,
111-
112117
pub mentioned_table_aliases: HashMap<String, String>,
118+
pub mentioned_columns: HashSet<MentionedColumn>,
113119
}
114120

115121
impl<'a> CompletionContext<'a> {
@@ -127,6 +133,7 @@ impl<'a> CompletionContext<'a> {
127133
is_invocation: false,
128134
mentioned_relations: HashMap::new(),
129135
mentioned_table_aliases: HashMap::new(),
136+
mentioned_columns: HashSet::new(),
130137
is_in_error_node: false,
131138
};
132139

@@ -144,6 +151,7 @@ impl<'a> CompletionContext<'a> {
144151

145152
executor.add_query_results::<queries::RelationMatch>();
146153
executor.add_query_results::<queries::TableAliasMatch>();
154+
executor.add_query_results::<queries::ColumnMatch>();
147155

148156
for relation_match in executor.get_iter(stmt_range) {
149157
match relation_match {
@@ -170,8 +178,12 @@ impl<'a> CompletionContext<'a> {
170178
table_alias_match.get_table(sql),
171179
);
172180
}
173-
174-
QueryResult::Column(_) => todo!(),
181+
QueryResult::Column(c) => {
182+
self.mentioned_columns.insert(MentionedColumn {
183+
column: c.get_column(sql),
184+
alias: c.get_alias(sql),
185+
});
186+
}
175187
};
176188
}
177189
}

crates/pgt_completions/src/relevance/scoring.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ impl CompletionScore<'_> {
3232
self.check_matching_clause_type(ctx);
3333
self.check_matching_wrapping_node(ctx);
3434
self.check_relations_in_stmt(ctx);
35+
self.check_columns_in_stmt(ctx);
3536
}
3637

3738
fn check_matches_query_input(&mut self, ctx: &CompletionContext) {
@@ -235,4 +236,50 @@ impl CompletionScore<'_> {
235236
self.score += 2;
236237
}
237238
}
239+
240+
fn check_columns_in_stmt(&mut self, ctx: &CompletionContext) {
241+
// we only want to consider mentioned columns in a select statement.
242+
if ctx
243+
.wrapping_clause_type
244+
.as_ref()
245+
.is_none_or(|ct| ct != &WrappingClause::Select)
246+
{
247+
return;
248+
}
249+
250+
match self.data {
251+
CompletionRelevanceData::Column(column) => {
252+
/*
253+
* Columns can be mentioned in one of two ways:
254+
*
255+
* 1) With an alias: `select u.id`.
256+
* If the currently investigated suggestion item is "id" of the "users" table,
257+
* we want to check
258+
* a) whether the name of the column matches.
259+
* b) whether we know which table is aliased by "u" (if we don't, we ignore the alias).
260+
* c) whether the aliased table matches the currently investigated suggestion item's table.
261+
*
262+
* 2) Without an alias: `select id`.
263+
* In that case, we only check whether the mentioned column fits our currently investigated
264+
* suggestion item's name.
265+
*
266+
*/
267+
if ctx
268+
.mentioned_columns
269+
.iter()
270+
.any(|mentioned| match mentioned.alias.as_ref() {
271+
Some(als) => {
272+
let aliased_table = ctx.mentioned_table_aliases.get(als.as_str());
273+
column.name == mentioned.column
274+
&& aliased_table.is_none_or(|t| t == &column.table_name)
275+
}
276+
None => mentioned.column == column.name,
277+
})
278+
{
279+
self.score -= 10;
280+
}
281+
}
282+
_ => {}
283+
}
284+
}
238285
}

0 commit comments

Comments
 (0)