# Buggy code
def user_exists(
    user,
    host="localhost",
    password=None,
    password_hash=None,
    passwordless=False,
    unix_socket=False,
    password_column=None,
    **connection_args,
):
    """
    Checks if a user exists on the MySQL server. A login can be checked to see
    if passwordless login is permitted by omitting ``password`` and
    ``password_hash``, and using ``passwordless=True``.

    .. versionadded:: 0.16.2
        The ``passwordless`` option was added.

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.user_exists 'username' 'hostname' 'password'
        salt '*' mysql.user_exists 'username' 'hostname' password_hash='hash'
        salt '*' mysql.user_exists 'username' passwordless=True
        salt '*' mysql.user_exists 'username' password_column='authentication_string'
    """
    dbc = _connect(**connection_args)
    # Did we fail to connect with the user we are checking
    # Its password might have previously change with the same command/state
    if (
        dbc is None
        and __context__["mysql.error"].startswith(
            "MySQL Error 1045: Access denied for user '{0}'@".format(user)
        )
        and password
    ):
        # Clear the previous error
        __context__["mysql.error"] = None
        connection_args["connection_pass"] = password
        dbc = _connect(**connection_args)
    if dbc is None:
        return False

    if not password_column:
        password_column = __password_column(**connection_args)

    cur = dbc.cursor()
    qry = "SELECT User,Host FROM mysql.user WHERE User = %(user)s AND Host = %(host)s"
    args = {}
    args["user"] = user
    args["host"] = host

    if salt.utils.data.is_true(passwordless):
        if salt.utils.data.is_true(unix_socket):
            qry += " AND plugin=%(unix_socket)s"
            args["unix_socket"] = "unix_socket"
        else:
            qry += " AND " + password_column + " = ''"
    elif password:
        qry += " AND " + password_column + " = PASSWORD(%(password)s)"
        args["password"] = six.text_type(password)
    elif password_hash:
        qry += " AND " + password_column + " = %(password)s"
        args["password"] = password_hash

    try:
        _execute(cur, qry, args)
    except MySQLdb.OperationalError as exc:
        err = "MySQL Error {0}: {1}".format(*exc)
        __context__["mysql.error"] = err
        log.error(err)
        return False

    return cur.rowcount == 1


# Traceback (ProgrammingError)
[DEBUG   ] Doing query: SELECT User,Host FROM mysql.user WHERE User = %(user)s AND Host = %(host)s AND authentication_string = PASSWORD(%(password)s) args: {u'host': u'localhost', u'password': u'somepass', u'user': u'monitoring'}
[ERROR   ] An exception occurred in this state: Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/salt/state.py", line 1905, in call
**cdata['kwargs'])
File "/usr/lib/python2.7/dist-packages/salt/loader.py", line 1830, in wrapper
return f(*args, **kwargs)
File "/usr/lib/python2.7/dist-packages/salt/states/mysql_user.py", line 142, in present
**connection_args):
File "/usr/lib/python2.7/dist-packages/salt/modules/mysql.py", line 1244, in user_exists
_execute(cur, qry, args)
File "/usr/lib/python2.7/dist-packages/salt/modules/mysql.py", line 548, in _execute
return cur.execute(qry, args)
File "/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 226, in execute
self.errorhandler(self, exc, value)
File "/usr/lib/python2.7/dist-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorvalue
ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '('u'somepass')' at line 1")

# Fixed code
def user_exists(
    user,
    host="localhost",
    password=None,
    password_hash=None,
    passwordless=False,
    unix_socket=False,
    password_column=None,
    **connection_args,
):
    """
    Checks if a user exists on the MySQL server. A login can be checked to see
    if passwordless login is permitted by omitting ``password`` and
    ``password_hash``, and using ``passwordless=True``.

    .. versionadded:: 0.16.2
        The ``passwordless`` option was added.

    CLI Example:

    .. code-block:: bash

        salt '*' mysql.user_exists 'username' 'hostname' 'password'
        salt '*' mysql.user_exists 'username' 'hostname' password_hash='hash'
        salt '*' mysql.user_exists 'username' passwordless=True
        salt '*' mysql.user_exists 'username' password_column='authentication_string'
    """
    server_version = version(**connection_args)
    dbc = _connect(**connection_args)
    # Did we fail to connect with the user we are checking
    # Its password might have previously change with the same command/state
    if (
        dbc is None
        and __context__["mysql.error"].startswith(
            "MySQL Error 1045: Access denied for user '{0}'@".format(user)
        )
        and password
    ):
        # Clear the previous error
        __context__["mysql.error"] = None
        connection_args["connection_pass"] = password
        dbc = _connect(**connection_args)
    if dbc is None:
        return False

    if not password_column:
        password_column = __password_column(**connection_args)

    cur = dbc.cursor()
    qry = "SELECT User,Host FROM mysql.user WHERE User = %(user)s AND Host = %(host)s"
    args = {}
    args["user"] = user
    args["host"] = host

    if salt.utils.data.is_true(passwordless):
        if salt.utils.data.is_true(unix_socket):
            qry += " AND plugin=%(unix_socket)s"
            args["unix_socket"] = "unix_socket"
        else:
            qry += " AND " + password_column + " = ''"
    elif password:
        if salt.utils.versions.version_cmp(server_version, "8.0.11") <= 0:
            qry += " AND " + password_column + " = %(password)s"
        else:
            qry += " AND " + password_column + " = PASSWORD(%(password)s)"
        args["password"] = six.text_type(password)
    elif password_hash:
        qry += " AND " + password_column + " = %(password)s"
        args["password"] = password_hash

    try:
        _execute(cur, qry, args)
    except MySQLdb.OperationalError as exc:
        err = "MySQL Error {0}: {1}".format(*exc)
        __context__["mysql.error"] = err
        log.error(err)
        return False

    return cur.rowcount == 1