Repository: mathesar-foundation/mathesar

Issue:
RecursionError in records endpoint
## Description
I've been getting this error for a few tables in my environment.
* These tables have been created using the 'Create new table' button, not using file import.
* These tables have no rows.
* The tables have a link to another table.

```
Environment:


Request Method: GET
Request URL: http://localhost:8000/api/db/v0/tables/2/records/

Django Version: 3.1.14
Python Version: 3.9.14
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'rest_framework',
 'django_filters',
 'django_property_filter',
 'mathesar']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/rest_framework/viewsets.py", line 125, in view
    return self.dispatch(request, *args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 466, in handle_exception
    response = exception_handler(exc, context)
  File "/code/mathesar/exception_handlers.py", line 55, in mathesar_exception_handler
    raise exc
  File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "/code/mathesar/api/db/viewsets/records.py", line 67, in list
    records = paginator.paginate_queryset(
  File "/code/mathesar/api/pagination.py", line 82, in paginate_queryset
    preview_metadata, preview_columns = get_preview_info(table.id)
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 81, in get_preview_info
    preview_info, columns = _preview_info_by_column_id(
  File "/code/mathesar/utils/preview.py", line 22, in _preview_info_by_column_id
    referent_preview_info, referent_preview_columns = get_preview_info(
  File "/code/mathesar/utils/preview.py", line 70, in get_preview_info
    fk_constraints = [
  File "/code/mathesar/utils/preview.py", line 73, in <listcomp>
    if table_constraint.type == ConstraintType.FOREIGN_KEY.value
  File "/code/mathesar/models/base.py", line 774, in type
    return constraint_utils.get_constraint_type_from_char(self._constraint_record['contype'])
  File "/code/mathesar/models/base.py", line 766, in _constraint_record
    return get_constraint_record_from_oid(self.oid, engine)
  File "/code/db/constraints/operations/select.py", line 33, in get_constraint_record_from_oid
    pg_constraint = get_pg_catalog_table("pg_constraint", engine, metadata=metadata)
  File "/code/db/utils.py", line 92, in warning_ignored_func
    return f(*args, **kwargs)
  File "/code/db/utils.py", line 99, in get_pg_catalog_table
    return sqlalchemy.Table(table_name, metadata, autoload_with=engine, schema='pg_catalog')
  File "<string>", line 2, in __new__
    <source code not available>
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/deprecations.py", line 298, in warned
    return fn(*args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/sql/schema.py", line 600, in __new__
    metadata._remove_table(name, schema)
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/langhelpers.py", line 70, in __exit__
    compat.raise_(
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/compat.py", line 207, in raise_
    raise exception
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/sql/schema.py", line 595, in __new__
    table._init(name, metadata, *args, **kw)
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/sql/schema.py", line 670, in _init
    self._autoload(
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/sql/schema.py", line 705, in _autoload
    conn_insp.reflect_table(
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/reflection.py", line 774, in reflect_table
    for col_d in self.get_columns(
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/reflection.py", line 497, in get_columns
    col_defs = self.dialect.get_columns(
  File "<string>", line 2, in get_columns
    <source code not available>
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/reflection.py", line 55, in cache
    ret = fn(self, con, *args, **kw)
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/dialects/postgresql/base.py", line 3585, in get_columns
    table_oid = self.get_table_oid(
  File "<string>", line 2, in get_table_oid
    <source code not available>
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/reflection.py", line 55, in cache
    ret = fn(self, con, *args, **kw)
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/dialects/postgresql/base.py", line 3462, in get_table_oid
    c = connection.execute(s, dict(table_name=table_name, schema=schema))
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/future/engine.py", line 280, in execute
    return self._execute_20(
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1582, in _execute_20
    return meth(self, args_10style, kwargs_10style, execution_options)
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/sql/elements.py", line 324, in _execute_on_connection
    return connection._execute_clauseelement(
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1451, in _execute_clauseelement
    ret = self._execute_context(
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1813, in _execute_context
    self._handle_dbapi_exception(
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1998, in _handle_dbapi_exception
    util.raise_(exc_info[1], with_traceback=exc_info[2])
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/compat.py", line 207, in raise_
    raise exception
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1786, in _execute_context
    result = context._setup_result_proxy()
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/default.py", line 1406, in _setup_result_proxy
    result = self._setup_dml_or_text_result()
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/default.py", line 1494, in _setup_dml_or_text_result
    result = _cursor.CursorResult(self, strategy, cursor_description)
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/cursor.py", line 1253, in __init__
    metadata = self._init_metadata(context, cursor_description)
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/cursor.py", line 1310, in _init_metadata
    metadata = metadata._adapt_to_context(context)
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/engine/cursor.py", line 136, in _adapt_to_context
    invoked_statement._exported_columns_iterator()
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/sql/selectable.py", line 126, in _exported_columns_iterator
    return iter(self.exported_columns)
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/sql/selectable.py", line 2870, in exported_columns
    return self.selected_columns
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/langhelpers.py", line 1180, in __get__
    obj.__dict__[self.__name__] = result = self.fget(obj)
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/sql/selectable.py", line 6354, in selected_columns
    return ColumnCollection(
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/sql/base.py", line 1128, in __init__
    self._initial_populate(columns)
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/sql/base.py", line 1131, in _initial_populate
    self._populate_separate_keys(iter_)
  File "/usr/local/lib/python3.9/site-packages/sqlalchemy/sql/base.py", line 1227, in _populate_separate_keys
    self._colset.update(c for k, c in self._collection)

Exception Type: RecursionError at /api/db/v0/tables/2/records/
Exception Value: maximum recursion depth exceeded

```

I'm not sure about the cause and it's occuring consistently for me but unable to reproduce it on staging.


