class FunctionRegistry {

    public final synchronized void addFunctions(List<? extends SqlFunction> functions)
    {
        for (SqlFunction function : functions) {
            String name = function.getFunctionMetadata().getSignature().getName();
            if (isOperatorName(name) && !(function instanceof GenericEqualOperator) &&
                    !(function instanceof GenericHashCodeOperator) &&
                    !(function instanceof GenericXxHash64Operator) &&
                    !(function instanceof GenericDistinctFromOperator) &&
                    !(function instanceof GenericIndeterminateOperator) &&
                    !(function instanceof GenericComparisonOperator) &&
                    !(function instanceof GenericLessThanOperator) &&
                    !(function instanceof GenericLessThanOrEqualOperator)) {
                OperatorType operatorType = unmangleOperator(name);
                checkArgument(operatorType != OperatorType.EQUAL &&
                                operatorType != OperatorType.HASH_CODE &&
                                operatorType != OperatorType.XX_HASH_64 &&
                                operatorType != OperatorType.IS_DISTINCT_FROM &&
                                operatorType != OperatorType.INDETERMINATE &&
                                operatorType != OperatorType.COMPARISON &&
                                operatorType != OperatorType.LESS_THAN &&
                                operatorType != OperatorType.LESS_THAN_OR_EQUAL,
                        "Can not register %s function: %s", operatorType, function.getFunctionMetadata().getSignature());
            }

            FunctionMetadata functionMetadata = function.getFunctionMetadata();
            checkArgument(!functionMetadata.getSignature().getName().contains("|"), "Function name cannot contain '|' character: %s", functionMetadata.getSignature());
            for (FunctionMetadata existingFunction : this.functions.list()) {
                checkArgument(!functionMetadata.getFunctionId().equals(existingFunction.getFunctionId()), "Function already registered: %s", functionMetadata.getFunctionId());
                checkArgument(!functionMetadata.getSignature().equals(existingFunction.getSignature()), "Function already registered: %s", functionMetadata.getSignature());
            }
        }
        this.functions = new FunctionMap(this.functions, functions);
    }

    public  FunctionRegistry(
            Supplier<BlockEncodingSerde> blockEncodingSerdeSupplier,
            FeaturesConfig featuresConfig,
            TypeOperators typeOperators,
            BlockTypeOperators blockTypeOperators);

}