@@ -1198,6 +1198,22 @@ fn is_from_consuming_function(name: &str) -> bool {
11981198 sql_text:: is_from_consuming_function ( name)
11991199}
12001200
1201+ fn is_nth_value_from_modifier ( tokens : & [ SqlToken ] , from_idx : usize ) -> bool {
1202+ if !next_word_upper ( tokens, from_idx. saturating_add ( 1 ) )
1203+ . is_some_and ( |( word, _) | matches ! ( word. as_str( ) , "FIRST" | "LAST" ) )
1204+ {
1205+ return false ;
1206+ }
1207+ let Some ( ( SqlToken :: Symbol ( close) , close_idx) ) = prev_non_comment_token ( tokens, from_idx)
1208+ else {
1209+ return false ;
1210+ } ;
1211+ close == ")"
1212+ && matching_open_paren_before_close ( tokens, close_idx)
1213+ . and_then ( |open_idx| prev_word_upper ( tokens, open_idx) )
1214+ . is_some_and ( |( word, _) | word == "NTH_VALUE" )
1215+ }
1216+
12011217/// FROM-clause table functions that may reference left-side row source aliases
12021218/// without an explicit APPLY/LATERAL modifier.
12031219fn is_implicitly_lateral_table_function ( name : & str ) -> bool {
@@ -3860,6 +3876,8 @@ fn scan_cursor_context(tokens: &[SqlToken], cursor_token_len: usize) -> CursorSc
38603876 let from_belongs_to_distinct_predicate =
38613877 is_distinct_from_operator ( tokens, idx)
38623878 && current_phase. is_column_context ( ) ;
3879+ let from_belongs_to_nth_value_modifier =
3880+ is_nth_value_from_modifier ( tokens, idx) ;
38633881 let should_treat_as_function_from = depth_frames
38643882 . get ( depth)
38653883 . map ( |frame| {
@@ -3880,6 +3898,7 @@ fn scan_cursor_context(tokens: &[SqlToken], cursor_token_len: usize) -> CursorSc
38803898 current_phase,
38813899 )
38823900 || from_belongs_to_distinct_predicate
3901+ || from_belongs_to_nth_value_modifier
38833902 {
38843903 relation_state. clear ( ) ;
38853904 } else {
0 commit comments