diff --git a/fennel/client_tests/test_expr.py b/fennel/client_tests/test_expr.py index 48470874..fd01f545 100644 --- a/fennel/client_tests/test_expr.py +++ b/fennel/client_tests/test_expr.py @@ -1,4 +1,4 @@ -from datetime import datetime, timezone +from datetime import datetime, timezone, timedelta from typing import Optional import pandas as pd @@ -47,6 +47,7 @@ class UserInfoFeatures: assert response.status_code == requests.codes.OK, response.json() now = datetime.now(timezone.utc) + now_1y = now - timedelta(days=365) df = pd.DataFrame( { "user_id": [1, 2, 3, 4, 5], @@ -59,7 +60,7 @@ class UserInfoFeatures: datetime(2001, 1, 21, tzinfo=timezone.utc), ], "country": ["India", "USA", "Africa", "UK", "Chile"], - "ts": [now, now, now, now, now], + "ts": [now_1y, now_1y, now_1y, now_1y, now_1y], } ) response = client.log("fennel_webhook", "UserInfoDataset", df) @@ -97,3 +98,52 @@ class UserInfoFeatures: "Chile", pd.NA, ] + + if not client.is_integration_client(): + df = client.query_offline( + inputs=[UserInfoFeatures.user_id], + outputs=[ + UserInfoFeatures.name, + UserInfoFeatures.age, + UserInfoFeatures.country, + ], + input_dataframe=pd.DataFrame( + { + "UserInfoFeatures.user_id": [1, 2, 3, 4, 5, 6], + "timestamp": [ + now_1y, + now_1y, + now_1y, + now_1y, + now_1y, + now_1y, + ], + } + ), + timestamp_column="timestamp", + ) + assert df.shape == (6, 4) + assert df["UserInfoFeatures.name"].tolist() == [ + "Ross", + "Monica", + "Chandler", + "Joey", + "Rachel", + pd.NA, + ] + assert df["UserInfoFeatures.age"].tolist() == [ + 53, + 43, + 33, + 25, + 22, + pd.NA, + ] + assert df["UserInfoFeatures.country"].tolist() == [ + "India", + "USA", + "Africa", + "UK", + "Chile", + pd.NA, + ] diff --git a/fennel/expr/expr.py b/fennel/expr/expr.py index 0cddad8d..c713faa5 100644 --- a/fennel/expr/expr.py +++ b/fennel/expr/expr.py @@ -7,6 +7,7 @@ from typing import Any, Callable, Dict, Type, Optional import pandas as pd +from fennel._vendor.pydantic import BaseModel # type: ignore from fennel.dtypes.dtypes import FENNEL_STRUCT, FENNEL_STRUCT_SRC_CODE from fennel.internal_lib.schema.schema import ( convert_dtype_to_arrow_type_with_nullable, @@ -17,6 +18,7 @@ from fennel_data_lib import assign, type_of, matches import fennel.gen.schema_pb2 as schema_proto +import fennel.gen.expr_pb2 as expr_proto from fennel.internal_lib.schema import ( get_datatype, cast_col_to_arrow_dtype, @@ -26,7 +28,9 @@ is_user_defined_class, ) -NOW_COL_NAME = "__fennel_ts_col__" + +class ExprContext(BaseModel): + now_col_name: Optional[str] = None class InvalidExprException(Exception): @@ -362,6 +366,7 @@ def eval( schema: Dict, output_dtype: Optional[Type] = None, parse=True, + context: Optional[ExprContext] = None ) -> pd.Series: from fennel.expr.serializer import ExprSerializer @@ -412,8 +417,12 @@ def pa_to_pd(pa_data, ret_type, parse=True): ret_type = output_dtype serialized_ret_type = get_datatype(ret_type).SerializeToString() + if context is None: + serialized_context = expr_proto.ExprContext().SerializeToString() + else: + serialized_context = expr_proto.ExprContext(**context.dict()).SerializeToString() arrow_col = assign( - proto_bytes, df_pa, proto_schema, serialized_ret_type + proto_bytes, df_pa, proto_schema, serialized_ret_type, serialized_context ) return pa_to_pd(arrow_col, ret_type, parse) diff --git a/fennel/expr/test_expr.py b/fennel/expr/test_expr.py index 0f7ac409..ce7caf60 100644 --- a/fennel/expr/test_expr.py +++ b/fennel/expr/test_expr.py @@ -13,7 +13,6 @@ TimeUnit, from_epoch, make_struct, - NOW_COL_NAME, ) from fennel.expr.visitor import ExprPrinter, FetchReferences from fennel.expr.serializer import ExprSerializer @@ -1359,23 +1358,17 @@ def test_now(): df=pd.DataFrame( { "birthdate": [ - datetime(2023, 1, 1, tzinfo=timezone.utc), - datetime(2023, 1, 2, tzinfo=timezone.utc), + datetime.now(timezone.utc), + datetime.now(timezone.utc), None, - datetime(2023, 1, 3, tzinfo=timezone.utc), - ], - NOW_COL_NAME: [ - datetime(2023, 1, 31, tzinfo=timezone.utc), - datetime(2023, 1, 31, tzinfo=timezone.utc), - datetime(2023, 1, 31, tzinfo=timezone.utc), - datetime(2023, 1, 31, tzinfo=timezone.utc), + datetime.now(timezone.utc), ], } ), - schema={"birthdate": Optional[datetime], NOW_COL_NAME: datetime}, + schema={"birthdate": Optional[datetime]}, display='SINCE(NOW(), col("birthdate"), unit=TimeUnit.DAY)', refs={"birthdate"}, - eval_result=[30, 29, pd.NA, 28], + eval_result=[0, 0, pd.NA, 0], expected_dtype=Optional[int], proto_json=None, ), diff --git a/fennel/gen/expr_pb2.py b/fennel/gen/expr_pb2.py index a72efdd9..c821a95f 100644 --- a/fennel/gen/expr_pb2.py +++ b/fennel/gen/expr_pb2.py @@ -14,7 +14,7 @@ import fennel.gen.schema_pb2 as schema__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\nexpr.proto\x12\x11\x66\x65nnel.proto.expr\x1a\x0cschema.proto\"\xe8\x06\n\x04\x45xpr\x12%\n\x03ref\x18\x01 \x01(\x0b\x32\x16.fennel.proto.expr.RefH\x00\x12\x36\n\x0cjson_literal\x18\x02 \x01(\x0b\x32\x1e.fennel.proto.expr.JsonLiteralH\x00\x12)\n\x05unary\x18\x04 \x01(\x0b\x32\x18.fennel.proto.expr.UnaryH\x00\x12\'\n\x04\x63\x61se\x18\x05 \x01(\x0b\x32\x17.fennel.proto.expr.CaseH\x00\x12+\n\x06\x62inary\x18\x06 \x01(\x0b\x32\x19.fennel.proto.expr.BinaryH\x00\x12+\n\x06isnull\x18\x07 \x01(\x0b\x32\x19.fennel.proto.expr.IsNullH\x00\x12/\n\x08\x66illnull\x18\x08 \x01(\x0b\x32\x1b.fennel.proto.expr.FillNullH\x00\x12,\n\x07list_fn\x18\t \x01(\x0b\x32\x19.fennel.proto.expr.ListFnH\x00\x12,\n\x07math_fn\x18\n \x01(\x0b\x32\x19.fennel.proto.expr.MathFnH\x00\x12\x30\n\tstruct_fn\x18\x0b \x01(\x0b\x32\x1b.fennel.proto.expr.StructFnH\x00\x12,\n\x07\x64ict_fn\x18\x0c \x01(\x0b\x32\x19.fennel.proto.expr.DictFnH\x00\x12\x30\n\tstring_fn\x18\r \x01(\x0b\x32\x1b.fennel.proto.expr.StringFnH\x00\x12\x34\n\x0b\x64\x61tetime_fn\x18\x0e \x01(\x0b\x32\x1d.fennel.proto.expr.DateTimeFnH\x00\x12>\n\x10\x64\x61tetime_literal\x18\x0f \x01(\x0b\x32\".fennel.proto.expr.DatetimeLiteralH\x00\x12\x34\n\x0bmake_struct\x18\x10 \x01(\x0b\x32\x1d.fennel.proto.expr.MakeStructH\x00\x12\x32\n\nfrom_epoch\x18\x11 \x01(\x0b\x32\x1c.fennel.proto.expr.FromEpochH\x00\x12%\n\x03var\x18\x12 \x01(\x0b\x32\x16.fennel.proto.expr.VarH\x00\x12%\n\x03now\x18\x13 \x01(\x0b\x32\x16.fennel.proto.expr.NowH\x00\x42\x06\n\x04node\"\x05\n\x03Now\"\x13\n\x03Var\x12\x0c\n\x04name\x18\x01 \x01(\t\"a\n\tFromEpoch\x12)\n\x08\x64uration\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\x12)\n\x04unit\x18\x02 \x01(\x0e\x32\x1b.fennel.proto.expr.TimeUnit\"\xad\x01\n\x0f\x44\x61tetimeLiteral\x12\x0c\n\x04year\x18\x01 \x01(\r\x12\r\n\x05month\x18\x02 \x01(\r\x12\x0b\n\x03\x64\x61y\x18\x03 \x01(\r\x12\x0c\n\x04hour\x18\x04 \x01(\r\x12\x0e\n\x06minute\x18\x05 \x01(\r\x12\x0e\n\x06second\x18\x06 \x01(\r\x12\x13\n\x0bmicrosecond\x18\x07 \x01(\r\x12-\n\x08timezone\x18\x08 \x01(\x0b\x32\x1b.fennel.proto.expr.Timezone\"\xc5\x01\n\nMakeStruct\x12\x34\n\x0bstruct_type\x18\x01 \x01(\x0b\x32\x1f.fennel.proto.schema.StructType\x12\x39\n\x06\x66ields\x18\x02 \x03(\x0b\x32).fennel.proto.expr.MakeStruct.FieldsEntry\x1a\x46\n\x0b\x46ieldsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.fennel.proto.expr.Expr:\x02\x38\x01\"L\n\x0bJsonLiteral\x12\x0f\n\x07literal\x18\x01 \x01(\t\x12,\n\x05\x64type\x18\x02 \x01(\x0b\x32\x1d.fennel.proto.schema.DataType\"\x13\n\x03Ref\x12\x0c\n\x04name\x18\x01 \x01(\t\"Y\n\x05Unary\x12&\n\x02op\x18\x01 \x01(\x0e\x32\x1a.fennel.proto.expr.UnaryOp\x12(\n\x07operand\x18\x02 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\"}\n\x06\x42inary\x12%\n\x04left\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\x12&\n\x05right\x18\x02 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\x12$\n\x02op\x18\x03 \x01(\x0e\x32\x18.fennel.proto.expr.BinOp\"b\n\x04\x43\x61se\x12.\n\twhen_then\x18\x01 \x03(\x0b\x32\x1b.fennel.proto.expr.WhenThen\x12*\n\totherwise\x18\x02 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\"X\n\x08WhenThen\x12%\n\x04when\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\x12%\n\x04then\x18\x02 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\"2\n\x06IsNull\x12(\n\x07operand\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\"[\n\x08\x46illNull\x12(\n\x07operand\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\x12%\n\x04\x66ill\x18\x02 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\"\xa3\x04\n\x06ListOp\x12%\n\x03len\x18\x01 \x01(\x0b\x32\x16.fennel.proto.expr.LenH\x00\x12&\n\x03get\x18\x02 \x01(\x0b\x32\x17.fennel.proto.expr.ExprH\x00\x12/\n\x08\x63ontains\x18\x03 \x01(\x0b\x32\x1b.fennel.proto.expr.ContainsH\x00\x12.\n\x08has_null\x18\x04 \x01(\x0b\x32\x1a.fennel.proto.expr.HasNullH\x00\x12)\n\x03sum\x18\x05 \x01(\x0b\x32\x1a.fennel.proto.expr.ListSumH\x00\x12)\n\x03min\x18\x06 \x01(\x0b\x32\x1a.fennel.proto.expr.ListMinH\x00\x12)\n\x03max\x18\x07 \x01(\x0b\x32\x1a.fennel.proto.expr.ListMaxH\x00\x12)\n\x03\x61ll\x18\x08 \x01(\x0b\x32\x1a.fennel.proto.expr.ListAllH\x00\x12)\n\x03\x61ny\x18\t \x01(\x0b\x32\x1a.fennel.proto.expr.ListAnyH\x00\x12+\n\x04mean\x18\n \x01(\x0b\x32\x1b.fennel.proto.expr.ListMeanH\x00\x12/\n\x06\x66ilter\x18\x0b \x01(\x0b\x32\x1d.fennel.proto.expr.ListFilterH\x00\x12)\n\x03map\x18\x0c \x01(\x0b\x32\x1a.fennel.proto.expr.ListMapH\x00\x42\t\n\x07\x66n_type\"E\n\nListFilter\x12\x0b\n\x03var\x18\x01 \x01(\t\x12*\n\tpredicate\x18\x02 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\"A\n\x07ListMap\x12\x0b\n\x03var\x18\x01 \x01(\t\x12)\n\x08map_expr\x18\x02 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\"\t\n\x07ListSum\"\t\n\x07ListMin\"\n\n\x08ListMean\"\t\n\x07ListMax\"\t\n\x07ListAll\"\t\n\x07ListAny\"\x05\n\x03Len\"\t\n\x07HasNull\"4\n\x08\x43ontains\x12(\n\x07\x65lement\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\"V\n\x06ListFn\x12%\n\x04list\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\x12%\n\x02\x66n\x18\x02 \x01(\x0b\x32\x19.fennel.proto.expr.ListOp\"\xb9\x01\n\x06MathOp\x12)\n\x05round\x18\x01 \x01(\x0b\x32\x18.fennel.proto.expr.RoundH\x00\x12%\n\x03\x61\x62s\x18\x02 \x01(\x0b\x32\x16.fennel.proto.expr.AbsH\x00\x12\'\n\x04\x63\x65il\x18\x03 \x01(\x0b\x32\x17.fennel.proto.expr.CeilH\x00\x12)\n\x05\x66loor\x18\x04 \x01(\x0b\x32\x18.fennel.proto.expr.FloorH\x00\x42\t\n\x07\x66n_type\"\x1a\n\x05Round\x12\x11\n\tprecision\x18\x01 \x01(\x05\"\x05\n\x03\x41\x62s\"\x06\n\x04\x43\x65il\"\x07\n\x05\x46loor\"Y\n\x06MathFn\x12(\n\x07operand\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\x12%\n\x02\x66n\x18\x02 \x01(\x0b\x32\x19.fennel.proto.expr.MathOp\"&\n\x08StructOp\x12\x0f\n\x05\x66ield\x18\x01 \x01(\tH\x00\x42\t\n\x07\x66n_type\"\\\n\x08StructFn\x12\'\n\x06struct\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\x12\'\n\x02\x66n\x18\x02 \x01(\x0b\x32\x1b.fennel.proto.expr.StructOp\"a\n\x07\x44ictGet\x12&\n\x05\x66ield\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\x12.\n\rdefault_value\x18\x03 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\"\x96\x01\n\x06\x44ictOp\x12%\n\x03len\x18\x01 \x01(\x0b\x32\x16.fennel.proto.expr.LenH\x00\x12)\n\x03get\x18\x02 \x01(\x0b\x32\x1a.fennel.proto.expr.DictGetH\x00\x12/\n\x08\x63ontains\x18\x03 \x01(\x0b\x32\x1b.fennel.proto.expr.ContainsH\x00\x42\t\n\x07\x66n_type\"V\n\x06\x44ictFn\x12%\n\x04\x64ict\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\x12%\n\x02\x66n\x18\x02 \x01(\x0b\x32\x19.fennel.proto.expr.DictOp\"\xc5\x03\n\x08StringOp\x12%\n\x03len\x18\x01 \x01(\x0b\x32\x16.fennel.proto.expr.LenH\x00\x12-\n\x07tolower\x18\x02 \x01(\x0b\x32\x1a.fennel.proto.expr.ToLowerH\x00\x12-\n\x07toupper\x18\x03 \x01(\x0b\x32\x1a.fennel.proto.expr.ToUpperH\x00\x12/\n\x08\x63ontains\x18\x04 \x01(\x0b\x32\x1b.fennel.proto.expr.ContainsH\x00\x12\x33\n\nstartswith\x18\x05 \x01(\x0b\x32\x1d.fennel.proto.expr.StartsWithH\x00\x12/\n\x08\x65ndswith\x18\x06 \x01(\x0b\x32\x1b.fennel.proto.expr.EndsWithH\x00\x12+\n\x06\x63oncat\x18\x07 \x01(\x0b\x32\x19.fennel.proto.expr.ConcatH\x00\x12/\n\x08strptime\x18\x08 \x01(\x0b\x32\x1b.fennel.proto.expr.StrptimeH\x00\x12\x34\n\x0bjson_decode\x18\t \x01(\x0b\x32\x1d.fennel.proto.expr.JsonDecodeH\x00\x42\t\n\x07\x66n_type\"\x1c\n\x08Timezone\x12\x10\n\x08timezone\x18\x01 \x01(\t\":\n\nJsonDecode\x12,\n\x05\x64type\x18\x01 \x01(\x0b\x32\x1d.fennel.proto.schema.DataType\"I\n\x08Strptime\x12\x0e\n\x06\x66ormat\x18\x01 \x01(\t\x12-\n\x08timezone\x18\x02 \x01(\x0b\x32\x1b.fennel.proto.expr.Timezone\"\t\n\x07ToLower\"\t\n\x07ToUpper\"2\n\nStartsWith\x12$\n\x03key\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\"0\n\x08\x45ndsWith\x12$\n\x03key\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\"0\n\x06\x43oncat\x12&\n\x05other\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\"\\\n\x08StringFn\x12\'\n\x06string\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\x12\'\n\x02\x66n\x18\x02 \x01(\x0b\x32\x1b.fennel.proto.expr.StringOp\"b\n\nDateTimeFn\x12)\n\x08\x64\x61tetime\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\x12)\n\x02\x66n\x18\x02 \x01(\x0b\x32\x1d.fennel.proto.expr.DateTimeOp\"\xd2\x01\n\nDateTimeOp\x12)\n\x05since\x18\x01 \x01(\x0b\x32\x18.fennel.proto.expr.SinceH\x00\x12\x34\n\x0bsince_epoch\x18\x02 \x01(\x0b\x32\x1d.fennel.proto.expr.SinceEpochH\x00\x12/\n\x08strftime\x18\x03 \x01(\x0b\x32\x1b.fennel.proto.expr.StrftimeH\x00\x12\'\n\x04part\x18\x04 \x01(\x0b\x32\x17.fennel.proto.expr.PartH\x00\x42\t\n\x07\x66n_type\"Z\n\x05Since\x12&\n\x05other\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\x12)\n\x04unit\x18\x02 \x01(\x0e\x32\x1b.fennel.proto.expr.TimeUnit\"7\n\nSinceEpoch\x12)\n\x04unit\x18\x01 \x01(\x0e\x32\x1b.fennel.proto.expr.TimeUnit\"I\n\x08Strftime\x12\x0e\n\x06\x66ormat\x18\x01 \x01(\t\x12-\n\x08timezone\x18\x02 \x01(\x0b\x32\x1b.fennel.proto.expr.Timezone\"`\n\x04Part\x12)\n\x04unit\x18\x01 \x01(\x0e\x32\x1b.fennel.proto.expr.TimeUnit\x12-\n\x08timezone\x18\x02 \x01(\x0b\x32\x1b.fennel.proto.expr.Timezone*\x1b\n\x07UnaryOp\x12\x07\n\x03NEG\x10\x00\x12\x07\n\x03NOT\x10\x01*\x86\x01\n\x05\x42inOp\x12\x07\n\x03\x41\x44\x44\x10\x00\x12\x07\n\x03SUB\x10\x01\x12\x07\n\x03MUL\x10\x02\x12\x07\n\x03\x44IV\x10\x03\x12\x07\n\x03MOD\x10\x04\x12\r\n\tFLOOR_DIV\x10\x05\x12\x06\n\x02\x45Q\x10\x06\x12\x06\n\x02NE\x10\x07\x12\x06\n\x02GT\x10\x08\x12\x07\n\x03GTE\x10\t\x12\x06\n\x02LT\x10\n\x12\x07\n\x03LTE\x10\x0b\x12\x07\n\x03\x41ND\x10\x0c\x12\x06\n\x02OR\x10\r*\x83\x01\n\x08TimeUnit\x12\x0b\n\x07UNKNOWN\x10\x00\x12\n\n\x06SECOND\x10\x01\x12\n\n\x06MINUTE\x10\x02\x12\x08\n\x04HOUR\x10\x03\x12\x07\n\x03\x44\x41Y\x10\x04\x12\x08\n\x04WEEK\x10\x05\x12\t\n\x05MONTH\x10\x06\x12\x08\n\x04YEAR\x10\x07\x12\x0f\n\x0bMICROSECOND\x10\x08\x12\x0f\n\x0bMILLISECOND\x10\tb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\nexpr.proto\x12\x11\x66\x65nnel.proto.expr\x1a\x0cschema.proto\"9\n\x0b\x45xprContext\x12\x19\n\x0cnow_col_name\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\x0f\n\r_now_col_name\"\xe8\x06\n\x04\x45xpr\x12%\n\x03ref\x18\x01 \x01(\x0b\x32\x16.fennel.proto.expr.RefH\x00\x12\x36\n\x0cjson_literal\x18\x02 \x01(\x0b\x32\x1e.fennel.proto.expr.JsonLiteralH\x00\x12)\n\x05unary\x18\x04 \x01(\x0b\x32\x18.fennel.proto.expr.UnaryH\x00\x12\'\n\x04\x63\x61se\x18\x05 \x01(\x0b\x32\x17.fennel.proto.expr.CaseH\x00\x12+\n\x06\x62inary\x18\x06 \x01(\x0b\x32\x19.fennel.proto.expr.BinaryH\x00\x12+\n\x06isnull\x18\x07 \x01(\x0b\x32\x19.fennel.proto.expr.IsNullH\x00\x12/\n\x08\x66illnull\x18\x08 \x01(\x0b\x32\x1b.fennel.proto.expr.FillNullH\x00\x12,\n\x07list_fn\x18\t \x01(\x0b\x32\x19.fennel.proto.expr.ListFnH\x00\x12,\n\x07math_fn\x18\n \x01(\x0b\x32\x19.fennel.proto.expr.MathFnH\x00\x12\x30\n\tstruct_fn\x18\x0b \x01(\x0b\x32\x1b.fennel.proto.expr.StructFnH\x00\x12,\n\x07\x64ict_fn\x18\x0c \x01(\x0b\x32\x19.fennel.proto.expr.DictFnH\x00\x12\x30\n\tstring_fn\x18\r \x01(\x0b\x32\x1b.fennel.proto.expr.StringFnH\x00\x12\x34\n\x0b\x64\x61tetime_fn\x18\x0e \x01(\x0b\x32\x1d.fennel.proto.expr.DateTimeFnH\x00\x12>\n\x10\x64\x61tetime_literal\x18\x0f \x01(\x0b\x32\".fennel.proto.expr.DatetimeLiteralH\x00\x12\x34\n\x0bmake_struct\x18\x10 \x01(\x0b\x32\x1d.fennel.proto.expr.MakeStructH\x00\x12\x32\n\nfrom_epoch\x18\x11 \x01(\x0b\x32\x1c.fennel.proto.expr.FromEpochH\x00\x12%\n\x03var\x18\x12 \x01(\x0b\x32\x16.fennel.proto.expr.VarH\x00\x12%\n\x03now\x18\x13 \x01(\x0b\x32\x16.fennel.proto.expr.NowH\x00\x42\x06\n\x04node\"\x05\n\x03Now\"\x13\n\x03Var\x12\x0c\n\x04name\x18\x01 \x01(\t\"a\n\tFromEpoch\x12)\n\x08\x64uration\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\x12)\n\x04unit\x18\x02 \x01(\x0e\x32\x1b.fennel.proto.expr.TimeUnit\"\xad\x01\n\x0f\x44\x61tetimeLiteral\x12\x0c\n\x04year\x18\x01 \x01(\r\x12\r\n\x05month\x18\x02 \x01(\r\x12\x0b\n\x03\x64\x61y\x18\x03 \x01(\r\x12\x0c\n\x04hour\x18\x04 \x01(\r\x12\x0e\n\x06minute\x18\x05 \x01(\r\x12\x0e\n\x06second\x18\x06 \x01(\r\x12\x13\n\x0bmicrosecond\x18\x07 \x01(\r\x12-\n\x08timezone\x18\x08 \x01(\x0b\x32\x1b.fennel.proto.expr.Timezone\"\xc5\x01\n\nMakeStruct\x12\x34\n\x0bstruct_type\x18\x01 \x01(\x0b\x32\x1f.fennel.proto.schema.StructType\x12\x39\n\x06\x66ields\x18\x02 \x03(\x0b\x32).fennel.proto.expr.MakeStruct.FieldsEntry\x1a\x46\n\x0b\x46ieldsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.fennel.proto.expr.Expr:\x02\x38\x01\"L\n\x0bJsonLiteral\x12\x0f\n\x07literal\x18\x01 \x01(\t\x12,\n\x05\x64type\x18\x02 \x01(\x0b\x32\x1d.fennel.proto.schema.DataType\"\x13\n\x03Ref\x12\x0c\n\x04name\x18\x01 \x01(\t\"Y\n\x05Unary\x12&\n\x02op\x18\x01 \x01(\x0e\x32\x1a.fennel.proto.expr.UnaryOp\x12(\n\x07operand\x18\x02 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\"}\n\x06\x42inary\x12%\n\x04left\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\x12&\n\x05right\x18\x02 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\x12$\n\x02op\x18\x03 \x01(\x0e\x32\x18.fennel.proto.expr.BinOp\"b\n\x04\x43\x61se\x12.\n\twhen_then\x18\x01 \x03(\x0b\x32\x1b.fennel.proto.expr.WhenThen\x12*\n\totherwise\x18\x02 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\"X\n\x08WhenThen\x12%\n\x04when\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\x12%\n\x04then\x18\x02 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\"2\n\x06IsNull\x12(\n\x07operand\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\"[\n\x08\x46illNull\x12(\n\x07operand\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\x12%\n\x04\x66ill\x18\x02 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\"\xa3\x04\n\x06ListOp\x12%\n\x03len\x18\x01 \x01(\x0b\x32\x16.fennel.proto.expr.LenH\x00\x12&\n\x03get\x18\x02 \x01(\x0b\x32\x17.fennel.proto.expr.ExprH\x00\x12/\n\x08\x63ontains\x18\x03 \x01(\x0b\x32\x1b.fennel.proto.expr.ContainsH\x00\x12.\n\x08has_null\x18\x04 \x01(\x0b\x32\x1a.fennel.proto.expr.HasNullH\x00\x12)\n\x03sum\x18\x05 \x01(\x0b\x32\x1a.fennel.proto.expr.ListSumH\x00\x12)\n\x03min\x18\x06 \x01(\x0b\x32\x1a.fennel.proto.expr.ListMinH\x00\x12)\n\x03max\x18\x07 \x01(\x0b\x32\x1a.fennel.proto.expr.ListMaxH\x00\x12)\n\x03\x61ll\x18\x08 \x01(\x0b\x32\x1a.fennel.proto.expr.ListAllH\x00\x12)\n\x03\x61ny\x18\t \x01(\x0b\x32\x1a.fennel.proto.expr.ListAnyH\x00\x12+\n\x04mean\x18\n \x01(\x0b\x32\x1b.fennel.proto.expr.ListMeanH\x00\x12/\n\x06\x66ilter\x18\x0b \x01(\x0b\x32\x1d.fennel.proto.expr.ListFilterH\x00\x12)\n\x03map\x18\x0c \x01(\x0b\x32\x1a.fennel.proto.expr.ListMapH\x00\x42\t\n\x07\x66n_type\"E\n\nListFilter\x12\x0b\n\x03var\x18\x01 \x01(\t\x12*\n\tpredicate\x18\x02 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\"A\n\x07ListMap\x12\x0b\n\x03var\x18\x01 \x01(\t\x12)\n\x08map_expr\x18\x02 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\"\t\n\x07ListSum\"\t\n\x07ListMin\"\n\n\x08ListMean\"\t\n\x07ListMax\"\t\n\x07ListAll\"\t\n\x07ListAny\"\x05\n\x03Len\"\t\n\x07HasNull\"4\n\x08\x43ontains\x12(\n\x07\x65lement\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\"V\n\x06ListFn\x12%\n\x04list\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\x12%\n\x02\x66n\x18\x02 \x01(\x0b\x32\x19.fennel.proto.expr.ListOp\"\xb9\x01\n\x06MathOp\x12)\n\x05round\x18\x01 \x01(\x0b\x32\x18.fennel.proto.expr.RoundH\x00\x12%\n\x03\x61\x62s\x18\x02 \x01(\x0b\x32\x16.fennel.proto.expr.AbsH\x00\x12\'\n\x04\x63\x65il\x18\x03 \x01(\x0b\x32\x17.fennel.proto.expr.CeilH\x00\x12)\n\x05\x66loor\x18\x04 \x01(\x0b\x32\x18.fennel.proto.expr.FloorH\x00\x42\t\n\x07\x66n_type\"\x1a\n\x05Round\x12\x11\n\tprecision\x18\x01 \x01(\x05\"\x05\n\x03\x41\x62s\"\x06\n\x04\x43\x65il\"\x07\n\x05\x46loor\"Y\n\x06MathFn\x12(\n\x07operand\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\x12%\n\x02\x66n\x18\x02 \x01(\x0b\x32\x19.fennel.proto.expr.MathOp\"&\n\x08StructOp\x12\x0f\n\x05\x66ield\x18\x01 \x01(\tH\x00\x42\t\n\x07\x66n_type\"\\\n\x08StructFn\x12\'\n\x06struct\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\x12\'\n\x02\x66n\x18\x02 \x01(\x0b\x32\x1b.fennel.proto.expr.StructOp\"a\n\x07\x44ictGet\x12&\n\x05\x66ield\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\x12.\n\rdefault_value\x18\x03 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\"\x96\x01\n\x06\x44ictOp\x12%\n\x03len\x18\x01 \x01(\x0b\x32\x16.fennel.proto.expr.LenH\x00\x12)\n\x03get\x18\x02 \x01(\x0b\x32\x1a.fennel.proto.expr.DictGetH\x00\x12/\n\x08\x63ontains\x18\x03 \x01(\x0b\x32\x1b.fennel.proto.expr.ContainsH\x00\x42\t\n\x07\x66n_type\"V\n\x06\x44ictFn\x12%\n\x04\x64ict\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\x12%\n\x02\x66n\x18\x02 \x01(\x0b\x32\x19.fennel.proto.expr.DictOp\"\xc5\x03\n\x08StringOp\x12%\n\x03len\x18\x01 \x01(\x0b\x32\x16.fennel.proto.expr.LenH\x00\x12-\n\x07tolower\x18\x02 \x01(\x0b\x32\x1a.fennel.proto.expr.ToLowerH\x00\x12-\n\x07toupper\x18\x03 \x01(\x0b\x32\x1a.fennel.proto.expr.ToUpperH\x00\x12/\n\x08\x63ontains\x18\x04 \x01(\x0b\x32\x1b.fennel.proto.expr.ContainsH\x00\x12\x33\n\nstartswith\x18\x05 \x01(\x0b\x32\x1d.fennel.proto.expr.StartsWithH\x00\x12/\n\x08\x65ndswith\x18\x06 \x01(\x0b\x32\x1b.fennel.proto.expr.EndsWithH\x00\x12+\n\x06\x63oncat\x18\x07 \x01(\x0b\x32\x19.fennel.proto.expr.ConcatH\x00\x12/\n\x08strptime\x18\x08 \x01(\x0b\x32\x1b.fennel.proto.expr.StrptimeH\x00\x12\x34\n\x0bjson_decode\x18\t \x01(\x0b\x32\x1d.fennel.proto.expr.JsonDecodeH\x00\x42\t\n\x07\x66n_type\"\x1c\n\x08Timezone\x12\x10\n\x08timezone\x18\x01 \x01(\t\":\n\nJsonDecode\x12,\n\x05\x64type\x18\x01 \x01(\x0b\x32\x1d.fennel.proto.schema.DataType\"I\n\x08Strptime\x12\x0e\n\x06\x66ormat\x18\x01 \x01(\t\x12-\n\x08timezone\x18\x02 \x01(\x0b\x32\x1b.fennel.proto.expr.Timezone\"\t\n\x07ToLower\"\t\n\x07ToUpper\"2\n\nStartsWith\x12$\n\x03key\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\"0\n\x08\x45ndsWith\x12$\n\x03key\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\"0\n\x06\x43oncat\x12&\n\x05other\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\"\\\n\x08StringFn\x12\'\n\x06string\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\x12\'\n\x02\x66n\x18\x02 \x01(\x0b\x32\x1b.fennel.proto.expr.StringOp\"b\n\nDateTimeFn\x12)\n\x08\x64\x61tetime\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\x12)\n\x02\x66n\x18\x02 \x01(\x0b\x32\x1d.fennel.proto.expr.DateTimeOp\"\xd2\x01\n\nDateTimeOp\x12)\n\x05since\x18\x01 \x01(\x0b\x32\x18.fennel.proto.expr.SinceH\x00\x12\x34\n\x0bsince_epoch\x18\x02 \x01(\x0b\x32\x1d.fennel.proto.expr.SinceEpochH\x00\x12/\n\x08strftime\x18\x03 \x01(\x0b\x32\x1b.fennel.proto.expr.StrftimeH\x00\x12\'\n\x04part\x18\x04 \x01(\x0b\x32\x17.fennel.proto.expr.PartH\x00\x42\t\n\x07\x66n_type\"Z\n\x05Since\x12&\n\x05other\x18\x01 \x01(\x0b\x32\x17.fennel.proto.expr.Expr\x12)\n\x04unit\x18\x02 \x01(\x0e\x32\x1b.fennel.proto.expr.TimeUnit\"7\n\nSinceEpoch\x12)\n\x04unit\x18\x01 \x01(\x0e\x32\x1b.fennel.proto.expr.TimeUnit\"I\n\x08Strftime\x12\x0e\n\x06\x66ormat\x18\x01 \x01(\t\x12-\n\x08timezone\x18\x02 \x01(\x0b\x32\x1b.fennel.proto.expr.Timezone\"`\n\x04Part\x12)\n\x04unit\x18\x01 \x01(\x0e\x32\x1b.fennel.proto.expr.TimeUnit\x12-\n\x08timezone\x18\x02 \x01(\x0b\x32\x1b.fennel.proto.expr.Timezone*\x1b\n\x07UnaryOp\x12\x07\n\x03NEG\x10\x00\x12\x07\n\x03NOT\x10\x01*\x86\x01\n\x05\x42inOp\x12\x07\n\x03\x41\x44\x44\x10\x00\x12\x07\n\x03SUB\x10\x01\x12\x07\n\x03MUL\x10\x02\x12\x07\n\x03\x44IV\x10\x03\x12\x07\n\x03MOD\x10\x04\x12\r\n\tFLOOR_DIV\x10\x05\x12\x06\n\x02\x45Q\x10\x06\x12\x06\n\x02NE\x10\x07\x12\x06\n\x02GT\x10\x08\x12\x07\n\x03GTE\x10\t\x12\x06\n\x02LT\x10\n\x12\x07\n\x03LTE\x10\x0b\x12\x07\n\x03\x41ND\x10\x0c\x12\x06\n\x02OR\x10\r*\x83\x01\n\x08TimeUnit\x12\x0b\n\x07UNKNOWN\x10\x00\x12\n\n\x06SECOND\x10\x01\x12\n\n\x06MINUTE\x10\x02\x12\x08\n\x04HOUR\x10\x03\x12\x07\n\x03\x44\x41Y\x10\x04\x12\x08\n\x04WEEK\x10\x05\x12\t\n\x05MONTH\x10\x06\x12\x08\n\x04YEAR\x10\x07\x12\x0f\n\x0bMICROSECOND\x10\x08\x12\x0f\n\x0bMILLISECOND\x10\tb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -23,120 +23,122 @@ DESCRIPTOR._options = None _globals['_MAKESTRUCT_FIELDSENTRY']._options = None _globals['_MAKESTRUCT_FIELDSENTRY']._serialized_options = b'8\001' - _globals['_UNARYOP']._serialized_start=5321 - _globals['_UNARYOP']._serialized_end=5348 - _globals['_BINOP']._serialized_start=5351 - _globals['_BINOP']._serialized_end=5485 - _globals['_TIMEUNIT']._serialized_start=5488 - _globals['_TIMEUNIT']._serialized_end=5619 - _globals['_EXPR']._serialized_start=48 - _globals['_EXPR']._serialized_end=920 - _globals['_NOW']._serialized_start=922 - _globals['_NOW']._serialized_end=927 - _globals['_VAR']._serialized_start=929 - _globals['_VAR']._serialized_end=948 - _globals['_FROMEPOCH']._serialized_start=950 - _globals['_FROMEPOCH']._serialized_end=1047 - _globals['_DATETIMELITERAL']._serialized_start=1050 - _globals['_DATETIMELITERAL']._serialized_end=1223 - _globals['_MAKESTRUCT']._serialized_start=1226 - _globals['_MAKESTRUCT']._serialized_end=1423 - _globals['_MAKESTRUCT_FIELDSENTRY']._serialized_start=1353 - _globals['_MAKESTRUCT_FIELDSENTRY']._serialized_end=1423 - _globals['_JSONLITERAL']._serialized_start=1425 - _globals['_JSONLITERAL']._serialized_end=1501 - _globals['_REF']._serialized_start=1503 - _globals['_REF']._serialized_end=1522 - _globals['_UNARY']._serialized_start=1524 - _globals['_UNARY']._serialized_end=1613 - _globals['_BINARY']._serialized_start=1615 - _globals['_BINARY']._serialized_end=1740 - _globals['_CASE']._serialized_start=1742 - _globals['_CASE']._serialized_end=1840 - _globals['_WHENTHEN']._serialized_start=1842 - _globals['_WHENTHEN']._serialized_end=1930 - _globals['_ISNULL']._serialized_start=1932 - _globals['_ISNULL']._serialized_end=1982 - _globals['_FILLNULL']._serialized_start=1984 - _globals['_FILLNULL']._serialized_end=2075 - _globals['_LISTOP']._serialized_start=2078 - _globals['_LISTOP']._serialized_end=2625 - _globals['_LISTFILTER']._serialized_start=2627 - _globals['_LISTFILTER']._serialized_end=2696 - _globals['_LISTMAP']._serialized_start=2698 - _globals['_LISTMAP']._serialized_end=2763 - _globals['_LISTSUM']._serialized_start=2765 - _globals['_LISTSUM']._serialized_end=2774 - _globals['_LISTMIN']._serialized_start=2776 - _globals['_LISTMIN']._serialized_end=2785 - _globals['_LISTMEAN']._serialized_start=2787 - _globals['_LISTMEAN']._serialized_end=2797 - _globals['_LISTMAX']._serialized_start=2799 - _globals['_LISTMAX']._serialized_end=2808 - _globals['_LISTALL']._serialized_start=2810 - _globals['_LISTALL']._serialized_end=2819 - _globals['_LISTANY']._serialized_start=2821 - _globals['_LISTANY']._serialized_end=2830 - _globals['_LEN']._serialized_start=2832 - _globals['_LEN']._serialized_end=2837 - _globals['_HASNULL']._serialized_start=2839 - _globals['_HASNULL']._serialized_end=2848 - _globals['_CONTAINS']._serialized_start=2850 - _globals['_CONTAINS']._serialized_end=2902 - _globals['_LISTFN']._serialized_start=2904 - _globals['_LISTFN']._serialized_end=2990 - _globals['_MATHOP']._serialized_start=2993 - _globals['_MATHOP']._serialized_end=3178 - _globals['_ROUND']._serialized_start=3180 - _globals['_ROUND']._serialized_end=3206 - _globals['_ABS']._serialized_start=3208 - _globals['_ABS']._serialized_end=3213 - _globals['_CEIL']._serialized_start=3215 - _globals['_CEIL']._serialized_end=3221 - _globals['_FLOOR']._serialized_start=3223 - _globals['_FLOOR']._serialized_end=3230 - _globals['_MATHFN']._serialized_start=3232 - _globals['_MATHFN']._serialized_end=3321 - _globals['_STRUCTOP']._serialized_start=3323 - _globals['_STRUCTOP']._serialized_end=3361 - _globals['_STRUCTFN']._serialized_start=3363 - _globals['_STRUCTFN']._serialized_end=3455 - _globals['_DICTGET']._serialized_start=3457 - _globals['_DICTGET']._serialized_end=3554 - _globals['_DICTOP']._serialized_start=3557 - _globals['_DICTOP']._serialized_end=3707 - _globals['_DICTFN']._serialized_start=3709 - _globals['_DICTFN']._serialized_end=3795 - _globals['_STRINGOP']._serialized_start=3798 - _globals['_STRINGOP']._serialized_end=4251 - _globals['_TIMEZONE']._serialized_start=4253 - _globals['_TIMEZONE']._serialized_end=4281 - _globals['_JSONDECODE']._serialized_start=4283 - _globals['_JSONDECODE']._serialized_end=4341 - _globals['_STRPTIME']._serialized_start=4343 - _globals['_STRPTIME']._serialized_end=4416 - _globals['_TOLOWER']._serialized_start=4418 - _globals['_TOLOWER']._serialized_end=4427 - _globals['_TOUPPER']._serialized_start=4429 - _globals['_TOUPPER']._serialized_end=4438 - _globals['_STARTSWITH']._serialized_start=4440 - _globals['_STARTSWITH']._serialized_end=4490 - _globals['_ENDSWITH']._serialized_start=4492 - _globals['_ENDSWITH']._serialized_end=4540 - _globals['_CONCAT']._serialized_start=4542 - _globals['_CONCAT']._serialized_end=4590 - _globals['_STRINGFN']._serialized_start=4592 - _globals['_STRINGFN']._serialized_end=4684 - _globals['_DATETIMEFN']._serialized_start=4686 - _globals['_DATETIMEFN']._serialized_end=4784 - _globals['_DATETIMEOP']._serialized_start=4787 - _globals['_DATETIMEOP']._serialized_end=4997 - _globals['_SINCE']._serialized_start=4999 - _globals['_SINCE']._serialized_end=5089 - _globals['_SINCEEPOCH']._serialized_start=5091 - _globals['_SINCEEPOCH']._serialized_end=5146 - _globals['_STRFTIME']._serialized_start=5148 - _globals['_STRFTIME']._serialized_end=5221 - _globals['_PART']._serialized_start=5223 - _globals['_PART']._serialized_end=5319 + _globals['_UNARYOP']._serialized_start=5380 + _globals['_UNARYOP']._serialized_end=5407 + _globals['_BINOP']._serialized_start=5410 + _globals['_BINOP']._serialized_end=5544 + _globals['_TIMEUNIT']._serialized_start=5547 + _globals['_TIMEUNIT']._serialized_end=5678 + _globals['_EXPRCONTEXT']._serialized_start=47 + _globals['_EXPRCONTEXT']._serialized_end=104 + _globals['_EXPR']._serialized_start=107 + _globals['_EXPR']._serialized_end=979 + _globals['_NOW']._serialized_start=981 + _globals['_NOW']._serialized_end=986 + _globals['_VAR']._serialized_start=988 + _globals['_VAR']._serialized_end=1007 + _globals['_FROMEPOCH']._serialized_start=1009 + _globals['_FROMEPOCH']._serialized_end=1106 + _globals['_DATETIMELITERAL']._serialized_start=1109 + _globals['_DATETIMELITERAL']._serialized_end=1282 + _globals['_MAKESTRUCT']._serialized_start=1285 + _globals['_MAKESTRUCT']._serialized_end=1482 + _globals['_MAKESTRUCT_FIELDSENTRY']._serialized_start=1412 + _globals['_MAKESTRUCT_FIELDSENTRY']._serialized_end=1482 + _globals['_JSONLITERAL']._serialized_start=1484 + _globals['_JSONLITERAL']._serialized_end=1560 + _globals['_REF']._serialized_start=1562 + _globals['_REF']._serialized_end=1581 + _globals['_UNARY']._serialized_start=1583 + _globals['_UNARY']._serialized_end=1672 + _globals['_BINARY']._serialized_start=1674 + _globals['_BINARY']._serialized_end=1799 + _globals['_CASE']._serialized_start=1801 + _globals['_CASE']._serialized_end=1899 + _globals['_WHENTHEN']._serialized_start=1901 + _globals['_WHENTHEN']._serialized_end=1989 + _globals['_ISNULL']._serialized_start=1991 + _globals['_ISNULL']._serialized_end=2041 + _globals['_FILLNULL']._serialized_start=2043 + _globals['_FILLNULL']._serialized_end=2134 + _globals['_LISTOP']._serialized_start=2137 + _globals['_LISTOP']._serialized_end=2684 + _globals['_LISTFILTER']._serialized_start=2686 + _globals['_LISTFILTER']._serialized_end=2755 + _globals['_LISTMAP']._serialized_start=2757 + _globals['_LISTMAP']._serialized_end=2822 + _globals['_LISTSUM']._serialized_start=2824 + _globals['_LISTSUM']._serialized_end=2833 + _globals['_LISTMIN']._serialized_start=2835 + _globals['_LISTMIN']._serialized_end=2844 + _globals['_LISTMEAN']._serialized_start=2846 + _globals['_LISTMEAN']._serialized_end=2856 + _globals['_LISTMAX']._serialized_start=2858 + _globals['_LISTMAX']._serialized_end=2867 + _globals['_LISTALL']._serialized_start=2869 + _globals['_LISTALL']._serialized_end=2878 + _globals['_LISTANY']._serialized_start=2880 + _globals['_LISTANY']._serialized_end=2889 + _globals['_LEN']._serialized_start=2891 + _globals['_LEN']._serialized_end=2896 + _globals['_HASNULL']._serialized_start=2898 + _globals['_HASNULL']._serialized_end=2907 + _globals['_CONTAINS']._serialized_start=2909 + _globals['_CONTAINS']._serialized_end=2961 + _globals['_LISTFN']._serialized_start=2963 + _globals['_LISTFN']._serialized_end=3049 + _globals['_MATHOP']._serialized_start=3052 + _globals['_MATHOP']._serialized_end=3237 + _globals['_ROUND']._serialized_start=3239 + _globals['_ROUND']._serialized_end=3265 + _globals['_ABS']._serialized_start=3267 + _globals['_ABS']._serialized_end=3272 + _globals['_CEIL']._serialized_start=3274 + _globals['_CEIL']._serialized_end=3280 + _globals['_FLOOR']._serialized_start=3282 + _globals['_FLOOR']._serialized_end=3289 + _globals['_MATHFN']._serialized_start=3291 + _globals['_MATHFN']._serialized_end=3380 + _globals['_STRUCTOP']._serialized_start=3382 + _globals['_STRUCTOP']._serialized_end=3420 + _globals['_STRUCTFN']._serialized_start=3422 + _globals['_STRUCTFN']._serialized_end=3514 + _globals['_DICTGET']._serialized_start=3516 + _globals['_DICTGET']._serialized_end=3613 + _globals['_DICTOP']._serialized_start=3616 + _globals['_DICTOP']._serialized_end=3766 + _globals['_DICTFN']._serialized_start=3768 + _globals['_DICTFN']._serialized_end=3854 + _globals['_STRINGOP']._serialized_start=3857 + _globals['_STRINGOP']._serialized_end=4310 + _globals['_TIMEZONE']._serialized_start=4312 + _globals['_TIMEZONE']._serialized_end=4340 + _globals['_JSONDECODE']._serialized_start=4342 + _globals['_JSONDECODE']._serialized_end=4400 + _globals['_STRPTIME']._serialized_start=4402 + _globals['_STRPTIME']._serialized_end=4475 + _globals['_TOLOWER']._serialized_start=4477 + _globals['_TOLOWER']._serialized_end=4486 + _globals['_TOUPPER']._serialized_start=4488 + _globals['_TOUPPER']._serialized_end=4497 + _globals['_STARTSWITH']._serialized_start=4499 + _globals['_STARTSWITH']._serialized_end=4549 + _globals['_ENDSWITH']._serialized_start=4551 + _globals['_ENDSWITH']._serialized_end=4599 + _globals['_CONCAT']._serialized_start=4601 + _globals['_CONCAT']._serialized_end=4649 + _globals['_STRINGFN']._serialized_start=4651 + _globals['_STRINGFN']._serialized_end=4743 + _globals['_DATETIMEFN']._serialized_start=4745 + _globals['_DATETIMEFN']._serialized_end=4843 + _globals['_DATETIMEOP']._serialized_start=4846 + _globals['_DATETIMEOP']._serialized_end=5056 + _globals['_SINCE']._serialized_start=5058 + _globals['_SINCE']._serialized_end=5148 + _globals['_SINCEEPOCH']._serialized_start=5150 + _globals['_SINCEEPOCH']._serialized_end=5205 + _globals['_STRFTIME']._serialized_start=5207 + _globals['_STRFTIME']._serialized_end=5280 + _globals['_PART']._serialized_start=5282 + _globals['_PART']._serialized_end=5378 # @@protoc_insertion_point(module_scope) diff --git a/fennel/gen/expr_pb2.pyi b/fennel/gen/expr_pb2.pyi index d949dcdb..3757436e 100644 --- a/fennel/gen/expr_pb2.pyi +++ b/fennel/gen/expr_pb2.pyi @@ -110,6 +110,23 @@ MICROSECOND: TimeUnit.ValueType # 8 MILLISECOND: TimeUnit.ValueType # 9 global___TimeUnit = TimeUnit +@typing_extensions.final +class ExprContext(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + NOW_COL_NAME_FIELD_NUMBER: builtins.int + now_col_name: builtins.str + def __init__( + self, + *, + now_col_name: builtins.str | None = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["_now_col_name", b"_now_col_name", "now_col_name", b"now_col_name"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["_now_col_name", b"_now_col_name", "now_col_name", b"now_col_name"]) -> None: ... + def WhichOneof(self, oneof_group: typing_extensions.Literal["_now_col_name", b"_now_col_name"]) -> typing_extensions.Literal["now_col_name"] | None: ... + +global___ExprContext = ExprContext + @typing_extensions.final class Expr(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor diff --git a/fennel/testing/query_engine.py b/fennel/testing/query_engine.py index fa5a2649..824e5e7b 100644 --- a/fennel/testing/query_engine.py +++ b/fennel/testing/query_engine.py @@ -8,7 +8,7 @@ import fennel.datasets.datasets import fennel.gen.schema_pb2 as schema_proto -from fennel.expr.expr import NOW_COL_NAME +from fennel.expr.expr import ExprContext from fennel.featuresets import Extractor, Feature, Featureset, is_valid_feature from fennel.gen.featureset_pb2 import ( ExtractorType as ProtoExtractorType, @@ -23,6 +23,8 @@ cast_df_to_arrow_dtype, ) +NOW_COL_NAME = "__ts_col_name__" + class QueryEngine: """ @@ -376,7 +378,7 @@ def _compute_expr_extractor( input_schema[NOW_COL_NAME] = datetime df = pd.DataFrame(input_features) df[NOW_COL_NAME] = timestamps - res = expr.eval(df, input_schema) # type: ignore + res = expr.eval(df, input_schema, context=ExprContext(now_col_name=NOW_COL_NAME)) # type: ignore output_dtype = expr.typeof(input_schema) # type: ignore # Cast to correct arrow dtype after evaluating the expression res = cast_col_to_arrow_dtype(res, get_datatype(output_dtype)) diff --git a/pyproject.toml b/pyproject.toml index a7c99a5e..3f8e5acf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,20 +43,20 @@ pyyaml = "^6.0.1" # For production, we use poetry to build the python package -[build-system] -requires = ["poetry-core>=1.0.0"] -build-backend = "poetry.core.masonry.api" +#[build-system] +#requires = ["poetry-core>=1.0.0"] +#build-backend = "poetry.core.masonry.api" # For local development, we use maturin to build the rust library -# [build-system] -# requires = ["maturin", "setuptools>=42", "wheel"] -# build-backend = "maturin" +[build-system] +requires = ["maturin", "setuptools>=42", "wheel"] +build-backend = "maturin" -# [tool.maturin] -# name = "fennel_data_lib" -# sdist-directory = "python_package" -# manifest-path = "../server/fennel_data_lib/Cargo.toml" +[tool.maturin] +name = "fennel_data_lib" +sdist-directory = "python_package" +manifest-path = "../server/fennel_data_lib/Cargo.toml" # inspired from - https://github.com/pypa/pip/blob/main/pyproject.toml