docs: def check_query(state, query, error_msg=None, expand_msg=None):
      """Run arbitrary queries against to the DB connection to verify the database state.
  
      For queries that do not return any output (INSERTs, UPDATEs, ...),
      you cannot use functions like ``check_col()`` and ``is_equal()`` to verify the query result.
  
      ``check_query()`` will rerun the solution query in the transaction prepared by sqlbackend,
      and immediately afterwards run the query specified in ``query``.
  
      Next, it will also run this query after rerunning the student query in a transaction.
  
      Finally, it produces a child state with these results, that you can then chain off of
      with functions like ``check_column()`` and ``has_equal_value()``.
  
      Args:
          query: A SQL query as a string that is executed after the student query is re-executed.
          error_msg: if specified, this overrides the automatically generated feedback
                     message in case the query generated an error.
          expand_msg: if specified, this overrides the automatically generated feedback 
                      message that is prepended to feedback messages that are thrown
                      further in the SCT chain.
  
      :Example:
  
          Suppose we are checking whether an INSERT happened correctly: ::
  
              INSERT INTO company VALUES (2, 'filip', 28, 'sql-lane', 42)
  
          We can write the following SCT: ::
  
              Ex().check_query('SELECT COUNT(*) AS c FROM company').has_equal_value()
  
      """
  
      if error_msg is None:
          error_msg = "Running `{{query}}` after your submission generated an error."
      if expand_msg is None:
          expand_msg = "The autograder verified the result of running `{{query}}` against the database. "
  
      msg_kwargs = {"query": query}
  
      # before redoing the query,
      # make sure that it didn't generate any errors
      has_no_error(state)
  
      _msg = state.build_message(error_msg, fmt_kwargs=msg_kwargs)
  
      # sqlbackend makes sure all queries are run in transactions.
      # Rerun the solution code first, after which we run the provided query
      with dbconn(state.solution_conn) as conn:
          _ = runQuery(conn, state.solution_code)
          sol_res = runQuery(conn, query)
  
      if sol_res is None:
          raise ValueError("Solution failed: " + _msg)
  
      # sqlbackend makes sure all queries are run in transactions.
      # Rerun the student code first, after wich we run the provided query
      with dbconn(state.student_conn) as conn:
          _ = runQuery(conn, state.student_code)
          stu_res = runQuery(conn, query)
  
      if stu_res is None:
          state.do_test(_msg)
  
      return state.to_child(
          append_message={"msg": expand_msg, "kwargs": msg_kwargs},
          student_result=stu_res,
          solution_result=sol_res,
      )