def json2sql(raw_json=None, **definition):  # pylint: disable=too-many-branches
    """Convert raw dictionary, JSON/YAML to SQL statement.

    :param raw_json: raw JSON/YAML or file to convert to SQL statement
    :type raw_json: str or file
    :return: raw SQL statement
    :rtype: str
    """
    if raw_json and definition:
        raise InputError("Cannot process dict and kwargs input at the same time")

    definition = load_input(raw_json or definition)
    if not isinstance(definition, dict):
        raise UnknownStatementError("Unknown statement parsed: %s (type: %s)"
                                    % (definition, type(definition)))

    try:
        statement = definition.pop('statement', None)
        if statement is None:
            raise NoStatementError("No statement provided")

        statement = statement.lower()

        if statement == 'delete':
            return delete2sql(definition)
        elif statement == 'insert':
            return insert2sql(definition)
        elif statement == 'select':
            return select2sql(definition)
        elif statement == 'update':
            return update2sql(definition)
        elif statement == 'replace':
            return replace2sql(definition)
        else:
            raise UnknownStatementError("Unknown statement provided '%s' in definition %s"
                                        % (statement, definition))
    except Exception as exc:  # pylint: disable=broad-except
        if isinstance(exc, Json2SqlError):
            raise

        raise Json2SqlInternalError("Internal json2sql error: %s" % str(exc)) from exc

    # Just to make Pylint happy :)
    raise Json2SqlInternalError("Unreachable state reached")