def test_format_expressions(query: Query, expected_query: Query) -> None: processor = CustomFunction( ColumnSet([("param1", String()), ("param2", UInt(8)), ("other_col", String())]), "f_call", [("param1", ColType({String})), ("param2", ColType({UInt}))], partial_function( "f_call_impl(param1, inner_call(param2), my_const)", [("my_const", 420)], ), ) # We cannot just run == on the query objects. The content of the two # objects is different, being one the AST and the ont the AST + raw body processor.process_query(query, HTTPRequestSettings()) assert (query.get_selected_columns_from_ast() == expected_query.get_selected_columns_from_ast()) assert query.get_groupby_from_ast() == expected_query.get_groupby_from_ast( ) assert query.get_condition_from_ast( ) == expected_query.get_condition_from_ast() assert query.get_arrayjoin_from_ast( ) == expected_query.get_arrayjoin_from_ast() assert query.get_having_from_ast() == expected_query.get_having_from_ast() assert query.get_orderby_from_ast() == expected_query.get_orderby_from_ast( )
def failure_rate_processor(columns: ColumnSet) -> CustomFunction: return CustomFunction( columns, "failure_rate", [], partial_function( "divide(countIf(notIn(transaction_status, tuple(ok, cancelled, unknown))), count())", [(code, SPAN_STATUS_NAME_TO_CODE[code]) for code in ("ok", "cancelled", "unknown")], ), )
def failure_rate_processor() -> CustomFunction: return CustomFunction( "failure_rate", [], partial_function( # We use and(notEquals...) here instead of in(tuple(...)) because it's possible to get an impossible query that sets transaction_status to NULL. # Clickhouse returns an error if an expression such as NULL in (0, 1, 2) appears. "divide(countIf(and(notEquals(transaction_status, ok), and(notEquals(transaction_status, cancelled), notEquals(transaction_status, unknown)))), count())", [(code, SPAN_STATUS_NAME_TO_CODE[code]) for code in ("ok", "cancelled", "unknown")], ), )