Skip to content

Commit e032c3f

Browse files
committed
progress
1 parent ba83202 commit e032c3f

File tree

5 files changed

+74
-32
lines changed

5 files changed

+74
-32
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/pgt_treesitter_queries/src/lib.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,7 @@ impl<'a> Iterator for QueryResultIter<'a> {
6969
mod tests {
7070

7171
use crate::{
72-
TreeSitterQueriesExecutor,
73-
queries::{ParameterMatch, RelationMatch},
72+
queries::{Field, ParameterMatch, RelationMatch}, TreeSitterQueriesExecutor
7473
};
7574

7675
#[test]
@@ -211,18 +210,18 @@ on sq1.id = pt.id;
211210

212211
assert_eq!(results[0].get_root(sql), None);
213212
assert_eq!(results[0].get_path(sql), None);
214-
assert_eq!(results[0].get_field(sql), "v_test");
213+
assert_eq!(results[0].get_field(sql), Field::Text("v_test".to_string()));
215214

216215
assert_eq!(results[1].get_root(sql), Some("fn_name".into()));
217216
assert_eq!(results[1].get_path(sql), Some("custom_type".into()));
218-
assert_eq!(results[1].get_field(sql), "v_test2");
217+
assert_eq!(results[1].get_field(sql), Field::Text("v_test2".to_string()));
219218

220219
assert_eq!(results[2].get_root(sql), None);
221220
assert_eq!(results[2].get_path(sql), None);
222-
assert_eq!(results[2].get_field(sql), "$3");
221+
assert_eq!(results[2].get_field(sql), Field::Parameter(3));
223222

224223
assert_eq!(results[3].get_root(sql), None);
225224
assert_eq!(results[3].get_path(sql), Some("custom_type".into()));
226-
assert_eq!(results[3].get_field(sql), "v_test3");
225+
assert_eq!(results[3].get_field(sql), Field::Text("v_test3".to_string()));
227226
}
228227
}

crates/pgt_treesitter_queries/src/queries/parameters.rs

+29-4
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ pub struct ParameterMatch<'a> {
2626
pub(crate) field: tree_sitter::Node<'a>,
2727
}
2828

29+
#[derive(Debug, PartialEq)]
30+
pub enum Field {
31+
Text(String),
32+
Parameter(usize),
33+
}
34+
2935
impl ParameterMatch<'_> {
3036
pub fn get_root(&self, sql: &str) -> Option<String> {
3137
let str = self
@@ -47,11 +53,30 @@ impl ParameterMatch<'_> {
4753
Some(str.to_string())
4854
}
4955

50-
pub fn get_field(&self, sql: &str) -> String {
51-
self.field
56+
pub fn get_field(&self, sql: &str) -> Field {
57+
let text = self
58+
.field
5259
.utf8_text(sql.as_bytes())
53-
.expect("Failed to get table from RelationMatch")
54-
.to_string()
60+
.expect("Failed to get field from RelationMatch");
61+
62+
if let Some(stripped) = text.strip_prefix('$') {
63+
return Field::Parameter(
64+
stripped
65+
.parse::<usize>()
66+
.expect("Failed to parse parameter"),
67+
);
68+
}
69+
70+
Field::Text(text.to_string())
71+
}
72+
73+
pub fn get_range(&self) -> tree_sitter::Range {
74+
self.field.range()
75+
}
76+
77+
pub fn get_byte_range(&self) -> std::ops::Range<usize> {
78+
let range = self.field.range();
79+
range.start_byte..range.end_byte
5580
}
5681
}
5782

crates/pgt_typecheck/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ pgt_diagnostics.workspace = true
1717
pgt_query_ext.workspace = true
1818
pgt_schema_cache.workspace = true
1919
pgt_text_size.workspace = true
20+
pgt_treesitter_queries.workspace = true
2021
sqlx.workspace = true
2122
tokio.workspace = true
2223
tree-sitter.workspace = true

crates/pgt_typecheck/src/typed_identifier.rs

+38-22
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,17 @@
1+
use pgt_treesitter_queries::{
2+
queries::{Field, ParameterMatch},
3+
TreeSitterQueriesExecutor,
4+
};
5+
16
#[derive(Debug)]
27
pub struct TypedIdentifier {
3-
pub schema: Option<String>,
4-
pub relation: Option<String>,
8+
pub root: Option<String>,
9+
pub field: Option<String>,
510
pub name: String,
6-
pub type_: (Option<String>, String),
11+
pub type_: Identifier,
712
}
813

9-
impl TypedIdentifier {
10-
pub fn new(
11-
schema: Option<String>,
12-
relation: Option<String>,
13-
name: String,
14-
type_: (Option<String>, String),
15-
) -> Self {
16-
TypedIdentifier {
17-
schema,
18-
relation,
19-
name,
20-
type_,
21-
}
22-
}
23-
24-
pub fn default_value(&self, schema_cache: &pgt_schema_cache::SchemaCache) -> String {
25-
"NULL".to_string()
26-
}
27-
}
14+
type Identifier = (Option<String>, String);
2815

2916
/// Applies the identifiers to the SQL string by replacing them with their default values.
3017
pub fn apply_identifiers<'a>(
@@ -38,6 +25,35 @@ pub fn apply_identifiers<'a>(
3825
println!("Identifiers: {:?}", identifiers);
3926
println!("CST: {:#?}", cst);
4027

28+
let mut executor = TreeSitterQueriesExecutor::new(cst.root_node(), sql);
29+
30+
executor.add_query_results::<ParameterMatch>();
31+
32+
// we need the range and type of each field
33+
34+
let results: Vec<(std::ops::Range<usize>, &Identifier)> = executor
35+
.get_iter(None)
36+
.filter_map(|q| {
37+
let m: &ParameterMatch = q.try_into().ok()?;
38+
39+
let ident = match m.get_field(sql) {
40+
Field::Parameter(idx) => identifiers.get(idx)?,
41+
Field::Text(field) => {
42+
let r = m.get_root(sql);
43+
let p = m.get_path(sql);
44+
45+
identifiers.iter().find(|i| {
46+
// TODO: this is not correct, we need to check if the identifier is a prefix of the field
47+
48+
})?
49+
}
50+
};
51+
52+
Some((m.get_byte_range(), &ident.type_))
53+
})
54+
// TODO resolve composite types or table types to plain types
55+
.collect();
56+
4157
sql
4258
}
4359

0 commit comments

Comments
 (0)