def check_node(
    state,
    name,
    index=0,
    missing_msg="Check the {ast_path}. Could not find the {index}{node_name}.",
    priority=None,
):
    """Select a node from abstract syntax tree (AST), using its name and index position.

    Args:
        state: State instance describing student and solution code. Can be omitted if used with Ex().
        name : the name of the abstract syntax tree node to find.
        index: the position of that node (see below for details).
        missing_msg: feedback message if node is not in student AST.
        priority: the priority level of the node being searched for. This determines whether to
                  descend into other AST nodes during the search. Higher priority nodes descend
                  into lower priority. Currently, the only important part of priority is that
                  setting a very high priority (e.g. 99) will search every node.


    :Example:
        If both the student and solution code are.. ::

            SELECT a FROM b; SELECT x FROM y;

        then we can focus on the first select with::

            # approach 1: with manually created State instance
            state = State(*args, **kwargs)
            new_state = check_node(state, 'SelectStmt', 0)

            # approach 2:  with Ex and chaining
            new_state = Ex().check_node('SelectStmt', 0)

    """
    df = partial(state.ast_dispatcher, name, priority=priority)

    sol_stmt_list = df(state.solution_ast)
    try:
        sol_stmt = sol_stmt_list[index]
    except IndexError:
        raise IndexError("Can't get %s statement at index %s" % (name, index))

    stu_stmt_list = df(state.student_ast)
    try:
        stu_stmt = stu_stmt_list[index]
    except IndexError:
        # use speaker on ast dialect module to get message, or fall back to generic
        ast_path = state.get_ast_path() or "highlighted code"
        _msg = state.ast_dispatcher.describe(
            sol_stmt, missing_msg, index=index, ast_path=ast_path
        )
        if _msg is None:
            _msg = MSG_CHECK_FALLBACK
        state.report(Feedback(_msg))

    action = {
        "type": "check_node",
        "kwargs": {"name": name, "index": index},
        "node": stu_stmt,
    }

    return state.to_child(
        student_ast=stu_stmt, solution_ast=sol_stmt, history=state.history + (action,)
    )