1
- #[ derive( Debug ) ]
2
- pub struct Type {
3
- pub schema : Option < String > ,
4
- pub name : String ,
5
- pub oid : i32 ,
6
- }
7
-
8
1
#[ derive( Debug ) ]
9
2
pub struct TypedIdentifier {
10
3
pub schema : Option < String > ,
11
4
pub relation : Option < String > ,
12
5
pub name : String ,
13
- pub type_ : Type ,
6
+ pub type_ : ( Option < String > , String ) ,
14
7
}
15
8
16
9
impl TypedIdentifier {
17
10
pub fn new (
18
11
schema : Option < String > ,
19
12
relation : Option < String > ,
20
13
name : String ,
21
- type_ : Type ,
14
+ type_ : ( Option < String > , String ) ,
22
15
) -> Self {
23
16
TypedIdentifier {
24
17
schema,
@@ -44,5 +37,107 @@ pub fn apply_identifiers<'a>(
44
37
println ! ( "Applying identifiers to SQL: {}" , sql) ;
45
38
println ! ( "Identifiers: {:?}" , identifiers) ;
46
39
println ! ( "CST: {:#?}" , cst) ;
40
+
47
41
sql
48
42
}
43
+
44
+ #[ cfg( test) ]
45
+ mod tests {
46
+ use pgt_test_utils:: test_database:: get_new_test_db;
47
+ use sqlx:: Executor ;
48
+
49
+ #[ tokio:: test]
50
+ async fn test_apply_identifiers ( ) {
51
+ let input = "select v_test + fn_name.custom_type.v_test2 + $3 + test.field;" ;
52
+
53
+ let test_db = get_new_test_db ( ) . await ;
54
+
55
+ let mut parser = tree_sitter:: Parser :: new ( ) ;
56
+ parser
57
+ . set_language ( tree_sitter_sql:: language ( ) )
58
+ . expect ( "Error loading sql language" ) ;
59
+
60
+ let schema_cache = pgt_schema_cache:: SchemaCache :: load ( & test_db)
61
+ . await
62
+ . expect ( "Failed to load Schema Cache" ) ;
63
+
64
+ let root = pgt_query_ext:: parse ( input) . unwrap ( ) ;
65
+ let tree = parser. parse ( input, None ) . unwrap ( ) ;
66
+
67
+ println ! ( "Parsed SQL: {:?}" , root) ;
68
+ println ! ( "Parsed CST: {:?}" , tree) ;
69
+
70
+ // let mut parameters = Vec::new();
71
+
72
+ enum Parameter {
73
+ Identifier {
74
+ range : ( usize , usize ) ,
75
+ name : ( Option < String > , String ) ,
76
+ } ,
77
+ Parameter {
78
+ range : ( usize , usize ) ,
79
+ idx : usize ,
80
+ } ,
81
+ }
82
+
83
+ let mut c = tree. walk ( ) ;
84
+
85
+ ' outer: loop {
86
+ // 0. Add the current node to the map.
87
+ println ! ( "Current node: {:?}" , c. node( ) ) ;
88
+ match c. node ( ) . kind ( ) {
89
+ "identifier" => {
90
+ println ! (
91
+ "Found identifier: {:?}" ,
92
+ c. node( ) . utf8_text( input. as_bytes( ) ) . unwrap( )
93
+ ) ;
94
+ }
95
+ "parameter" => {
96
+ println ! (
97
+ "Found parameter: {:?}" ,
98
+ c. node( ) . utf8_text( input. as_bytes( ) ) . unwrap( )
99
+ ) ;
100
+ }
101
+ "object_reference" => {
102
+ println ! (
103
+ "Found object reference: {:?}" ,
104
+ c. node( ) . utf8_text( input. as_bytes( ) ) . unwrap( )
105
+ ) ;
106
+
107
+ // let source = self.text;
108
+ // ts_node.utf8_text(source.as_bytes()).ok().map(|txt| {
109
+ // if SanitizedCompletionParams::is_sanitized_token(txt) {
110
+ // NodeText::Replaced
111
+ // } else {
112
+ // NodeText::Original(txt)
113
+ // }
114
+ // })
115
+ }
116
+ _ => { }
117
+ }
118
+
119
+ // 1. Go to its child and continue.
120
+ if c. goto_first_child ( ) {
121
+ continue ' outer;
122
+ }
123
+
124
+ // 2. We've reached a leaf (node without a child). We will go to a sibling.
125
+ if c. goto_next_sibling ( ) {
126
+ continue ' outer;
127
+ }
128
+
129
+ // 3. If there are no more siblings, we need to go back up.
130
+ ' inner: loop {
131
+ // 4. Check if we've reached the root node. If so, we're done.
132
+ if !c. goto_parent ( ) {
133
+ break ' outer;
134
+ }
135
+ // 5. Go to the previous node's sibling.
136
+ if c. goto_next_sibling ( ) {
137
+ // And break out of the inner loop.
138
+ break ' inner;
139
+ }
140
+ }
141
+ }
142
+ }
143
+ }
0 commit comments