@@ -144,17 +144,22 @@ pub fn get_child_token_range_mod(_item: proc_macro2::TokenStream) -> proc_macro2
144144 return  vec![ text] ; 
145145 } 
146146
147-  pub  struct  ChildTokenRange  { 
148-  /// the .start of all child tokens used to estimate the range 
149- pub  child_token_indices:  Vec <i32 >, 
150-  pub  range:  Option <TextRange >
147+  #[ derive( Debug ) ] 
148+  pub  enum  ChildTokenRangeResult  { 
149+  TooManyTokens , 
150+  NoTokens , 
151+  /// indices are the .start of all child tokens used to estimate the range 
152+ ChildTokenRange  {  used_token_indices:  Vec <i32 >,  range:  TextRange  } , 
151153 } 
152154
153-  pub  fn  get_child_token_range( node:  & NodeEnum ,  tokens:  Vec <& ScanToken >,  text:  & str ,  nearest_parent_location:  u32 )  -> ChildTokenRange  { 
154-  let  mut  child_tokens = Vec :: new( ) ; 
155+  pub  fn  get_child_token_range( node:  & NodeEnum ,  tokens:  Vec <& ScanToken >,  text:  & str ,  nearest_parent_location:  Option <u32 >)  -> ChildTokenRangeResult  { 
156+  let  mut  child_tokens:  Vec <& ScanToken > = Vec :: new( ) ; 
157+ 
158+  // if true, we found more than one valid token for at least one property of the node 
159+  let  mut  has_too_many_tokens:  bool  = false ; 
155160
156161 let  mut  get_token = |property:  TokenProperty | { 
157-  let  token  = tokens
162+  let  possible_tokens  = tokens
158163 . iter( ) 
159164 . filter_map( |t| { 
160165 if  property. token. is_some( )  { 
@@ -178,42 +183,59 @@ pub fn get_child_token_range_mod(_item: proc_macro2::TokenStream) -> proc_macro2
178183 } 
179184 } 
180185
181-  // if the token is before the nearest parent location, we can safely ignore it 
182-  // if not, we calculate the distance to the nearest parent location 
183-  let  distance = t. start - nearest_parent_location as  i32 ; 
184-  if  distance >= 0  { 
185-  Some ( ( distance,  t) ) 
186-  }  else { 
187-  None 
188-  } 
186+  Some ( t) 
189187 } ) 
190-  // and use the token with the smallest distance to the nearest parent location 
191-  . min_by_key( |( d,  _) | d. to_owned( ) ) 
192-  . map( |( _,  t) | t) ; 
188+  . collect:: <Vec <&&ScanToken >>( ) ; 
193189
194-  if  token. is_some( )  { 
195-  child_tokens. push( token. unwrap( ) ) ; 
196-  }  else { 
190+  if  possible_tokens. len( )  == 0  { 
197191 debug!( 
198192 "No matching token found for property {:#?} of node {:#?} in {:#?} with tokens {:#?}" , 
199193 property,  node,  text,  tokens
200194 ) ; 
195+  return ; 
196+  } 
197+ 
198+  if  possible_tokens. len( )  == 1  { 
199+  debug!( 
200+  "Found token {:#?} for property {:#?} of node {:#?}" , 
201+  possible_tokens[ 0 ] ,  property,  node
202+  ) ; 
203+  child_tokens. push( possible_tokens[ 0 ] ) ; 
204+  return ; 
201205 } 
206+ 
207+  if  nearest_parent_location. is_none( )  { 
208+  debug!( "Found {:#?} for property {:#?} and no nearest_parent_location set" ,  possible_tokens,  property) ; 
209+  has_too_many_tokens = true ; 
210+  return ; 
211+  } 
212+ 
213+  let  token = possible_tokens
214+  . iter( ) . map( |t| ( ( nearest_parent_location. unwrap( )  as  i32  - t. start) ,  t) ) 
215+  . min_by_key( |( d,  _) | d. to_owned( ) ) 
216+  . map( |( _,  t) | t) ; 
217+ 
218+  debug!( "Selected {:#?} as token closest from parent {:#?} as location {:#?}" ,  token. unwrap( ) ,  node,  nearest_parent_location) ; 
219+ 
220+  child_tokens. push( token. unwrap( ) ) ; 
202221 } ; 
203222
204223 match  node { 
205224 #( NodeEnum :: #node_identifiers( n)  => { #node_handlers} ) , * , 
206225 } ; 
207226
208-  ChildTokenRange  { 
209-  child_token_indices:  child_tokens. iter( ) . map( |t| t. start) . collect( ) , 
210-  range:  if  child_tokens. len( )  > 0  { 
211-  Some ( TextRange :: new( 
227+ 
228+  if  has_too_many_tokens == true  { 
229+  ChildTokenRangeResult :: TooManyTokens 
230+  }  else if  child_tokens. len( )  == 0  { 
231+  ChildTokenRangeResult :: NoTokens 
232+  }  else { 
233+  ChildTokenRangeResult :: ChildTokenRange  { 
234+  used_token_indices:  child_tokens. iter( ) . map( |t| t. start) . collect( ) , 
235+  range:  TextRange :: new( 
212236 TextSize :: from( child_tokens. iter( ) . min_by_key( |t| t. start) . unwrap( ) . start as  u32 ) , 
213237 TextSize :: from( child_tokens. iter( ) . max_by_key( |t| t. end) . unwrap( ) . end as  u32 ) , 
214-  ) ) 
215-  }  else { 
216-  None 
238+  ) 
217239 } 
218240 } 
219241 } 
@@ -252,6 +274,13 @@ fn custom_handlers(node: &Node) -> TokenStream {
252274 "Integer"  => quote !  { 
253275 get_token( TokenProperty :: from( n) ) ; 
254276 } , 
277+  "WindowDef"  => quote !  { 
278+  if  n. partition_clause. len( )  > 0  { 
279+  get_token( TokenProperty :: from( Token :: Window ) ) ; 
280+  }  else { 
281+  get_token( TokenProperty :: from( Token :: Over ) ) ; 
282+  } 
283+  } , 
255284 "Boolean"  => quote !  { 
256285 get_token( TokenProperty :: from( n) ) ; 
257286 } , 
@@ -263,6 +292,28 @@ fn custom_handlers(node: &Node) -> TokenStream {
263292 get_token( TokenProperty :: from( Token :: Filter ) ) ; 
264293 } 
265294 } , 
295+  "SqlvalueFunction"  => quote !  { 
296+  match  n. op { 
297+  // 1 SvfopCurrentDate 
298+  // 2 SvfopCurrentTime 
299+  // 3 SvfopCurrentTimeN 
300+  // 4 SvfopCurrentTimestamp 
301+  // 5 SvfopCurrentTimestampN 
302+  // 6 SvfopLocaltime 
303+  // 7 SvfopLocaltimeN 
304+  // 8 SvfopLocaltimestamp 
305+  // 9 SvfopLocaltimestampN 
306+  // 10 SvfopCurrentRole 
307+  10  => get_token( TokenProperty :: from( Token :: CurrentRole ) ) , 
308+  // 11 SvfopCurrentUser 
309+  11  => get_token( TokenProperty :: from( Token :: CurrentUser ) ) , 
310+  // 12 SvfopUser 
311+  // 13 SvfopSessionUser 
312+  // 14 SvfopCurrentCatalog 
313+  // 15 SvfopCurrentSchema 
314+  _ => panic!( "Unknown SqlvalueFunction {:#?}" ,  n. op) , 
315+  } 
316+  } , 
266317 "SortBy"  => quote !  { 
267318 get_token( TokenProperty :: from( Token :: Order ) ) ; 
268319 match  n. sortby_dir { 
@@ -271,9 +322,6 @@ fn custom_handlers(node: &Node) -> TokenStream {
271322 _ => { } 
272323 } 
273324 } , 
274-  "WindowDef"  => quote !  { 
275-  get_token( TokenProperty :: from( Token :: Partition ) ) ; 
276-  } , 
277325 "AConst"  => quote !  { 
278326 if  n. isnull { 
279327 get_token( TokenProperty :: from( Token :: NullP ) ) ; 
0 commit comments