Discussion:
@pavish Can you share a JSON schema of the relationship between the tables and the preview template in the table settings? I am refactoring the record summary endpoint to improve its performance and take a look at the bug. 

Also, can you try out the #1838 PR and see if you are still getting the error? As #1838 uses a slightly different logic to fetch summary data
@silentninja Even in #1838, you have:
- `mathesar.utils.preview.get_preview_info` calling
- `mathesar.utils.preview._get_table_preview_info`, which is calling
- `mathesar.utils.preview._preview_info_by_column_id`, which is in turn calling
- `mathesar.utils.preview._get_table_preview_info`.

There's a recursive loop there, and I don't see any clear limit on the recursion depth. In fact, there's a loop involved so that a given call produces multiple calls per level of recursion.
I'm assigning to @silentninja since I'm 90% sure that when my requests on #1838 are addressed, this problem will be solved.

Resolving patch:
diff --git a/mathesar/utils/preview.py b/mathesar/utils/preview.py
--- a/mathesar/utils/preview.py
+++ b/mathesar/utils/preview.py
@@ -16,8 +16,8 @@ def _preview_info_by_column_id(fk_constraints, previous_path=[], exising_columns
         preview_template = referent_table_settings.preview_settings.template
         preview_data_column_ids = column_ids_from_preview_template(preview_template)
         preview_data_columns = Column.objects.filter(id__in=preview_data_column_ids)
-        current_position = [[constrained_column.id, referent_column.id]]
-        current_path = previous_path + current_position
+        current_position = (constrained_column.id, referent_column.id)
+        current_path = previous_path + [current_position]
         # Extract the template for foreign key columns of the referent table
         referent_preview_info, referent_preview_columns = get_preview_info(
             referent_table.id,
@@ -77,6 +77,10 @@ def get_preview_info(referrer_table_pk, restrict_columns=None, path=[], existing
             _get_filter_restricted_columns_fn(restrict_columns),
             fk_constraints
         )
+    fk_constraints = filter(
+        _get_filter_out_circular_dependency_columns_fn(path),
+        fk_constraints
+    )
 
     preview_info, columns = _preview_info_by_column_id(
         fk_constraints,
@@ -92,3 +96,13 @@ def _filter_restricted_columns(fk_constraint):
         return constrained_column in restricted_columns
 
     return _filter_restricted_columns
+
+
+def _get_filter_out_circular_dependency_columns_fn(path):
+
+    def _filter_out_circular_dependency_columns(fk_constraint):
+        constrained_column = fk_constraint.columns[0]
+        referent_column = fk_constraint.referent_columns[0]
+        return (constrained_column.id, referent_column.id) not in path
+
+    return _filter_out_circular_dependency_columns


Test patch:
diff --git a/mathesar/tests/api/test_record_api.py b/mathesar/tests/api/test_record_api.py
--- a/mathesar/tests/api/test_record_api.py
+++ b/mathesar/tests/api/test_record_api.py
@@ -3,6 +3,7 @@
 from copy import deepcopy
 from unittest.mock import patch
 
+from db.constraints.base import ForeignKeyConstraint, UniqueConstraint
 from db.functions.exceptions import UnknownDBFunctionID
 from db.records.exceptions import BadGroupFormat, GroupFieldNotFound
 from db.records.operations.group import GroupBy
@@ -739,6 +740,59 @@ def test_record_list_pagination_offset(create_patents_table, client):
     assert record_1_data[str(columns_id[5])] != record_2_data[str(columns_id[5])]
 
 
+def test_self_referential_column_preview(self_referential_table, engine, client):
+    table = self_referential_table
+    pk_column = table.get_column_by_name("Id")
+    name_column = table.get_column_by_name("Name")
+    parent_column = table.get_column_by_name("Parent")
+    table.add_constraint(UniqueConstraint(None, table.oid, [pk_column.attnum]))
+    table.add_constraint(
+        ForeignKeyConstraint(
+            None,
+            table.oid,
+            [parent_column.attnum],
+            table.oid,
+            [pk_column.attnum], {}
+        )
+    )
+    recursive_preview_template = f'Name: {{{name_column.id}}} Parent: {{{parent_column.id}}}'
+    table_settings_id = table.settings.id
+    data = {
+        "preview_settings": {
+            'template': recursive_preview_template
+        }
+    }
+    response = client.patch(
+        f"/api/db/v0/tables/{table.id}/settings/{table_settings_id}/",
+        data=data,
+    )
+    assert response.status_code == 200
+    response = client.get(f'/api/db/v0/tables/{table.id}/records/')
+    response_data = response.json()
+    preview_data = response_data['preview_data']
+    self_referential_column_reference_path = [[parent_column.id, pk_column.id]]
+    self_referential_column_path_prefix = compute_path_prefix(self_referential_column_reference_path)
+    name_column_alias = compute_path_str(self_referential_column_path_prefix, name_column.id)
+    parent_column_alias = compute_path_str(self_referential_column_path_prefix, parent_column.id)
+    preview_column = next(
+        preview
+        for preview in preview_data
+        if preview['column'] == parent_column.id
+    )
+    preview_data = preview_column['data']['2']
+    assert all(
+        [
+            key in preview_data
+            for key in [name_column_alias, parent_column_alias]
+        ]
+    )
+
+    expected_preview_data = {
+        name_column_alias: 'Child1', parent_column_alias: '1'
+    }
+    assert preview_data == expected_preview_data
+
+
 def test_foreign_key_record_api_all_column_previews(publication_tables, client):
     author_table, publisher_table, publication_table, checkouts_table = publication_tables
     author_template_columns = author_table.get_columns_by_name(["first_name", "last_name", "id"])