@@ -1309,9 +1309,9 @@ def add_from_alias_to_where_tokens(self, from_alias: str) -> None:
13091309 raise RuntimeError ("Alias cannot be None or empty" )
13101310
13111311 tokens = self .__get_current_where_tokens ()
1312- for token in tokens :
1312+ for i , token in enumerate ( tokens ) :
13131313 if isinstance (token , WhereToken ):
1314- token .add_alias (from_alias )
1314+ tokens [ i ] = token .add_alias (from_alias )
13151315
13161316 def add_alias_to_includes_tokens (self , from_alias : str ) -> str :
13171317 if self ._includes_alias is None :
@@ -2757,6 +2757,198 @@ def suggest_using(
27572757 self ._suggest_using (suggestion_or_builder )
27582758 return SuggestionDocumentQuery (self )
27592759
2760+ # Date-component filter methods. The C# client achieves the same result via LINQ expression
2761+ # trees (e.g. Where(x => x.Date.Year == 2024)), which the LINQ provider translates to a
2762+ # JavaScript predicate (new Date(Date.parse(x.Date)).getFullYear() >= 1400) evaluated at
2763+ # query time. Python has no expression-tree mechanism, so these methods use the RQL
2764+ # dot-notation field path directly ("date.Year = $p0"), which relies on the server's
2765+ # auto-indexer extracting the component from the stored ISO 8601 string.
2766+ #
2767+ # LIMITATION — dates before approximately year 1000:
2768+ # The server's dynamic date-component extraction fails for very old dates because the
2769+ # underlying JavaScript engine (used by the auto-indexer) cannot reliably parse ISO 8601
2770+ # strings with years below ~1000 (Date.parse returns NaN). Documents with such dates
2771+ # will not match these where-clauses even when they should.
2772+ #
2773+ # The C# LINQ approach is immune because its JavaScript predicate is evaluated at query
2774+ # time rather than index time, but Python has no equivalent mechanism.
2775+ #
2776+ # WORKAROUND for ancient dates:
2777+ # Create a static index whose C# LINQ map extracts date components explicitly, e.g.:
2778+ #
2779+ # from e in docs.MyCollection
2780+ # select new { date_Year = e.date.Year, date_Day = e.date.Day, ... }
2781+ #
2782+ # The map runs as compiled .NET code so .NET DateTime handles all years correctly.
2783+ # Query the pre-indexed fields directly (e.g. where_less_than("date_Day", 7)).
2784+ # See TestStaticIndexDateComponents in tests/issue_tests/test_RDBC_1041.py.
2785+ #
2786+ # "exact" is intentionally omitted: date components are integers, so case/token options
2787+ # have no effect.
2788+ #
2789+ # where_ticks accepts a raw .NET tick count (100-nanosecond intervals since 0001-01-01).
2790+
2791+ def where_year (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2792+ return self .where_equals (f"{ field_name } .Year" , value )
2793+
2794+ def where_year_greater_than (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2795+ self ._where_greater_than (f"{ field_name } .Year" , value )
2796+ return self
2797+
2798+ def where_year_greater_than_or_equal (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2799+ self ._where_greater_than_or_equal (f"{ field_name } .Year" , value )
2800+ return self
2801+
2802+ def where_year_less_than (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2803+ self ._where_less_than (f"{ field_name } .Year" , value )
2804+ return self
2805+
2806+ def where_year_less_than_or_equal (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2807+ self ._where_less_than_or_equal (f"{ field_name } .Year" , value )
2808+ return self
2809+
2810+ def where_year_between (self , field_name : str , start : int , end : int ) -> "DocumentQuery[_T]" :
2811+ self ._where_between (f"{ field_name } .Year" , start , end )
2812+ return self
2813+
2814+ def where_month (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2815+ return self .where_equals (f"{ field_name } .Month" , value )
2816+
2817+ def where_month_greater_than (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2818+ self ._where_greater_than (f"{ field_name } .Month" , value )
2819+ return self
2820+
2821+ def where_month_greater_than_or_equal (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2822+ self ._where_greater_than_or_equal (f"{ field_name } .Month" , value )
2823+ return self
2824+
2825+ def where_month_less_than (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2826+ self ._where_less_than (f"{ field_name } .Month" , value )
2827+ return self
2828+
2829+ def where_month_less_than_or_equal (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2830+ self ._where_less_than_or_equal (f"{ field_name } .Month" , value )
2831+ return self
2832+
2833+ def where_month_between (self , field_name : str , start : int , end : int ) -> "DocumentQuery[_T]" :
2834+ self ._where_between (f"{ field_name } .Month" , start , end )
2835+ return self
2836+
2837+ def where_day_of_month (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2838+ return self .where_equals (f"{ field_name } .Day" , value )
2839+
2840+ def where_day_of_month_greater_than (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2841+ self ._where_greater_than (f"{ field_name } .Day" , value )
2842+ return self
2843+
2844+ def where_day_of_month_greater_than_or_equal (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2845+ self ._where_greater_than_or_equal (f"{ field_name } .Day" , value )
2846+ return self
2847+
2848+ def where_day_of_month_less_than (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2849+ self ._where_less_than (f"{ field_name } .Day" , value )
2850+ return self
2851+
2852+ def where_day_of_month_less_than_or_equal (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2853+ self ._where_less_than_or_equal (f"{ field_name } .Day" , value )
2854+ return self
2855+
2856+ def where_day_of_month_between (self , field_name : str , start : int , end : int ) -> "DocumentQuery[_T]" :
2857+ self ._where_between (f"{ field_name } .Day" , start , end )
2858+ return self
2859+
2860+ def where_hour (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2861+ return self .where_equals (f"{ field_name } .Hour" , value )
2862+
2863+ def where_hour_greater_than (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2864+ self ._where_greater_than (f"{ field_name } .Hour" , value )
2865+ return self
2866+
2867+ def where_hour_greater_than_or_equal (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2868+ self ._where_greater_than_or_equal (f"{ field_name } .Hour" , value )
2869+ return self
2870+
2871+ def where_hour_less_than (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2872+ self ._where_less_than (f"{ field_name } .Hour" , value )
2873+ return self
2874+
2875+ def where_hour_less_than_or_equal (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2876+ self ._where_less_than_or_equal (f"{ field_name } .Hour" , value )
2877+ return self
2878+
2879+ def where_hour_between (self , field_name : str , start : int , end : int ) -> "DocumentQuery[_T]" :
2880+ self ._where_between (f"{ field_name } .Hour" , start , end )
2881+ return self
2882+
2883+ def where_minute (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2884+ return self .where_equals (f"{ field_name } .Minute" , value )
2885+
2886+ def where_minute_greater_than (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2887+ self ._where_greater_than (f"{ field_name } .Minute" , value )
2888+ return self
2889+
2890+ def where_minute_greater_than_or_equal (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2891+ self ._where_greater_than_or_equal (f"{ field_name } .Minute" , value )
2892+ return self
2893+
2894+ def where_minute_less_than (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2895+ self ._where_less_than (f"{ field_name } .Minute" , value )
2896+ return self
2897+
2898+ def where_minute_less_than_or_equal (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2899+ self ._where_less_than_or_equal (f"{ field_name } .Minute" , value )
2900+ return self
2901+
2902+ def where_minute_between (self , field_name : str , start : int , end : int ) -> "DocumentQuery[_T]" :
2903+ self ._where_between (f"{ field_name } .Minute" , start , end )
2904+ return self
2905+
2906+ def where_second (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2907+ return self .where_equals (f"{ field_name } .Second" , value )
2908+
2909+ def where_second_greater_than (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2910+ self ._where_greater_than (f"{ field_name } .Second" , value )
2911+ return self
2912+
2913+ def where_second_greater_than_or_equal (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2914+ self ._where_greater_than_or_equal (f"{ field_name } .Second" , value )
2915+ return self
2916+
2917+ def where_second_less_than (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2918+ self ._where_less_than (f"{ field_name } .Second" , value )
2919+ return self
2920+
2921+ def where_second_less_than_or_equal (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2922+ self ._where_less_than_or_equal (f"{ field_name } .Second" , value )
2923+ return self
2924+
2925+ def where_second_between (self , field_name : str , start : int , end : int ) -> "DocumentQuery[_T]" :
2926+ self ._where_between (f"{ field_name } .Second" , start , end )
2927+ return self
2928+
2929+ def where_ticks (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2930+ return self .where_equals (f"{ field_name } .Ticks" , value )
2931+
2932+ def where_ticks_greater_than (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2933+ self ._where_greater_than (f"{ field_name } .Ticks" , value )
2934+ return self
2935+
2936+ def where_ticks_greater_than_or_equal (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2937+ self ._where_greater_than_or_equal (f"{ field_name } .Ticks" , value )
2938+ return self
2939+
2940+ def where_ticks_less_than (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2941+ self ._where_less_than (f"{ field_name } .Ticks" , value )
2942+ return self
2943+
2944+ def where_ticks_less_than_or_equal (self , field_name : str , value : int ) -> "DocumentQuery[_T]" :
2945+ self ._where_less_than_or_equal (f"{ field_name } .Ticks" , value )
2946+ return self
2947+
2948+ def where_ticks_between (self , field_name : str , start : int , end : int ) -> "DocumentQuery[_T]" :
2949+ self ._where_between (f"{ field_name } .Ticks" , start , end )
2950+ return self
2951+
27602952
27612953class RawDocumentQuery (Generic [_T ], AbstractDocumentQuery [_T ]):
27622954 def __init__ (self , object_type : Type [_T ], session : InMemoryDocumentSessionOperations , raw_query : str ):
0 commit comments