public Function getFunction(Function desc, Function.CompareMode mode) {
        List<Function> fns = vectorizedFunctions.get(desc.functionName());
        if (desc.hasNamedArg() && fns != null && !fns.isEmpty()) {
            fns = fns.stream().filter(Function::hasNamedArg).collect(Collectors.toList());
        }
        if (fns == null || fns.isEmpty()) {
            return null;
        }

        Function func;
        // To be back-compatible, we first choose the functions from the non-polymorphic functions, if we can't find
        // a suitable in non-polymorphic functions. We will try to search in the polymorphic functions.
        List<Function> standFns = fns.stream().filter(fn -> !fn.isPolymorphic()).collect(Collectors.toList());
        func = matchStrictFunction(desc, mode, standFns);
        if (func != null) {
            return func;
        }

        List<Function> polyFns = fns.stream().filter(Function::isPolymorphic).collect(Collectors.toList());
        func = matchPolymorphicFunction(desc, mode, polyFns);
        if (func != null) {
            return func;
        }

        return matchCastFunction(desc, mode, standFns);
    }
@Test
    public void testGetLagFunction() {
        Type[] argTypes1 = {ScalarType.DECIMALV2, ScalarType.TINYINT, ScalarType.TINYINT};
        Function lagDesc1 = new Function(new FunctionName(FunctionSet.LAG), argTypes1, ScalarType.INVALID, false);
        Function newFunction = functionSet.getFunction(lagDesc1, Function.CompareMode.IS_SUPERTYPE_OF);
        Type[] newArgTypes = newFunction.getArgs();
        Assert.assertTrue(newArgTypes[0].matchesType(newArgTypes[2]));
        Assert.assertTrue(newArgTypes[0].matchesType(ScalarType.DECIMALV2));

        Type[] argTypes2 = {ScalarType.VARCHAR, ScalarType.TINYINT, ScalarType.TINYINT};
        Function lagDesc2 = new Function(new FunctionName(FunctionSet.LAG), argTypes2, ScalarType.INVALID, false);
        newFunction = functionSet.getFunction(lagDesc2, Function.CompareMode.IS_SUPERTYPE_OF);
        newArgTypes = newFunction.getArgs();
        Assert.assertTrue(newArgTypes[0].matchesType(newArgTypes[2]));
        Assert.assertTrue(newArgTypes[0].matchesType(ScalarType.VARCHAR));
    }