diff --git a/parser/boundargs.py b/parser/boundargs.py index 771a47b..c2c047d 100644 --- a/parser/boundargs.py +++ b/parser/boundargs.py @@ -204,8 +204,12 @@ def _delegated(body: str, helpers: dict[str, tuple[str, list[str]]]): return None, {}, {} -# A call to a lowercase C function, the form every MEOS function takes. -_CALLEE = re.compile(r"\b(?P[a-z][a-z0-9_]*)\s*\(") +# A call to a lowercase C function, the form every MEOS function takes. A keyword +# followed by a parenthesis (`if (`, `while (`, `return (`, `sizeof (`) opens no call: +# read as one, the condition of `nad_tint_tbox`'s first `if` paired with the wrapper's +# `if (datum_eq(...))` as the kernel both of them call. +_CALLEE = re.compile(r"\b(?!(?:if|else|for|while|do|switch|case|return|sizeof)\b)" + r"(?P[a-z][a-z0-9_]*)\s*\(") def _param_name(decl: str) -> str | None: diff --git a/tests/test_boundargs.py b/tests/test_boundargs.py index 2aa0137..89ba6cc 100644 --- a/tests/test_boundargs.py +++ b/tests/test_boundargs.py @@ -1077,6 +1077,22 @@ def test_the_literal_is_attached_then_stripped(self): return (int) distance_set_value(s, (long) i); """ DISTANCE_SET_INT = {"name": "distance_set_int", "params": [{"name": "s"}, {"name": "i"}]} +# NAD_tbox_tnumber and nad_tint_tbox open a condition before the kernel call, in the shape of +# #KERNEL_WRAPPER and #KERNEL_PUBLIC +GUARDED_WRAPPER = """ + TBox *box = PG_GETARG_TBOX_P(0); + Temporal *temp = PG_GETARG_TEMPORAL_P(1); + Datum result = nad_tnumber_tbox(temp, box); + if (datum_eq(result, 0, T_INT4)) + PG_RETURN_NULL(); + PG_RETURN_DATUM(result); +""" +GUARDED_PUBLIC = """ + if (! ensure_valid_tnumber_tbox(temp, box)) + return INT_MAX; + return (int) nad_tnumber_tbox(temp, box); +""" +NAD_TINT_TBOX = {"name": "nad_tint_tbox", "params": [{"name": "temp"}, {"name": "box"}]} class SqlArgParamsTests(unittest.TestCase): @@ -1099,6 +1115,12 @@ def test_a_shared_kernel_states_the_order(self): self.assertEqual(_sql_arg_params(KERNEL_WRAPPER, DISTANCE_SET_INT, KERNEL_PUBLIC), ["i", "s"]) + def test_a_condition_is_not_the_kernel(self): + """#test_a_shared_kernel_states_the_order where both bodies open an `if` before the + kernel call: the condition is no call, so the kernel is nad_tnumber_tbox.""" + self.assertEqual(_sql_arg_params(GUARDED_WRAPPER, NAD_TINT_TBOX, GUARDED_PUBLIC), + ["box", "temp"]) + def test_a_shared_kernel_in_the_c_order_is_not_stated(self): """#test_the_c_order_is_not_stated, through a kernel.""" body = KERNEL_WRAPPER.replace("PG_GETARG_DATUM(0)", "PG_GETARG_DATUM(1)").replace(