@@ -101,14 +101,35 @@ def pull_latest_from_table_or_query(
101101 if created_timestamp_column :
102102 timestamps .append (created_timestamp_column )
103103 timestamp_desc_string = " DESC, " .join (_append_alias (timestamps , "a" )) + " DESC"
104- a_field_string = ", " .join (
105- _append_alias (join_key_columns + feature_name_columns + timestamps , "a" )
106- )
107- b_field_string = ", " .join (
108- _append_alias (join_key_columns + feature_name_columns + timestamps , "b" )
109- )
110-
111- query = f"""
104+ # Empty feature_name_columns means "all source columns". BatchFeatureView
105+ # python/pandas/ray transforms signal this via get_column_info. Selecting
106+ # only join keys + timestamps would starve the UDF of input features.
107+ if not feature_name_columns :
108+ distinct_on = ", " .join (f'a."{ c } "' for c in join_key_columns ) or (
109+ f'a."{ timestamp_field } "'
110+ )
111+ order_by_parts = [f'a."{ c } "' for c in join_key_columns ] + [
112+ f'a."{ timestamp_field } " DESC'
113+ ]
114+ if created_timestamp_column :
115+ order_by_parts .append (f'a."{ created_timestamp_column } " DESC' )
116+ order_by = ", " .join (order_by_parts )
117+ query = f"""
118+ SELECT DISTINCT ON ({ distinct_on } )
119+ a.*
120+ { f", { repr (DUMMY_ENTITY_VAL )} AS { DUMMY_ENTITY_ID } " if not join_key_columns else "" }
121+ FROM { from_expression } a
122+ WHERE a."{ timestamp_field } " BETWEEN '{ start_date } '::timestamptz AND '{ end_date } '::timestamptz
123+ ORDER BY { order_by }
124+ """
125+ else :
126+ a_field_string = ", " .join (
127+ _append_alias (join_key_columns + feature_name_columns + timestamps , "a" )
128+ )
129+ b_field_string = ", " .join (
130+ _append_alias (join_key_columns + feature_name_columns + timestamps , "b" )
131+ )
132+ query = f"""
112133 SELECT
113134 { b_field_string }
114135 { f", { repr (DUMMY_ENTITY_VAL )} AS { DUMMY_ENTITY_ID } " if not join_key_columns else "" }
@@ -275,12 +296,17 @@ def pull_all_from_table_or_query(
275296 timestamp_fields = [timestamp_field ]
276297 if created_timestamp_column :
277298 timestamp_fields .append (created_timestamp_column )
278- field_string = ", " .join (
279- _append_alias (
280- join_key_columns + feature_name_columns + timestamp_fields ,
281- "paftoq_alias" ,
299+ # Empty feature_name_columns => SELECT * (BatchFeatureView python mode).
300+ # Default materialization uses pull_all (pull_latest_features=False).
301+ if not feature_name_columns :
302+ field_string = "paftoq_alias.*"
303+ else :
304+ field_string = ", " .join (
305+ _append_alias (
306+ join_key_columns + feature_name_columns + timestamp_fields ,
307+ "paftoq_alias" ,
308+ )
282309 )
283- )
284310
285311 timestamp_filter = get_timestamp_filter_sql (
286312 start_date ,
0 commit comments