diff --git a/.dockerignore b/.dockerignore
index e79c44c7e..21f4569b9 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -2,4 +2,6 @@
 **/node_modules
 **/.pytest_cache
 *.iml
-.idea/
\ No newline at end of file
+.idea/
+web-frontend/reports/
+backend/reports/
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 093a5b4fd..6e1328e06 100644
--- a/.gitignore
+++ b/.gitignore
@@ -96,6 +96,8 @@ venv/
 
 web-frontend/plugins/
 backend/plugins/
+web-frontend/reports/
+backend/reports/
 
 .idea/
 *.iml
@@ -115,3 +117,6 @@ out/
 vetur.config.js
 
 formula/out/
+
+.coverage
+junit.xml
\ No newline at end of file
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index a50d8a3f9..39ce89b36 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,70 +1,599 @@
-before_script:
-  - apt-get update && apt-get -y install make curl gnupg2
+# == Summary of Baserow's CI workflow:
+#
+# This file contains the gitlab CI job definitions that build and test Baserow
+# automatically.
+#
+# === Overview of how Baserow uses git branches
+#
+# * `develop` is the branch we merge newly developed features onto from feature
+#   branches.
+# * a feature branch is a branch made starting off `develop` containing a specific
+#   new feature, when finished it will be merged back onto `develop`.
+# * `master` is the branch which contains official releases of Baserow, to do so we
+#   periodically merge the latest changes from `develop` onto `master` and then tag
+#   that new master commit with a git tag containing the version (1.8.2 etc).
+#
+# === How new version of Baserow is released to Dockerhub
+#
+# A. Create an MR from develop to master and merge it.
+# B. Wait for the merge commit pipeline succeed on master which will build and test the
+#    images.
+# C. Tag the merge commit in the Gitlab GUI with the git tag being the Baserow version
+#    (1.8.2, 1.0, etc).
+# D. Gitlab will make a new pipeline for the tag which will push the images built in
+#    step B to Dockerhub. If step B failed or has not completed yet then this pipeline
+#    will fail and not push anything.
+#
+# === What Gitlab CI steps are configured to run and when
+#
+# See below for the high level summary of the steps Gitlab will run to build, test and
+# release Baserow images in various scenarios depending on the branches involved.
+#
+# ==== On the master branch - When MR Merged/commit pushed/branch made
+#
+#   1. The backend and web-frontend dev images will be built and pushed to the
+#      gitlab ci image repo.
+#      1. A `{image_dev}:ci-latest-$CI_COMMIT_SHA` image is pushed for the next stages.
+#      2. A `{image_dev}:ci-latest-$BRANCH_NAME` image is pushed to cache future runs.
+#   2. The pushed `ci-latest-$CI_COMMIT_SHA` images will be tested and linted. If a
+#      previously successful test/lint run is found for the same/prev commit AND no
+#      files have changed which could possibly change the result this is skipped.
+#   3. Cached from the `ci-latest-$CI_COMMIT_SHA` image the non-dev images will be built
+#      and then both the dev and non-dev images will be with tagged marking them as
+#      tested and pushed to the gitlab ci repo.
+#   4. Trigger a pipeline in any downstream repos that depend on this one.
+#
+# ==== On the develop branch - When MR Merged/new commit pushed
+#
+#   The build and testing steps 1, 2 and 3 from above are run first and then:
+#   4. Push the tested images from step 3 to the Dockerhub repo under the
+#      `develop-latest` tag.
+#   5. Trigger a pipeline in any downstream repos that depend on this one.
+#
+# ==== On feature branches - When MR Merged/new commit pushed
+#
+#   The build and testing steps 1, 2 and 3 from above are run.
+#
+# ===== On the latest commit on master - When a Git tag is created
+#
+#   This is done when we have merged the latest changes from develop on master, and we
+#   want to release them as a new version of Baserow. Gitlab will automatically detect
+#   the new git tag and only do the following:
+#
+#   1. Push the images built from step 3 above (or fail if they don't exist) to the
+#      Dockerhub repo with the tags:
+#      1. `latest`
+#      2. `${git tag}`
+#
+# ==== Older commit on master - When a Git tag created
+#
+#   1. Push the images built from step 3 above (or fail if they don't exist) to the
+#      Dockerhub repo with the tags:
+#      1. `${git tag}`
+#
+# ==== Any non-master commit - When a Git tag created
+#
+#   1. Fail as only master commits should be tagged/released.
+#
+# == Cleanup
+#
+# Images with tags starting with `ci-latest` or `ci-tested` (made in steps 1. and 3.)
+# will be deleted after they are 7 days old by a job that runs daily at 11AM CET.
+
+include: '/.gitlab/ci_includes/jobs.yml'
 
 stages:
-  - lint
-  - test
   - build
+  - test
+  - build-final
+  - publish
 
-web-frontend-eslint:
-  stage: lint
-  image: node:12
-  script:
-    - cd web-frontend
-    - make install-dependencies
-    - make eslint
+variables:
+  ENABLE_JOB_SKIPPING:
+    value: "true"
+    description: "If set to false then tests and lints will be forced to run and not use previously cached results."
+  ENABLE_COVERAGE:
+    value: "true"
+    description: "If set to false then tests will not generate coverage or testing reports used by gitlab to show nicer MRs."
+  # An image repo which is used for storing and passing images between ci pipeline jobs
+  # and also speeding up ci builds by caching from the latest ci image when building.
+  CI_IMAGE_REPO: $CI_REGISTRY_IMAGE/ci
+  # Any images with tags prefixed with the two variables below will be cleaned up automatically
+  # by our gitlab cleanup job:
+  # (https://gitlab.com/bramw/baserow/-/settings/packages_and_registries).
+  #
+  # ## Note:
+  #   These cleanup tag prefixes are needed as gitlab only supports cleanup by defining
+  #   a regex that matches tags, so we can't do cleanup differently based on image name
+  #   or repo...
+  #
+  # IMPORTANT: UPDATE GITLAB CONTAINER REPO CLEANUP JOB REGEX IF YOU CHANGE THIS
+  CLEANUP_JOB_CI_TAG_PREFIX: ci-latest-
+  # IMPORTANT: UPDATE GITLAB CONTAINER REPO CLEANUP JOB REGEX IF YOU CHANGE THIS
+  TESTED_IMAGE_PREFIX: ci-tested-
+  # An image repo where dev and normal images will be released to for public usage after
+  # they have been successfully built and tested.
+  RELEASE_IMAGE_REPO: $CI_REGISTRY_IMAGE/testing
+  BACKEND_IMAGE_NAME: backend
+  BACKEND_DEV_IMAGE_NAME: backend_dev
+  WEBFRONTEND_IMAGE_NAME: web-frontend
+  WEBFRONTEND_DEV_IMAGE_NAME: web-frontend_dev
+  BACKEND_CI_DEV_IMAGE: $CI_IMAGE_REPO/$BACKEND_DEV_IMAGE_NAME:$CLEANUP_JOB_CI_TAG_PREFIX$CI_COMMIT_SHORT_SHA
+  WEBFRONTEND_CI_DEV_IMAGE: $CI_IMAGE_REPO/$WEBFRONTEND_DEV_IMAGE_NAME:$CLEANUP_JOB_CI_TAG_PREFIX$CI_COMMIT_SHORT_SHA
+  # Once images are tested they will publish under these names to ensure that any
+  # tag only runs of the pipeline can never publish untested images.
+  TESTED_BACKEND_CI_IMAGE: $CI_IMAGE_REPO/$BACKEND_IMAGE_NAME:$TESTED_IMAGE_PREFIX$CI_COMMIT_SHORT_SHA
+  TESTED_WEBFRONTEND_CI_IMAGE: $CI_IMAGE_REPO/$WEBFRONTEND_IMAGE_NAME:$TESTED_IMAGE_PREFIX$CI_COMMIT_SHORT_SHA
+  TESTED_BACKEND_CI_DEV_IMAGE: $CI_IMAGE_REPO/$BACKEND_DEV_IMAGE_NAME:$TESTED_IMAGE_PREFIX$CI_COMMIT_SHORT_SHA
+  TESTED_WEBFRONTEND_CI_DEV_IMAGE: $CI_IMAGE_REPO/$WEBFRONTEND_DEV_IMAGE_NAME:$TESTED_IMAGE_PREFIX$CI_COMMIT_SHORT_SHA
+  # Used to tag the latest images on $DEVELOP_BRANCH_NAME
+  DEVELOP_LATEST_TAG: develop-latest
+  # Names of important branches used to decide when to run certain jobs.
+  MASTER_BRANCH_NAME: master
+  DEVELOP_BRANCH_NAME: develop
+  # The locations of the various dockerfiles to build.
+  BACKEND_DOCKERFILE_PATH: $CI_PROJECT_DIR/backend/Dockerfile
+  WEBFRONTEND_DOCKERFILE_PATH: $CI_PROJECT_DIR/web-frontend/Dockerfile
+  # The image path for the helper CI util image that will be built and pushed to.
+  CI_UTIL_IMAGE: $CI_IMAGE_REPO/ci_util_image:latest
 
-web-frontend-stylelint:
-  stage: lint
-  image: node:12
-  script:
-    - cd web-frontend
-    - make install-dependencies
-    - make stylelint
-
-web-frontend-test:
-  stage: test
-  image: node:12
-  script:
-    - cd web-frontend
-    - make install-dependencies
-    - make test
-
-backend-flake8:
-  stage: lint
-  image: python:3.7
-  script:
-    - cd backend
-    - make install-dependencies
-    - make install-dev-dependencies
-    - make lint
-
-backend-pytest:
-  stage: test
-  image: python:3.7
+build-ci-util-image:
+  image: docker:20.10.12
+  stage: build
   services:
+    - docker:20.10.12-dind
+  variables:
+    DOCKER_BUILDKIT: 1
+    DOCKER_HOST: tcp://docker:2376
+    DOCKER_TLS_CERTDIR: "/certs"
+  before_script:
+    - |
+      echo "$CI_REGISTRY_PASSWORD" | \
+        docker login -u "$CI_REGISTRY_USER" "$CI_REGISTRY" --password-stdin
+  script:
+    - cd .gitlab/ci_util_image
+    - docker build -t $CI_UTIL_IMAGE .
+    - docker push $CI_UTIL_IMAGE
+  only:
+    changes:
+      - .gitlab/ci_util_image/*
+
+# If pipeline not triggered by tag :
+# - Builds the backend dev image and stores in ci repo for next stages.
+build-backend-image:
+  extends: .build-baserow-image
+  variables:
+    DEV_IMAGE_NAME: $BACKEND_DEV_IMAGE_NAME
+    DOCKERFILE_PATH: $BACKEND_DOCKERFILE_PATH
+
+# If pipeline not triggered by tag and backend code has changed:
+# - Runs the backend lint
+backend-lint:
+  extends:
+    - .docker-image-test-stage
+  script:
+    - docker run --rm $BACKEND_CI_DEV_IMAGE lint
+  only:
+    # Skip linting if no change to files
+    changes:
+      - backend/**/*
+      - premium/backend/**/*
+
+# If pipeline not triggered by tag and backend code has not changed:
+# - If there is a previous successful backend lint run in the cache then skip.
+# - Otherwise runs backend lint.
+no-backend-changes-so-try-skip-lint:
+  extends:
+    - .skippable-job
+    - backend-lint
+  variables:
+    SKIP_JOB_NAME: backend-lint
+  # Override inherited only block, so we can run this job in the
+  # exact opposite situations.
+  only: null
+  except:
+    changes:
+      - backend/**/*
+      - premium/backend/**/*
+
+# If pipeline not triggered by tag and backend code has changed:
+# - Runs the backend tests (the first 1/3)
+# - Generates coverage db's and stores as artifact for later coverage merge and report
+backend-test-group-1:
+  extends:
+    - .docker-image-test-stage
+  services:
+    - docker:20.10.12-dind
     - name: postgres:11.3
       alias: db
     - name: liminspace/mjml-tcpserver:0.10
       alias: mjml
   variables:
+    DOCKER_HOST: tcp://docker:2376
+    DOCKER_TLS_CERTDIR: "/certs"
     POSTGRES_USER: baserow
     POSTGRES_PASSWORD: baserow
     POSTGRES_DB: baserow
+    PYTEST_SPLIT_GROUP: 1
   script:
-    - cd backend
-    - make install-dependencies
-    - make install-dev-dependencies
-    - export PYTHONPATH=$CI_PROJECT_DIR/backend/src:$CI_PROJECT_DIR/premium/backend/src
-    - make test
+    - MJML_IP=$(cat /etc/hosts | awk '{if ($2 == "mjml") print $1;}')
+    - ping -w 2 $MJML_IP
+    - DB_IP=$(cat /etc/hosts | awk '{if ($2 == "db") print $1;}')
+    - ping -w 2 $DB_IP
+    - mkdir -p reports
+    - TEST_TYPE=$([[ "$ENABLE_COVERAGE" = "true" ]] && echo "ci-test" || echo "test")
+    - |
+      docker run \
+        -e PYTEST_SPLITS=3 \
+        -e PYTEST_SPLIT_GROUP=$PYTEST_SPLIT_GROUP \
+        --name=baserow_backend_test_container \
+        --add-host="db:$DB_IP" \
+        --add-host="mjml:$MJML_IP" \
+        $BACKEND_CI_DEV_IMAGE $TEST_TYPE;
+    - docker cp baserow_backend_test_container:/baserow/backend/reports .
+    - docker rm baserow_backend_test_container
+    - |
+      if [[ $PYTEST_SPLIT_GROUP = 1 ]]; then
+        docker run -e DATABASE_USER=baserow \
+          -e DATABASE_NAME=baserow \
+          -e DATABASE_HOST=db \
+          -e DATABASE_PASSWORD=baserow \
+          --rm \
+          --add-host="db:$DB_IP" \
+          --add-host="mjml:$MJML_IP" \
+          $BACKEND_CI_DEV_IMAGE ci-check-startup;
+      fi
+  only:
+    # Skip testing on if no change to backend files
+    changes:
+      - backend/**/*
+      - premium/backend/**/*
+  artifacts:
+    paths:
+      - reports/
+    reports:
+      junit: reports/report.xml
 
-backend-setup:
-  stage: build
-  image: python:3.7
+# If pipeline not triggered by tag and backend code has not changed:
+# - If there is a previous successful backend test run then download and reuse its
+#   artifacts (coverage etc).
+# - Otherwise runs the backend-test job like normal.
+no-backend-changes-so-try-skip-tests-group-1:
+  extends:
+    - backend-test-group-1
+    - .skippable-job
+  variables:
+    SKIP_JOB_NAME: backend-test-group-1
+    DOWNLOAD_AND_UNPACK_ARTIFACTS_ON_SKIP: 'true'
+  # Override inherited only block, so we can run this job in the
+  # exact opposite situations.
+  only: null
+  except:
+    changes:
+      - backend/**/*
+      - premium/backend/**/*
+
+# Create 2 more separate groups to parallelize pytest by using separate groups to
+# decrease overall build time. Pytest xdist doesn't help as the gitlab saas runners only
+# have a single virtual core so `pytest -n 2+` slows things down.
+backend-test-group-2:
+  extends: backend-test-group-1
+  variables:
+    PYTEST_SPLIT_GROUP: 2
+
+no-backend-changes-so-try-skip-tests-group-2:
+  extends: no-backend-changes-so-try-skip-tests-group-1
+  variables:
+    SKIP_JOB_NAME: backend-test-group-2
+    PYTEST_SPLIT_GROUP: 2
+
+backend-test-group-3:
+  extends: backend-test-group-1
+  variables:
+    PYTEST_SPLIT_GROUP: 3
+
+no-backend-changes-so-try-skip-tests-group-3:
+  extends: no-backend-changes-so-try-skip-tests-group-1
+  variables:
+    SKIP_JOB_NAME: backend-test-group-3
+    PYTEST_SPLIT_GROUP: 3
+
+# Collects together all the separate backend coverage databases from previous jobs and
+# combines them to generate a single report for gitlab to use. Gitlab itself does not
+# correctly merge these if you just add them all separately into artifacts->reports->
+# cobertura.
+backend-coverage:
+  image: $CI_UTIL_IMAGE
+  stage: build-final
+  interruptible: true
+  only:
+    variables:
+      - $ENABLE_COVERAGE == "true"
+  # Prevent rebuilds when tagging as all we want to do is tag and push 
+  except:
+    variables:
+      - $CI_COMMIT_TAG
+  # Depend on the `reports` artifacts from the previous jobs
+  dependencies:
+    - backend-test-group-1
+    - backend-test-group-2
+    - backend-test-group-3
+    # If the actual tests were skipped then the artifacts will be on these jobs instead
+    - no-backend-changes-so-try-skip-tests-group-1
+    - no-backend-changes-so-try-skip-tests-group-2
+    - no-backend-changes-so-try-skip-tests-group-3
   script:
-    - pip install -e ./backend
-    - python -c 'import baserow'
-    - pip install -e ./premium/backend
-    - python -c 'import baserow_premium'
-    - export DJANGO_SETTINGS_MODULE='baserow.config.settings.base'
-    - timeout --preserve-status 10s gunicorn --workers=1 -b 0.0.0.0:8000 -k uvicorn.workers.UvicornWorker baserow.config.asgi:application
+    - . /baserow/venv/bin/activate
+    # The reports artifacts will be extracted before the script runs into reports by
+    # gitlab
+    - cp reports/.coverage.* .
+    - export COVERAGE_RCFILE=backend/.coveragerc
+    - coverage combine
+    - coverage report
+    - coverage xml -o coverage.xml
+  artifacts:
+    reports:
+      cobertura: coverage.xml
+  coverage: '/^TOTAL.+?(\d+\%)$/'
+
+# If pipeline not triggered by tag:
+# - Build and store non-dev images in CI repo under the `ci-tested` tag so we know
+#   those images have passed the tests.
+build-final-backend-image:
+  extends: .build-final-baserow-image
+  variables:
+    IMAGE_NAME: $BACKEND_IMAGE_NAME
+    DEV_IMAGE_NAME: $BACKEND_DEV_IMAGE_NAME
+    DOCKERFILE_PATH: $BACKEND_DOCKERFILE_PATH
+
+# ==================================== WEB-FRONTEND ====================================
+
+# If pipeline not triggered by tag:
+# - Builds the web-frontend dev image and stores in ci repo for next stages.
+build-web-frontend-image:
+  extends: .build-baserow-image
+  variables:
+    DEV_IMAGE_NAME: $WEBFRONTEND_DEV_IMAGE_NAME
+    DOCKERFILE_PATH: $WEBFRONTEND_DOCKERFILE_PATH
+
+# If pipeline not triggered by tag and web-frontend code has changed:
+# - Runs eslint and stylelint
+# - Stores a web-frontend_lint_success file in the cache so future pipelines can skip
+#   if no file changes.
+web-frontend-lint:
+  extends:
+    - .docker-image-test-stage
+  script:
+    - docker run --rm $WEBFRONTEND_CI_DEV_IMAGE lint
+  only:
+    changes:
+      - web-frontend/**/*
+      - premium/web-frontend/**/*
+
+# If pipeline not triggered by tag and web-frontend code has not changed:
+# - If there is a previous successful lint run in the cache then skip.
+# - otherwise runs lint and stores success file in cache if successful.
+no-web-frontend-changes-so-try-skip-lint:
+  extends:
+    - web-frontend-lint
+    - .skippable-job
+  variables:
+    SKIP_JOB_NAME: web-frontend-lint
+  # Override inherited only block so we can run this job in the
+  # exact opposite situations.
+  only: null
+  except:
+    changes:
+      - web-frontend/**/*
+      - premium/web-frontend/**/*
+
+# If pipeline not triggered by tag and web-frontend code has changed:
+# - Runs the web-frontend tests
+# - Generates coverage and testing reports
+# - Stores the reports in the cache if successful
+web-frontend-test:
+  extends:
+    - .docker-image-test-stage
+  script:
+    - mkdir reports/ -p
+    - TEST_TYPE=$([[ "$ENABLE_COVERAGE" = "true" ]] && echo "ci-test" || echo "test")
+    - |
+      docker run --name=webfrontend_test $WEBFRONTEND_CI_DEV_IMAGE $TEST_TYPE \
+        | tee reports/stdout.txt;
+    - docker cp webfrontend_test:/baserow/reports .
+    - docker rm webfrontend_test
+  only:
+    # Skip testing on if no change to web-frontend files
+    changes:
+      - web-frontend/**/*
+      - premium/web-frontend/**/*
+  artifacts:
+    paths:
+      - reports/
+    reports:
+      cobertura: reports/coverage/cobertura-coverage.xml
+      junit: reports/junit.xml
+  coverage: '/Lines\s*:\s*(\d+.?\d*)%/'
+
+# If pipeline not triggered by tag and web-frontend code has not changed:
+# - If there is a previous successful webfrontend test run in the cache then skip and
+#   unpack its coverage reports.
+# - Otherwise runs the tests, coverage reporting and stores in cache if successful
+#   as normal
+no-web-frontend-changes-so-try-skip-tests:
+  extends:
+    - web-frontend-test
+    - .skippable-job
+  variables:
+    SKIP_JOB_NAME: web-frontend-test
+    DOWNLOAD_AND_UNPACK_ARTIFACTS_ON_SKIP: 'true'
+  # Override inherited only block so we can run this job in the
+  # exact opposite situations.
+  only: null
+  except:
+    changes:
+      - web-frontend/**/*
+      - premium/web-frontend/**/*
+
+# If pipeline not triggered by tag:
+# - Build and store non-dev images in CI repo under the `ci-tested` tag so we know
+#   those images have passed the tests.
+build-final-web-frontend-image:
+  extends: .build-final-baserow-image
+  variables:
+    IMAGE_NAME: $WEBFRONTEND_IMAGE_NAME
+    DEV_IMAGE_NAME: $WEBFRONTEND_DEV_IMAGE_NAME
+    DOCKERFILE_PATH: $WEBFRONTEND_DOCKERFILE_PATH
+
+
+# ================================== TRIGGER SAAS =====================================
+
+# Triggers a special pipeline in dependant project and passes various variables to it.
+# Only on master and develop.
+trigger-saas-build:
+  stage: publish
+  inherit:
+    variables:
+      - CI_COMMIT_BRANCH
+      - TESTED_BACKEND_CI_IMAGE
+      - TESTED_WEBFRONTEND_CI_IMAGE
+      - CI_COMMIT_SHA
+      - CI_COMMIT_SHORT_SHA
+      - DEVELOP_BRANCH_NAME
+      - MASTER_BRANCH_NAME
+  variables:
+    UPSTREAM_SHA: $CI_COMMIT_SHA
+    UPSTREAM_SHORT_SHA: $CI_COMMIT_SHORT_SHA
+    UPSTREAM_TESTED_BACKEND_CI_IMAGE: $TESTED_BACKEND_CI_IMAGE
+    UPSTREAM_TESTED_WEBFRONTEND_CI_IMAGE: $TESTED_WEBFRONTEND_CI_IMAGE
+  only:
+    changes:
+      - web-frontend/**/*
+      - premium/web-frontend/**/*
+      - backend/**/*
+      - premium/backend/**/*
+    variables:
+      - ($CI_COMMIT_BRANCH == $DEVELOP_BRANCH_NAME || $CI_COMMIT_BRANCH == $MASTER_BRANCH_NAME)
+  allow_failure: true
+  trigger:
+    project: bramw/baserow-saas
+    branch: $CI_COMMIT_BRANCH
+
+# ================================== PUSHING BACKEND ==================================
+
+# Push baserow/backend:develop_latest
+publish-backend-develop-latest-image:
+  extends: .publish-baserow-image
+  only:
+    variables:
+      - $CI_COMMIT_BRANCH == $DEVELOP_BRANCH_NAME
+  variables:
+    SKIP_IF_NOT_LATEST_COMMIT_ON_BRANCH: $DEVELOP_BRANCH_NAME
+    SOURCE_IMAGE: $TESTED_BACKEND_CI_IMAGE
+    TARGET_IMAGE: "$RELEASE_IMAGE_REPO/$BACKEND_IMAGE_NAME:$DEVELOP_LATEST_TAG"
+    TARGET_REGISTRY: $CI_REGISTRY
+    TARGET_REGISTRY_PASSWORD: $CI_REGISTRY_PASSWORD
+    TARGET_REGISTRY_USER: $CI_REGISTRY_USER
+
+
+# Push baserow/backend_dev:develop_latest
+publish-backend-develop-latest-dev-image:
+  extends: .publish-baserow-image
+  only:
+    variables:
+      - $CI_COMMIT_BRANCH == $DEVELOP_BRANCH_NAME
+  variables:
+    SKIP_IF_NOT_LATEST_COMMIT_ON_BRANCH: $DEVELOP_BRANCH_NAME
+    SOURCE_IMAGE: $TESTED_BACKEND_CI_DEV_IMAGE
+    TARGET_IMAGE: "$RELEASE_IMAGE_REPO/$BACKEND_DEV_IMAGE_NAME:$DEVELOP_LATEST_TAG"
+    TARGET_REGISTRY: $CI_REGISTRY
+    TARGET_REGISTRY_PASSWORD: $CI_REGISTRY_PASSWORD
+    TARGET_REGISTRY_USER: $CI_REGISTRY_USER
+
+# Push baserow/backend:$VERSION_GIT_TAG
+publish-backend-release-tagged-image:
+  extends: .publish-baserow-image
+  only:
+    variables:
+      - $CI_COMMIT_TAG
+  variables:
+    SKIP_IF_TAG_NOT_ON_BRANCH: $MASTER_BRANCH_NAME
+    SOURCE_IMAGE: $TESTED_BACKEND_CI_IMAGE
+    TARGET_IMAGE: "$RELEASE_IMAGE_REPO/$BACKEND_IMAGE_NAME:$CI_COMMIT_TAG"
+    TARGET_REGISTRY: $CI_REGISTRY
+    TARGET_REGISTRY_PASSWORD: $CI_REGISTRY_PASSWORD
+    TARGET_REGISTRY_USER: $CI_REGISTRY_USER
+
+# Push baserow/backend:latest
+publish-backend-latest-release-image:
+  extends: .publish-baserow-image
+  only:
+    variables:
+      - $CI_COMMIT_TAG
+  variables:
+    SKIP_IF_NOT_LATEST_COMMIT_ON_BRANCH: $MASTER_BRANCH_NAME
+    SKIP_IF_TAG_NOT_ON_BRANCH: $MASTER_BRANCH_NAME
+    SOURCE_IMAGE: $TESTED_BACKEND_CI_IMAGE
+    TARGET_IMAGE: "$RELEASE_IMAGE_REPO/$BACKEND_IMAGE_NAME:latest"
+    TARGET_REGISTRY: $CI_REGISTRY
+    TARGET_REGISTRY_PASSWORD: $CI_REGISTRY_PASSWORD
+    TARGET_REGISTRY_USER: $CI_REGISTRY_USER
+
+# ================================ PUSHING WEB-FRONTEND ===============================
+
+# Push baserow/web-frontend:develop_latest
+publish-webfrontend-develop-latest-image:
+  extends: .publish-baserow-image
+  only:
+    variables:
+      - $CI_COMMIT_BRANCH == $DEVELOP_BRANCH_NAME
+  variables:
+    SKIP_IF_NOT_LATEST_COMMIT_ON_BRANCH: $DEVELOP_BRANCH_NAME
+    SOURCE_IMAGE: $TESTED_WEBFRONTEND_CI_IMAGE
+    TARGET_IMAGE: "$RELEASE_IMAGE_REPO/$WEBFRONTEND_IMAGE_NAME:$DEVELOP_LATEST_TAG"
+    TARGET_REGISTRY: $CI_REGISTRY
+    TARGET_REGISTRY_PASSWORD: $CI_REGISTRY_PASSWORD
+    TARGET_REGISTRY_USER: $CI_REGISTRY_USER
+
+# Push baserow/web-frontend_dev:develop_latest
+publish-webfrontend-develop-latest-dev-image:
+  extends: .publish-baserow-image
+  only:
+    variables:
+      - $CI_COMMIT_BRANCH == $DEVELOP_BRANCH_NAME
+  variables:
+    SKIP_IF_NOT_LATEST_COMMIT_ON_BRANCH: $DEVELOP_BRANCH_NAME
+    SOURCE_IMAGE: $TESTED_WEBFRONTEND_CI_DEV_IMAGE
+    TARGET_IMAGE: "$RELEASE_IMAGE_REPO/$WEBFRONTEND_DEV_IMAGE_NAME:$DEVELOP_LATEST_TAG"
+    TARGET_REGISTRY: $CI_REGISTRY
+    TARGET_REGISTRY_PASSWORD: $CI_REGISTRY_PASSWORD
+    TARGET_REGISTRY_USER: $CI_REGISTRY_USER
+
+# Push baserow/web-frontend:$VERSION_GIT_TAG
+publish-webfrontend-release-tagged-image:
+  extends: .publish-baserow-image
+  only:
+    variables:
+      - $CI_COMMIT_TAG
+  variables:
+    SKIP_IF_TAG_NOT_ON_BRANCH: $MASTER_BRANCH_NAME
+    SOURCE_IMAGE: $TESTED_WEBFRONTEND_CI_IMAGE
+    TARGET_IMAGE: "$RELEASE_IMAGE_REPO/$WEBFRONTEND_IMAGE_NAME:$CI_COMMIT_TAG"
+    TARGET_REGISTRY: $CI_REGISTRY
+    TARGET_REGISTRY_PASSWORD: $CI_REGISTRY_PASSWORD
+    TARGET_REGISTRY_USER: $CI_REGISTRY_USER
+
+# Push baserow/web-frontend:latest
+publish-webfrontend-latest-release-image:
+  extends: .publish-baserow-image
+  only:
+    variables:
+      - $CI_COMMIT_TAG
+  variables:
+    SKIP_IF_NOT_LATEST_COMMIT_ON_BRANCH: $MASTER_BRANCH_NAME
+    SKIP_IF_TAG_NOT_ON_BRANCH: $MASTER_BRANCH_NAME
+    SOURCE_IMAGE: $TESTED_WEBFRONTEND_CI_IMAGE
+    TARGET_IMAGE: "$RELEASE_IMAGE_REPO/$WEBFRONTEND_IMAGE_NAME:latest"
+    TARGET_REGISTRY: $CI_REGISTRY
+    TARGET_REGISTRY_PASSWORD: $CI_REGISTRY_PASSWORD
+    TARGET_REGISTRY_USER: $CI_REGISTRY_USER
diff --git a/.gitlab/ci_includes/jobs.yml b/.gitlab/ci_includes/jobs.yml
new file mode 100644
index 000000000..65be55a99
--- /dev/null
+++ b/.gitlab/ci_includes/jobs.yml
@@ -0,0 +1,409 @@
+# ============== "Abstract" ci stages used by real stages =======================
+
+# Builds a dev version of a specific Dockerfile (--target dev) using a previous CI
+# image or the latest develop image as a cache to speed up the build. Tags and pushes
+# the resulting dev image for later stages in the pipeline to use.
+#
+# To extend this stage set the DOCKERFILE_PATH and IMAGE_NAME variables.
+.build-baserow-image:
+  image: docker:20.10.12
+  stage: build
+  interruptible: true
+  # Prevent rebuilds when tagging as all we want to do is tag and push the already built image
+  except:
+    refs:
+      - pipelines
+    variables:
+      - $CI_COMMIT_TAG
+  services:
+    - docker:20.10.12-dind
+  variables:
+    DOCKER_BUILDKIT: 1
+    DOCKER_HOST: tcp://docker:2376
+    DOCKER_TLS_CERTDIR: "/certs"
+    IMAGE_LABELS: >
+      --label org.opencontainers.image.vendor=$CI_PROJECT_URL
+      --label org.opencontainers.image.authors=$CI_PROJECT_URL
+      --label org.opencontainers.image.revision=$CI_COMMIT_SHA
+      --label org.opencontainers.image.source=$CI_PROJECT_URL
+      --label org.opencontainers.image.documentation=$CI_PROJECT_URL
+      --label org.opencontainers.image.licenses=$CI_PROJECT_URL
+      --label org.opencontainers.image.url=$CI_PROJECT_URL
+      --label vcs-url=$CI_PROJECT_URL
+      --label com.gitlab.ci.user=$CI_SERVER_URL/$GITLAB_USER_LOGIN
+      --label com.gitlab.ci.email=$GITLAB_USER_EMAIL
+      --label com.gitlab.ci.tagorbranch=$CI_COMMIT_REF_NAME
+      --label com.gitlab.ci.pipelineurl=$CI_PIPELINE_URL
+      --label com.gitlab.ci.commiturl=$CI_PROJECT_URL/commit/$CI_COMMIT_SHA
+      --label com.gitlab.ci.cijoburl=$CI_JOB_URL
+      --label com.gitlab.ci.mrurl=$CI_PROJECT_URL/-/merge_requests/$CI_MERGE_REQUEST_ID
+      --label org.opencontainers.image.ref.name=$CI_IMAGE_REPO:$CI_COMMIT_REF_NAME
+  script:
+    - |
+      echo "$CI_REGISTRY_PASSWORD" | \
+        docker login -u "$CI_REGISTRY_USER" "$CI_REGISTRY" --password-stdin
+      if [[ -z "$DOCKERFILE_PATH" ]]; then
+          echo "Must provide DOCKERFILE_PATH as a job variable" 2>&1
+          exit 1
+      fi
+      if [[ -z "$DEV_IMAGE_NAME" ]]; then
+          echo "Must provide DEV_IMAGE_NAME as a job variable" 2>&1
+          exit 1
+      fi
+
+
+      # Try cache from this branches latest image, if not fall back to the latest
+      # develop image.
+      # Ensure we don't go over 128 char docker tag length limit
+      TRUNCATED_BRANCH_NAME=${CI_COMMIT_REF_NAME:0:100}
+      CI_DEV_LATEST_BRANCH_TAG=$CLEANUP_JOB_CI_TAG_PREFIX$TRUNCATED_BRANCH_NAME
+
+      LATEST_CI_IMAGE="$CI_IMAGE_REPO/$DEV_IMAGE_NAME:$CI_DEV_LATEST_BRANCH_TAG"
+      # ===== 1. Try pull an image we can use to cache the build with =====
+
+      # First try the latest CI image for this branch
+      CACHE_IMAGE=$LATEST_CI_IMAGE
+      if ! docker pull $CACHE_IMAGE; then
+
+          # If that didnt work try the latest dev image from develop
+          CACHE_IMAGE="$RELEASE_IMAGE_REPO/$DEV_IMAGE_NAME:$DEVELOP_LATEST_TAG";
+          if ! docker pull $CACHE_IMAGE; then
+             CACHE_IMAGE=""
+          fi
+      fi
+
+      EXTRA_BUILD_ARGS=""
+      if [[ -n "$CACHE_IMAGE" ]]; then
+        echo "Caching docker build from $CACHE_IMAGE";
+        EXTRA_BUILD_ARGS="$EXTRA_BUILD_ARGS --cache-from $CACHE_IMAGE";
+      else
+        echo "Couldn't find image to cache build using"
+      fi
+
+      # This image tag is one that can be used by subsequent build steps, using the
+      # latest one might introduce race conditions with concurrent pipelines. Instead
+      # by using a simple name + sha we know we will be getting the right image later on
+      # and we can easily re-construct this image path also as $CI_COMMIT_SHORT_SHA is
+      # available in all stages.
+      CI_IMAGE_PATH=$CI_IMAGE_REPO/$DEV_IMAGE_NAME:$CLEANUP_JOB_CI_TAG_PREFIX$CI_COMMIT_SHORT_SHA
+
+      # ===== 2. Build a dev image to be used in subsequent CI stages =====
+
+      if [[ -n "$BUILD_FROM_IMAGE" ]]; then
+        EXTRA_BUILD_ARGS="$EXTRA_BUILD_ARGS --build-arg FROM_IMAGE=$BUILD_FROM_IMAGE";
+        echo "Building from $BUILD_FROM_IMAGE."
+      fi
+
+      # * Use `--build-arg BUILDKIT_INLINE_CACHE=1` to ensure this image's itermediate
+      #    layers will be cached so builds caching from this image can use those layers.
+      # * $CACHE_ARG is a --cache-from if we have an existing image that we can use
+      #    to speed up this build.
+      # * Target the dev image as we want to run tests and linting in this image.
+      # * Tag as both the ci image for use in later stages and the latest ci image to
+      #   cache any future ci pipeline runs.
+      docker build \
+        --build-arg BUILDKIT_INLINE_CACHE=1 \
+        $EXTRA_BUILD_ARGS \
+        $IMAGE_LABELS \
+        --target dev \
+        --tag $CI_IMAGE_PATH \
+        --tag $LATEST_CI_IMAGE \
+        -f $DOCKERFILE_PATH .;
+
+      # ===== 3. Push the CI image for the next stages and latest ci image cache =====
+
+      docker push $CI_IMAGE_PATH
+      docker push $LATEST_CI_IMAGE
+
+# Builds a non-dev (no docker build target provided) and fully labelled final image
+# and tags and pushes the non-dev and dev images using $TESTED_IMAGE_PREFIX to mark
+# them as being successfully tested for the publishing jobs to use.
+#
+# To extend this stage set the DOCKERFILE_PATH, IMAGE_NAME and DEV_IMAGE_NAME variables.
+.build-final-baserow-image:
+  image: $CI_UTIL_IMAGE
+  stage: build-final
+  interruptible: true
+  # Prevent rebuilds when tagging as all we want to do is tag and push
+  except:
+    refs:
+      - pipelines
+    variables:
+      - $CI_COMMIT_TAG
+  services:
+    - docker:20.10.12-dind
+  variables:
+    DOCKER_BUILDKIT: 1
+    DOCKER_HOST: tcp://docker:2376
+    DOCKER_TLS_CERTDIR: "/certs"
+    IMAGE_LABELS: >
+      --label org.opencontainers.image.vendor=$CI_PROJECT_URL
+      --label org.opencontainers.image.authors=$CI_PROJECT_URL
+      --label org.opencontainers.image.revision=$CI_COMMIT_SHA
+      --label org.opencontainers.image.source=$CI_PROJECT_URL
+      --label org.opencontainers.image.documentation=$CI_PROJECT_URL
+      --label org.opencontainers.image.licenses=$CI_PROJECT_URL
+      --label org.opencontainers.image.url=$CI_PROJECT_URL
+      --label vcs-url=$CI_PROJECT_URL
+      --label com.gitlab.ci.user=$CI_SERVER_URL/$GITLAB_USER_LOGIN
+      --label com.gitlab.ci.email=$GITLAB_USER_EMAIL
+      --label com.gitlab.ci.tagorbranch=$CI_COMMIT_REF_NAME
+      --label com.gitlab.ci.pipelineurl=$CI_PIPELINE_URL
+      --label com.gitlab.ci.commiturl=$CI_PROJECT_URL/commit/$CI_COMMIT_SHA
+      --label com.gitlab.ci.cijoburl=$CI_JOB_URL
+      --label com.gitlab.ci.mrurl=$CI_PROJECT_URL/-/merge_requests/$CI_MERGE_REQUEST_ID
+      --label org.opencontainers.image.ref.name=$RELEASE_IMAGE_REPO:$CI_COMMIT_REF_NAME
+  script:
+    - |
+      echo "$CI_REGISTRY_PASSWORD" | \
+        docker login -u "$CI_REGISTRY_USER" "$CI_REGISTRY" --password-stdin
+      if [[ -z "$DOCKERFILE_PATH" ]]; then
+          echo "Must provide DOCKERFILE_PATH as a job variable" 2>&1
+          exit 1
+      fi
+      if [[ -z "$IMAGE_NAME" ]]; then
+          echo "Must provide IMAGE_NAME as a job variable" 2>&1
+          exit 1
+      fi
+      if [[ -z "$DEV_IMAGE_NAME" ]]; then
+          echo "Must provide DEV_IMAGE_NAME as a job variable" 2>&1
+          exit 1
+      fi
+
+      # ===== 1. Setup image metadata labels =====
+      #Build date for opencontainers
+      #rfc 3339 date
+      BUILDDATE="'$(date '+%FT%T%z' | sed -E -n 's/(\+[0-9]{2})([0-9]{2})$/\1:\2/p')'"
+      IMAGE_LABELS="$IMAGE_LABELS --label org.opencontainers.image.created=$BUILDDATE"
+      IMAGE_LABELS="$IMAGE_LABELS --label build-date=$BUILDDATE"
+      # Description for opencontainers
+      BUILDTITLE="$(echo $CI_PROJECT_TITLE | tr " " "_")_$IMAGE_NAME"
+      IMAGE_LABELS="$IMAGE_LABELS --label org.opencontainers.image.title=$BUILDTITLE"
+      IMAGE_LABELS="$IMAGE_LABELS --label org.opencontainers.image.description=$BUILDTITLE"
+
+      # ==== 2. Tag, build and push non-dev image ====
+
+      # Cache from the CI dev image to build the non dev image.
+      CI_IMAGE_PATH=$CI_IMAGE_REPO/$DEV_IMAGE_NAME:$CLEANUP_JOB_CI_TAG_PREFIX$CI_COMMIT_SHORT_SHA
+
+      TRUNCATED_BRANCH_NAME=${CI_COMMIT_REF_NAME:0:100}
+      NON_DEV_CACHE_IMAGE=$CI_IMAGE_REPO/$IMAGE_NAME:$CLEANUP_JOB_CI_TAG_PREFIX$TRUNCATED_BRANCH_NAME
+
+      TARGET_NON_DEV_IMAGE_PATH=$CI_IMAGE_REPO/$IMAGE_NAME:$TESTED_IMAGE_PREFIX$CI_COMMIT_SHORT_SHA
+      TARGET_DEV_IMAGE_PATH=$CI_IMAGE_REPO/$DEV_IMAGE_NAME:$TESTED_IMAGE_PREFIX$CI_COMMIT_SHORT_SHA
+
+      docker pull $CI_IMAGE_PATH
+
+      if ! docker pull $NON_DEV_CACHE_IMAGE ; then
+        echo "Failed to find non dev cache image $NON_DEV_CACHE_IMAGE..."
+        EXTRA_BUILD_ARGS="";
+      else
+        echo "Caching from $NON_DEV_CACHE_IMAGE";
+        EXTRA_BUILD_ARGS="--cache-from $NON_DEV_CACHE_IMAGE";
+      fi
+      
+      if [[ -n "$BUILD_FROM_IMAGE" ]]; then
+        EXTRA_BUILD_ARGS="$EXTRA_BUILD_ARGS --build-arg FROM_IMAGE=$BUILD_FROM_IMAGE";
+        IMAGE_LABELS="$IMAGE_LABELS --label built-from-image=$BUILD_FROM_IMAGE"
+        if docker pull "$BUILD_FROM_IMAGE"; then
+          BUILT_FROM_REVISION=$(docker inspect $BUILD_FROM_IMAGE | jq -r '.[0].Config.Labels["org.opencontainers.image.revision"]')
+          BUILT_FROM_COMMITURL=$(docker inspect $BUILD_FROM_IMAGE | jq -r '.[0].Config.Labels["com.gitlab.ci.commiturl"]')
+          BUILT_FROM_CIJOBURL=$(docker inspect $BUILD_FROM_IMAGE | jq -r '.[0].Config.Labels["com.gitlab.ci.cijoburl"]')
+          BUILT_FROM_MRURL=$(docker inspect $BUILD_FROM_IMAGE | jq -r '.[0].Config.Labels["com.gitlab.ci.mrurl"]')
+          BUILT_FROM_VCSURL=$(docker inspect $BUILD_FROM_IMAGE | jq -r '.[0].Config.Labels["vcs-url"]')
+
+          IMAGE_LABELS="$IMAGE_LABELS --label built-from-revision=$BUILD_FROM_REVISION"
+          IMAGE_LABELS="$IMAGE_LABELS --label built-from-commiturl=$BUILD_FROM_COMMITURL"
+          IMAGE_LABELS="$IMAGE_LABELS --label built-from-cijoburl=$BUILD_FROM_CIJOBURL"
+          IMAGE_LABELS="$IMAGE_LABELS --label built-from-mrurl=$BUILD_FROM_MRURL"
+          IMAGE_LABELS="$IMAGE_LABELS --label built-from-vcsurl=$BUILD_FROM_VCSURL"
+        else
+          echo "Failed to pull build from image $BUILD_FROM_IMAGE, something has gone wrong"
+          exit 1
+        fi
+      fi
+
+      # Build the normal non-dev image with all the tags and labels.
+      docker build \
+        --cache-from $CI_IMAGE_PATH \
+        $EXTRA_BUILD_ARGS \
+        $FORMATTEDTAGLIST \
+        $IMAGE_LABELS \
+        -t $TARGET_NON_DEV_IMAGE_PATH \
+        -f $DOCKERFILE_PATH .;
+      docker push $TARGET_NON_DEV_IMAGE_PATH
+
+      # Build the cache image with layer caching enabled. We don't enable it for the image above to reduce its size.
+      docker build \
+        --cache-from $CI_IMAGE_PATH \
+        $EXTRA_BUILD_ARGS \
+        $IMAGE_LABELS \
+        --build-arg BUILDKIT_INLINE_CACHE=1 \
+        -t $NON_DEV_CACHE_IMAGE \
+        -f $DOCKERFILE_PATH .;
+      docker push $NON_DEV_CACHE_IMAGE
+
+      docker tag $CI_IMAGE_PATH $TARGET_DEV_IMAGE_PATH
+      docker push $TARGET_DEV_IMAGE_PATH
+
+# A simple docker based test job which does not run for a TAG pipeline and does not
+# check out git.
+.docker-image-test-stage:
+  stage: test
+  image: $CI_UTIL_IMAGE
+  interruptible: true
+  # Prevent rebuilds when tagging as all we want to do is tag and push
+  except:
+    refs:
+      - pipelines
+    variables:
+      - $CI_COMMIT_TAG
+  services:
+    - docker:20.10.12-dind
+
+
+# Pushes $SOURCE_IMAGE to $TARGET_IMAGE using the $TARGET_REGISTRY_PASSWORD,
+# $TARGET_REGISTRY_USER and $TARGET_REGISTRY credentials.
+#
+# Set $SKIP_IF_TAG_NOT_ON_BRANCH to make the job skip if the commit is not on
+# the specified branch. Useful for TAG pipelines when $CI_COMMIT_BRANCH is not set
+# and so we need to do some extra git work to figure out what branches this commit is
+# on.
+#
+# Set $SKIP_IF_NOT_LATEST_COMMIT_ON_BRANCH to a branch name. If the job is not
+# for a commit which is the latest on the specified branch name (for example due to
+# someone re-running a pipeline for an old commit) this job will be skipped.
+.publish-baserow-image:
+  image: $CI_UTIL_IMAGE
+  stage: publish
+  services:
+    - docker:20.10.12-dind
+  except:
+    refs:
+      - pipelines
+  variables:
+    DOCKER_HOST: tcp://docker:2376
+    DOCKER_TLS_CERTDIR: "/certs"
+  allow_failure:
+    # By exiting with this code we can skip this step without failing the build,
+    # but still fail if something else goes wrong.
+    exit_codes: 137
+  script:
+    - |
+      if [[ -n "$SKIP_IF_TAG_NOT_ON_BRANCH" ]]; then
+        # Query for all the branches that this commit is part of.
+        curl -s --header "JOB-TOKEN: $CI_JOB_TOKEN" \
+          "https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/repository/commits/$CI_COMMIT_SHA/refs?type=branch" \
+          -o this_commits_branches.json;
+        # Extract just the branch names from the json so we can assert it matches.
+        TAG_BRANCH_NAMES=$(cat this_commits_branches.json | jq -r ".[].name")
+        NUM_BRANCHES=$(cat this_commits_branches.json | jq length)
+        # Ensure the commit is only on master and no other branches, otherwise someone
+        # could checkout a master commit as a new branch and tag it to cause an image
+        # upload.
+        if [[ "$NUM_BRANCHES" != "1" || "$TAG_BRANCH_NAMES" != "$SKIP_IF_TAG_NOT_ON_BRANCH" ]]; then
+          echo "Tags should never be applied to non $SKIP_IF_TAG_NOT_ON_BRANCH branches!" 2>&1;
+          echo "Pipeline is running for tag: $CI_COMMIT_TAG which for a commit that only appears on $SKIP_IF_TAG_NOT_ON_BRANCH and no other branches." 2>&1;
+          echo "Instead this commit appears on $NUM_BRANCHES branches called $TAG_BRANCH_NAMES" 2>&1;
+          exit 1;
+        fi
+      fi
+
+      if [[ -n "$SKIP_IF_NOT_LATEST_COMMIT_ON_BRANCH" ]]; then
+        LATEST_COMMIT_HASH=$(git rev-parse origin/$SKIP_IF_NOT_LATEST_COMMIT_ON_BRANCH)
+        HEAD_COMMIT_HASH=$CI_COMMIT_SHA
+        if [[ "$LATEST_COMMIT_HASH" != "$HEAD_COMMIT_HASH" ]]; then
+            echo "Pipeline is not running for latest commit on origin/$SKIP_IF_NOT_LATEST_COMMIT_ON_BRANCH";
+            echo " which has commit $LATEST_COMMIT_HASH.";
+            echo "Instead pipeline is running on commit $HEAD_COMMIT_HASH, exitting as configured to do so in this situation...";
+            exit 137;
+        fi
+      fi
+
+      echo "$TARGET_REGISTRY_PASSWORD" | docker login -u "$TARGET_REGISTRY_USER" "$TARGET_REGISTRY" --password-stdin
+
+      if ! docker pull $SOURCE_IMAGE; then
+        echo "Could not pull $SOURCE_IMAGE, has the build pipeline finished yet?" 2>&1;
+        exit 1
+      fi
+      docker tag $SOURCE_IMAGE $TARGET_IMAGE
+      docker push $TARGET_IMAGE
+
+.skippable-job:
+  before_script:
+    - |
+      if [[ -z "$SKIP_JOB_NAME" ]]; then
+          echo "Must provide SKIP_JOB_NAME as a job variable" 2>&1
+          exit 1
+      fi
+
+      if [[ "$ENABLE_JOB_SKIPPING" = "true" ]]; then
+
+        try_download_latest_successful_artifacts_for_commit(){
+          COMMIT_HASH=$1
+          JOB_NAME=$2
+          echo -e "\e[0Ksection_start:`date +%s`:$COMMIT_HASH$JOB_NAME[collapsed=true]\r\e[0KPrevious successful run check for $JOB_NAME and $COMMIT_HASH"
+          URL="https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/repository/commits/$COMMIT_HASH/statuses?name=$JOB_NAME"
+          COMMIT_GITLAB_JOBS=$(curl --header "PRIVATE-TOKEN: $PROJECT_READ_ONLY_API_TOKEN" $URL)
+
+          if [[ "$COMMIT_GITLAB_JOBS" ]]; then
+            echo "Got these job statuses: $COMMIT_GITLAB_JOBS"
+            JOB_ID=$(echo $COMMIT_GITLAB_JOBS| jq "[.[] | select(.status == \"success\")][0].id")
+            # Check if JOB_ID is an integer (POSIX compliant way)
+
+            if [ "$JOB_ID" -eq "$JOB_ID" ] 2> /dev/null;  then
+              if [[ -n "$DOWNLOAD_AND_UNPACK_ARTIFACTS_ON_SKIP" ]] ; then
+                exit_code=0
+                curl --fail --location --output artifacts.zip \
+                  --header "PRIVATE-TOKEN: $PROJECT_READ_ONLY_API_TOKEN" \
+                  "https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/jobs/$JOB_ID/artifacts" \
+                  || exit_code=$?;
+
+                if [ ${exit_code} -ne 0 ]; then
+                  echo "Failed to get artifacts from successful run $JOB_ID"
+                else
+                  unzip artifacts.zip || exit_code=$?
+                  if [ ${exit_code} -ne 0 ]; then
+                    echo "Failed to unzip artifacts"
+                  else
+                    if [[ -f "reports/stdout.txt" ]]; then
+                        cat reports/stdout.txt;
+                    fi
+                    echo "Skipping $JOB_NAME as previous successful run for $COMMIT_HASH and it's artifacts were found."
+                    exit 0;
+                  fi
+                fi
+
+              else
+                echo "Skipping $JOB_NAME as previous successful build for $COMMIT_HASH were found.".
+                exit 0;
+              fi
+            else
+              echo "Failed to find successful run of $JOB_NAME in $COMMIT_GITLAB_JOBS"
+            fi
+          else
+            echo "Failed to query gitlab for jobs";
+          fi
+          echo -e "\e[0Ksection_end:`date +%s`:$COMMIT_HASH$JOB_NAME\r\e[0K"
+        }
+
+        SECOND_PARENT_COMMIT=$(git rev-list -1 --merges ${CI_COMMIT_SHA}~1..${CI_COMMIT_SHA})
+        if [[ -z "$SECOND_PARENT_COMMIT" ]] ; then
+          # If there is no second parent commit then there is only one parent commit
+          # and so we can safely look for its artifacts.
+          PREVIOUS_COMMIT_SHA=$(git rev-parse HEAD~1)
+          # Search for successful runs of either the normal job or this job itself
+          # for either this or previous commit.
+          try_download_latest_successful_artifacts_for_commit $CI_COMMIT_SHA $SKIP_JOB_NAME
+          try_download_latest_successful_artifacts_for_commit $CI_COMMIT_SHA $CI_JOB_NAME
+          try_download_latest_successful_artifacts_for_commit $PREVIOUS_COMMIT_SHA $SKIP_JOB_NAME
+          try_download_latest_successful_artifacts_for_commit $PREVIOUS_COMMIT_SHA $CI_JOB_NAME
+          echo "Actually running job as successful run for previous or this commit not found"
+        else
+          # There is a second (or more) parent commit meaning we should re-run this job
+          # as a merge has happened.
+          echo "Running full job as this is a merge commit."
+        fi
+      else
+          echo "Force running job regardless of previous runs."
+      fi
diff --git a/.gitlab/ci_util_image/Dockerfile b/.gitlab/ci_util_image/Dockerfile
new file mode 100644
index 000000000..fda7eea7b
--- /dev/null
+++ b/.gitlab/ci_util_image/Dockerfile
@@ -0,0 +1,9 @@
+# A small helper image which has some useful tools pre-installed that are used by ci
+# stages. By building our own little image it means every single ci job doesn't need
+# to repeatedly re-install these tools when they run.
+FROM docker:20.10.12
+ENV PYTHONUNBUFFERED=1
+RUN apk add --update --no-cache curl git jq python3 openssh-client && ln -sf python3 /usr/bin/python
+RUN python3 -m ensurepip
+RUN pip3 install --no-cache --upgrade pip setuptools
+RUN mkdir /baserow && python3 -m venv /baserow/venv && . /baserow/venv/bin/activate && pip3 install coverage
diff --git a/backend/.coveragerc b/backend/.coveragerc
new file mode 100644
index 000000000..f552fd64f
--- /dev/null
+++ b/backend/.coveragerc
@@ -0,0 +1,12 @@
+[run]
+# Also required for gitlab MR coverage to be shown correctly.
+relative_files = True
+omit =
+    */generated/*
+# We can't set source as it changes the xml reports file paths to be relative from
+# say `backend/src` instead of the root of the repo. Gitlab needs paths to be relative
+# from the root so instead we just set include which ensures in gitlab MR coverage is
+# shown correctly.
+include =
+    backend/src/**/*
+    premium/backend/src/**/*
diff --git a/backend/.test_durations b/backend/.test_durations
new file mode 100644
index 000000000..d89937c31
--- /dev/null
+++ b/backend/.test_durations
@@ -0,0 +1,1140 @@
+{
+    "baserow_premium/admin/dashboard/test_admin_dashboard_handler.py::test_get_active_user_counts": 0.1822943090046465,
+    "baserow_premium/admin/dashboard/test_admin_dashboard_handler.py::test_get_active_users_per_day": 0.16566099500050768,
+    "baserow_premium/admin/dashboard/test_admin_dashboard_handler.py::test_get_new_user_counts": 0.8151876599986281,
+    "baserow_premium/admin/dashboard/test_admin_dashboard_handler.py::test_get_new_users_per_day": 0.4079730240009667,
+    "baserow_premium/admin/groups/test_groups_admin_handler.py::test_cant_delete_template_group": 0.07579601500037825,
+    "baserow_premium/admin/groups/test_groups_admin_handler.py::test_delete_group": 0.21693506900192006,
+    "baserow_premium/admin/groups/test_groups_admin_handler.py::test_delete_group_without_premium_license": 0.11121500800072681,
+    "baserow_premium/admin/users/test_user_admin_handler.py::test_admin_can_deactive_and_unstaff_other_users": 0.1647288540007139,
+    "baserow_premium/admin/users/test_user_admin_handler.py::test_admin_can_delete_user": 0.11796121900260914,
+    "baserow_premium/admin/users/test_user_admin_handler.py::test_admin_can_modify_allowed_user_attributes": 0.16221829300411628,
+    "baserow_premium/admin/users/test_user_admin_handler.py::test_admin_cant_deactivate_themselves": 0.0576791929997853,
+    "baserow_premium/admin/users/test_user_admin_handler.py::test_admin_cant_delete_themselves": 0.06128557300326065,
+    "baserow_premium/admin/users/test_user_admin_handler.py::test_admin_cant_destaff_themselves": 0.057741159998840885,
+    "baserow_premium/admin/users/test_user_admin_handler.py::test_admin_delete_user_without_premium_license": 0.0577257209988602,
+    "baserow_premium/admin/users/test_user_admin_handler.py::test_admin_update_user_without_premium_license": 0.05568703899189131,
+    "baserow_premium/admin/users/test_user_admin_handler.py::test_non_admin_cant_delete_user": 0.06248184100331855,
+    "baserow_premium/admin/users/test_user_admin_handler.py::test_non_admin_cant_edit_user": 0.06459872799678124,
+    "baserow_premium/admin/users/test_user_admin_handler.py::test_raises_exception_when_deleting_an_unknown_user": 0.06124864099911065,
+    "baserow_premium/admin/users/test_user_admin_handler.py::test_raises_exception_when_updating_an_unknown_user": 0.06304805400213809,
+    "baserow_premium/admin/users/test_user_admin_handler.py::test_updating_a_users_password_uses_djangos_built_in_smart_set_password": 0.1574360250015161,
+    "baserow_premium/admin/users/test_user_admin_handler.py::test_updating_a_users_password_with_invalid_password_raises_error[984kds]": 0.1590474550066574,
+    "baserow_premium/admin/users/test_user_admin_handler.py::test_updating_a_users_password_with_invalid_password_raises_error[Bgvmt95en6HGJZ9Xz0F8xysQ6eYgo2Y54YzRPxxv10b5n16F4rZ6YH4ulonocwiFK6970KiAxoYhULYA3JFDPIQGj5gMZZl25M46sO810Zd3nyBg699a2TDMJdHG7hAAi0YeDnuHuabyBawnb4962OQ1OOf1MxzFyNWG7NR2X6MZQL5G1V61x56lQTXbvK1AG1IPM87bQ3YAtIBtGT2vK3Wd83q3he5ezMtUfzK2ibj0WWhf86DyQB4EHRUJjYcBiI78iEJv5hcu33X2I345YosO66cTBWK45SqJEDudrCOq]": 0.15665854400140233,
+    "baserow_premium/admin/users/test_user_admin_handler.py::test_updating_a_users_password_with_invalid_password_raises_error[]": 0.16137919500033604,
+    "baserow_premium/admin/users/test_user_admin_handler.py::test_updating_a_users_password_with_invalid_password_raises_error[a]": 0.16080309500466683,
+    "baserow_premium/admin/users/test_user_admin_handler.py::test_updating_a_users_password_with_invalid_password_raises_error[ab]": 0.1593808799989347,
+    "baserow_premium/admin/users/test_user_admin_handler.py::test_updating_a_users_password_with_invalid_password_raises_error[ask]": 0.15975657799936016,
+    "baserow_premium/admin/users/test_user_admin_handler.py::test_updating_a_users_password_with_invalid_password_raises_error[dsfkjh4]": 0.16153580999889527,
+    "baserow_premium/admin/users/test_user_admin_handler.py::test_updating_a_users_password_with_invalid_password_raises_error[dsj43]": 0.15873133999775746,
+    "baserow_premium/admin/users/test_user_admin_handler.py::test_updating_a_users_password_with_invalid_password_raises_error[oiue]": 0.16811270299876924,
+    "baserow_premium/api/admin/dashboard/test_admin_dashboard_views.py::test_admin_dashboard": 0.14857133199984673,
+    "baserow_premium/api/admin/groups/test_groups_admin_views.py::test_cant_delete_template_group": 0.0693339899989951,
+    "baserow_premium/api/admin/groups/test_groups_admin_views.py::test_delete_group": 0.13029559099959442,
+    "baserow_premium/api/admin/groups/test_groups_admin_views.py::test_list_admin_groups": 0.1384509010022157,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_admin_accessing_invalid_user_admin_page_returns_error": 0.06374025500190328,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_admin_accessing_user_admin_with_invalid_page_size_returns_error": 0.06178190499849734,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_admin_can_delete_user": 0.12688089400035096,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_admin_can_patch_user": 0.12753979300396168,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_admin_can_patch_user_without_providing_password": 0.07300627000222448,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_admin_can_search_users": 0.1170142089977162,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_admin_can_see_admin_users_endpoint": 0.06700950199956424,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_admin_can_sort_users": 0.11766191599963349,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_admin_cannot_delete_user_without_premium_license": 0.11292251899794792,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_admin_getting_view_users_only_runs_two_queries_instead_of_n": 1.135972041000059,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_admin_list_users_without_premium_license": 0.05721638199975132,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_admin_with_invalid_token_cannot_see_admin_users": 0.05717548800021177,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_error_returned_when_invalid_field_supplied_to_edit": 0.05928290700467187,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_error_returned_when_updating_user_with_invalid_email": 0.06189783299851115,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_error_returned_when_valid_and_invalid_fields_supplied_to_edit": 0.06387469899345888,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_invalid_password_returns_400[984kds]": 0.1151537420009845,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_invalid_password_returns_400[a]": 0.11094330899504712,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_invalid_password_returns_400[ab]": 0.11288261199661065,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_invalid_password_returns_400[ask]": 0.11714549599855673,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_invalid_password_returns_400[dsfkjh4]": 0.11293282800033921,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_invalid_password_returns_400[dsj43]": 0.11079325600076118,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_invalid_password_returns_400[oiue]": 0.11494598199715256,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_non_admin_cannot_delete_user": 0.110916064997582,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_non_admin_cannot_patch_user": 0.06779227199876914,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_non_admin_cannot_patch_user_without_premium_license": 0.060885039001732366,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_non_admin_cannot_see_admin_users_endpoint": 0.06364982399827568,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_returns_error_response_if_blank_sorts_provided": 0.058435456001461716,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_returns_error_response_if_invalid_sort_direction_provided": 0.05867311000110931,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_returns_error_response_if_invalid_sort_field_provided": 0.06850142500115908,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_returns_error_response_if_invalid_sorts_mixed_with_valid_ones": 0.05885015500098234,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_returns_error_response_if_no_sorts_provided": 0.05864809400009108,
+    "baserow_premium/api/admin/users/test_users_admin_views.py::test_returns_error_response_if_sort_direction_not_provided": 0.06823474200064084,
+    "baserow_premium/api/export/test_premium_export_views.py::test_exporting_json_writes_file_to_storage": 0.17049703399970895,
+    "baserow_premium/api/export/test_premium_export_views.py::test_exporting_xml_writes_file_to_storage": 0.16273675900083617,
+    "baserow_premium/api/license/test_premium_license_views.py::test_admin_add_user_to_license": 0.11681095599851687,
+    "baserow_premium/api/license/test_premium_license_views.py::test_admin_check_license": 0.13599404199703713,
+    "baserow_premium/api/license/test_premium_license_views.py::test_admin_delete_license": 0.11428986699684174,
+    "baserow_premium/api/license/test_premium_license_views.py::test_admin_delete_user_from_license": 0.12179404199923738,
+    "baserow_premium/api/license/test_premium_license_views.py::test_admin_fill_users_in_license": 0.11625386999730836,
+    "baserow_premium/api/license/test_premium_license_views.py::test_admin_get_license": 0.13057594899873948,
+    "baserow_premium/api/license/test_premium_license_views.py::test_admin_license_user_lookup": 0.1775878129992634,
+    "baserow_premium/api/license/test_premium_license_views.py::test_admin_list_licenses": 0.35079707600016263,
+    "baserow_premium/api/license/test_premium_license_views.py::test_admin_register_license": 0.15721870699780993,
+    "baserow_premium/api/license/test_premium_license_views.py::test_admin_remove_all_users": 0.11555949400280952,
+    "baserow_premium/api/row_comments/test_row_comments_views.py::test_cant_make_a_blank_row_comment": 0.09096986599615775,
+    "baserow_premium/api/row_comments/test_row_comments_views.py::test_cant_make_a_null_row_comment": 0.08153097399917897,
+    "baserow_premium/api/row_comments/test_row_comments_views.py::test_cant_make_a_row_comment_greater_than_max_settings": 0.09377145000325982,
+    "baserow_premium/api/row_comments/test_row_comments_views.py::test_cant_make_a_row_without_premium_license": 0.07498848799878033,
+    "baserow_premium/api/row_comments/test_row_comments_views.py::test_getting_row_comments_executes_fixed_number_of_queries": 0.1664281069970457,
+    "baserow_premium/api/row_comments/test_row_comments_views.py::test_perm_deleting_a_trashed_row_with_comments_cleans_up_the_rows": 0.14113137800450204,
+    "baserow_premium/api/row_comments/test_row_comments_views.py::test_perm_deleting_a_trashed_table_with_comments_cleans_up_the_rows": 0.1899557190008636,
+    "baserow_premium/api/row_comments/test_row_comments_views.py::test_row_comments_api_view": 0.15420178699787357,
+    "baserow_premium/api/row_comments/test_row_comments_views.py::test_row_comments_api_view_without_premium_license": 0.07917400300357258,
+    "baserow_premium/api/row_comments/test_row_comments_views.py::test_row_comments_cant_create_comments_in_invalid_row_in_table": 0.08498848399540293,
+    "baserow_premium/api/row_comments/test_row_comments_views.py::test_row_comments_cant_create_comments_in_invalid_table": 0.06335438000314753,
+    "baserow_premium/api/row_comments/test_row_comments_views.py::test_row_comments_cant_view_comments_for_invalid_row_in_table": 0.07971987300334149,
+    "baserow_premium/api/row_comments/test_row_comments_views.py::test_row_comments_cant_view_comments_for_invalid_table": 0.06053732400323497,
+    "baserow_premium/api/row_comments/test_row_comments_views.py::test_row_comments_users_cant_create_comments_for_table_they_are_not_in_group_for": 0.14230158600548748,
+    "baserow_premium/api/row_comments/test_row_comments_views.py::test_row_comments_users_cant_view_comments_for_table_they_are_not_in_group_for": 0.13711942700319923,
+    "baserow_premium/api/row_comments/test_row_comments_views.py::test_trashing_the_row_returns_404_for_comments": 0.1395496759978414,
+    "baserow_premium/api/views/views/test_kanban_views.py::test_create_kanban_view": 0.13086866899902816,
+    "baserow_premium/api/views/views/test_kanban_views.py::test_create_kanban_view_invalid_card_cover_image_field": 0.2708426210010657,
+    "baserow_premium/api/views/views/test_kanban_views.py::test_list_all_invalid_select_option_parameter": 0.08849603699854924,
+    "baserow_premium/api/views/views/test_kanban_views.py::test_list_all_rows": 0.1030027640008484,
+    "baserow_premium/api/views/views/test_kanban_views.py::test_list_all_rows_with_limit_and_offset": 0.14826155999980983,
+    "baserow_premium/api/views/views/test_kanban_views.py::test_list_rows_include_field_options": 0.10348627199709881,
+    "baserow_premium/api/views/views/test_kanban_views.py::test_list_rows_invalid_parameters": 0.11130999800298014,
+    "baserow_premium/api/views/views/test_kanban_views.py::test_list_with_specific_select_options": 0.11143074400024489,
+    "baserow_premium/api/views/views/test_kanban_views.py::test_list_without_valid_premium_license": 0.09280392400251003,
+    "baserow_premium/api/views/views/test_kanban_views.py::test_patch_kanban_view_field_options": 0.08793423000679468,
+    "baserow_premium/api/views/views/test_kanban_views.py::test_update_kanban_view": 0.11505826400389196,
+    "baserow_premium/api/views/views/test_kanban_views.py::test_update_kanban_view_card_cover_image_field": 0.09101296600420028,
+    "baserow_premium/export/test_premium_export_types.py::test_can_export_every_interesting_different_field_to_json": 2.2952473090044805,
+    "baserow_premium/export/test_premium_export_types.py::test_can_export_every_interesting_different_field_to_xml": 2.2912878140014072,
+    "baserow_premium/export/test_premium_export_types.py::test_cannot_export_json_without_premium_license": 2.378322243996081,
+    "baserow_premium/export/test_premium_export_types.py::test_cannot_export_xml_without_premium_license": 2.2118516850023298,
+    "baserow_premium/export/test_premium_export_types.py::test_if_duplicate_field_names_json_export": 0.14931628300109878,
+    "baserow_premium/export/test_premium_export_types.py::test_if_xml_duplicate_name_and_value_are_escaped": 0.1222804070021084,
+    "baserow_premium/export/test_premium_export_utils.py::test_get_unique_name": 0.0008035999962885398,
+    "baserow_premium/export/test_premium_export_utils.py::test_safe_xml_tag_name": 0.0008034000020415988,
+    "baserow_premium/export/test_premium_export_utils.py::test_to_xml": 0.0007807870024407748,
+    "baserow_premium/license/test_license_handler.py::test_add_user_to_license": 0.6863466670001799,
+    "baserow_premium/license/test_license_handler.py::test_check_licenses_with_authority_check": 0.031040695001138374,
+    "baserow_premium/license/test_license_handler.py::test_check_licenses_without_authority_check": 0.23054841499833856,
+    "baserow_premium/license/test_license_handler.py::test_decode_license_with_valid_license": 0.0014293559979705606,
+    "baserow_premium/license/test_license_handler.py::test_fetch_license_status_in_production_mode": 0.007037198003672529,
+    "baserow_premium/license/test_license_handler.py::test_fetch_license_status_with_authority": 0.006806551002227934,
+    "baserow_premium/license/test_license_handler.py::test_fetch_license_status_with_authority_invalid_response": 0.01111569200293161,
+    "baserow_premium/license/test_license_handler.py::test_fetch_license_status_with_authority_unavailable": 0.013204257997131208,
+    "baserow_premium/license/test_license_handler.py::test_fill_remaining_seats_in_license": 0.713903380001284,
+    "baserow_premium/license/test_license_handler.py::test_get_public_key_debug": 0.0011557020006875973,
+    "baserow_premium/license/test_license_handler.py::test_get_public_key_production": 0.0010503039993636776,
+    "baserow_premium/license/test_license_handler.py::test_has_active_premium_license": 0.27259950500229024,
+    "baserow_premium/license/test_license_handler.py::test_invalid_signature_decode_license": 0.0015919720026431605,
+    "baserow_premium/license/test_license_handler.py::test_register_an_older_license": 0.07743426599699887,
+    "baserow_premium/license/test_license_handler.py::test_register_license": 0.16693839599611238,
+    "baserow_premium/license/test_license_handler.py::test_register_license_with_authority_check_does_not_exist": 0.0702758690022165,
+    "baserow_premium/license/test_license_handler.py::test_register_license_with_authority_check_instance_id_mismatch": 0.07028844399974332,
+    "baserow_premium/license/test_license_handler.py::test_register_license_with_authority_check_invalid": 0.07279425200249534,
+    "baserow_premium/license/test_license_handler.py::test_register_license_with_authority_check_ok": 0.08199809299549088,
+    "baserow_premium/license/test_license_handler.py::test_register_license_with_authority_check_updated": 0.07766329500373104,
+    "baserow_premium/license/test_license_handler.py::test_remove_all_users_from_license": 0.7410918209970987,
+    "baserow_premium/license/test_license_handler.py::test_remove_license": 0.17189667399725295,
+    "baserow_premium/license/test_license_handler.py::test_remove_user_from_license": 0.6866209510044428,
+    "baserow_premium/license/test_license_handler.py::test_unsupported_version_decode_license": 0.7651296020012524,
+    "baserow_premium/license/test_license_handler.py::test_upgrade_license_by_register": 0.0733719480012951,
+    "baserow_premium/license/test_license_models.py::test_premium_license_model_is_active": 0.06169771500208299,
+    "baserow_premium/license/test_license_models.py::test_premium_license_model_properties": 0.007191326996689895,
+    "baserow_premium/license/test_license_models.py::test_premium_license_model_save": 0.006248095000046305,
+    "baserow_premium/license/test_license_tasks.py::test_license_check": 0.005903237004531547,
+    "baserow_premium/premium/test_premium_installed.py::test_premium_app_installed": 0.004354035001597367,
+    "baserow_premium/row_comments/test_row_comments_handler.py::test_cant_create_comment_without_premium_license": 0.07543832300143549,
+    "baserow_premium/row_comments/test_row_comments_handler.py::test_cant_make_blank_comment_using_handler": 0.08603012200183002,
+    "baserow_premium/row_comments/test_row_comments_handler.py::test_cant_make_null_comment_using_handler": 0.0857561539960443,
+    "baserow_premium/row_comments/test_row_comments_handler.py::test_row_comment_created_signal_called": 0.6049891099974047,
+    "baserow_premium/views/test_premium_view_handler.py::test_get_rows_grouped_by_single_select_field": 0.06970030700176721,
+    "baserow_premium/views/test_premium_view_handler.py::test_get_rows_grouped_by_single_select_field_not_existing_options_are_null": 0.03846194300058414,
+    "baserow_premium/views/test_premium_view_handler.py::test_get_rows_grouped_by_single_select_field_with_empty_table": 0.023536557997431373,
+    "baserow_premium/views/test_premium_view_types.py::test_convert_card_cover_image_field_deleted": 0.09759637999377446,
+    "baserow_premium/views/test_premium_view_types.py::test_convert_card_cover_image_field_to_another": 0.10965998399842647,
+    "baserow_premium/views/test_premium_view_types.py::test_field_of_same_table_is_provided": 0.1111354280001251,
+    "baserow_premium/views/test_premium_view_types.py::test_import_export_kanban_view": 0.09074440199765377,
+    "baserow_premium/views/test_premium_view_types.py::test_newly_created_view": 0.09444661100496887,
+    "baserow_premium/ws/test_ws_row_comments_signals.py::test_row_comment_created": 0.6207814519984822,
+    "tests/baserow/api/applications/test_application_views.py::test_create_application": 0.08253989600416389,
+    "tests/baserow/api/applications/test_application_views.py::test_delete_application": 0.1228395360049035,
+    "tests/baserow/api/applications/test_application_views.py::test_get_application": 0.12910750700029894,
+    "tests/baserow/api/applications/test_application_views.py::test_list_applications": 0.10352716600027634,
+    "tests/baserow/api/applications/test_application_views.py::test_order_tables": 0.07749547599814832,
+    "tests/baserow/api/applications/test_application_views.py::test_update_application": 0.13171893800245016,
+    "tests/baserow/api/groups/test_group_invitation_views.py::test_accept_group_invitation": 0.1191657720009971,
+    "tests/baserow/api/groups/test_group_invitation_views.py::test_create_group_invitation": 0.26868016999651445,
+    "tests/baserow/api/groups/test_group_invitation_views.py::test_delete_group_invitation": 0.18169929400028195,
+    "tests/baserow/api/groups/test_group_invitation_views.py::test_get_group_invitation": 0.17149721499663428,
+    "tests/baserow/api/groups/test_group_invitation_views.py::test_get_group_invitation_by_token": 0.16495009099890012,
+    "tests/baserow/api/groups/test_group_invitation_views.py::test_list_group_invitations": 0.13785813600043184,
+    "tests/baserow/api/groups/test_group_invitation_views.py::test_reject_group_invitation": 0.12208356699920841,
+    "tests/baserow/api/groups/test_group_invitation_views.py::test_update_group_invitation": 0.17463189900081488,
+    "tests/baserow/api/groups/test_group_invitation_views.py::test_when_group_is_trashed_so_is_invitation": 0.08184512000298128,
+    "tests/baserow/api/groups/test_group_user_views.py::test_delete_group_user": 0.17158070399455028,
+    "tests/baserow/api/groups/test_group_user_views.py::test_if_group_trashed_then_group_user_is_trashed": 0.06964253499972983,
+    "tests/baserow/api/groups/test_group_user_views.py::test_list_group_users": 0.18270031200154335,
+    "tests/baserow/api/groups/test_group_user_views.py::test_update_group_user": 0.18032029099776992,
+    "tests/baserow/api/groups/test_group_views.py::test_create_group": 0.06588677600302617,
+    "tests/baserow/api/groups/test_group_views.py::test_delete_group": 0.12677222000274924,
+    "tests/baserow/api/groups/test_group_views.py::test_leave_group": 0.12791166999886627,
+    "tests/baserow/api/groups/test_group_views.py::test_list_groups": 0.06758564799383748,
+    "tests/baserow/api/groups/test_group_views.py::test_reorder_groups": 0.07037355799911893,
+    "tests/baserow/api/groups/test_group_views.py::test_trashed_group_not_returned_by_views": 0.06636974199864198,
+    "tests/baserow/api/groups/test_group_views.py::test_update_group": 0.12704573399969377,
+    "tests/baserow/api/settings/test_settings_views.py::test_get_instance_id": 0.11899857599564712,
+    "tests/baserow/api/settings/test_settings_views.py::test_get_settings": 0.009036937004566425,
+    "tests/baserow/api/settings/test_settings_views.py::test_update_settings": 0.12602239999978337,
+    "tests/baserow/api/templates/test_templates_views.py::test_install_template": 0.462049827001465,
+    "tests/baserow/api/templates/test_templates_views.py::test_list_templates": 0.014340325000375742,
+    "tests/baserow/api/test_api_authentication.py::test_authenticate": 0.23731841900007566,
+    "tests/baserow/api/test_api_decorators.py::test_accept_timezone": 0.001084759998775553,
+    "tests/baserow/api/test_api_decorators.py::test_allowed_includes": 0.0009654050008975901,
+    "tests/baserow/api/test_api_decorators.py::test_map_exceptions": 0.0012284290023671929,
+    "tests/baserow/api/test_api_decorators.py::test_validate_body": 0.0020403839989739936,
+    "tests/baserow/api/test_api_decorators.py::test_validate_body_and_query_parameters": 0.0022062870048102923,
+    "tests/baserow/api/test_api_decorators.py::test_validate_body_custom_fields": 0.002890814001148101,
+    "tests/baserow/api/test_api_decorators.py::test_validate_query_parameter": 0.0027183580023120157,
+    "tests/baserow/api/test_api_utils.py::test_get_serializer_class": 0.005554090996156447,
+    "tests/baserow/api/test_api_utils.py::test_map_exceptions": 0.000925599000765942,
+    "tests/baserow/api/test_api_utils.py::test_validate_data": 0.002161112002795562,
+    "tests/baserow/api/test_api_utils.py::test_validate_data_custom_fields": 0.001348544996290002,
+    "tests/baserow/api/test_redoc.py::test_can_generate_open_api_schema": 0.19589749099759501,
+    "tests/baserow/api/trash/test_trash_views.py::test_can_get_trash_contents_for_undeleted_app": 0.06667796199690201,
+    "tests/baserow/api/trash/test_trash_views.py::test_can_get_trash_contents_for_undeleted_group": 0.061934466000820976,
+    "tests/baserow/api/trash/test_trash_views.py::test_can_get_trash_structure": 0.10369971000545775,
+    "tests/baserow/api/trash/test_trash_views.py::test_can_restore_a_deleted_trash_item": 0.08941777600193745,
+    "tests/baserow/api/trash/test_trash_views.py::test_cant_delete_same_item_twice": 0.30694540300100925,
+    "tests/baserow/api/trash/test_trash_views.py::test_cant_restore_a_deleted_trash_item_if_not_in_group": 0.13111413899969193,
+    "tests/baserow/api/trash/test_trash_views.py::test_cant_restore_a_non_existent_trashed_item": 0.0591339109960245,
+    "tests/baserow/api/trash/test_trash_views.py::test_cant_restore_a_trash_item_marked_for_perm_deletion": 0.09776903300007689,
+    "tests/baserow/api/trash/test_trash_views.py::test_cant_restore_a_trashed_item_requiring_a_parent_id_without_providing_it": 0.09919143799561425,
+    "tests/baserow/api/trash/test_trash_views.py::test_cant_restore_a_trashed_item_with_a_missing_parent": 0.1017198509980517,
+    "tests/baserow/api/trash/test_trash_views.py::test_deleting_a_group_moves_it_to_the_trash_and_hides_it": 0.09199045100103831,
+    "tests/baserow/api/trash/test_trash_views.py::test_deleting_a_user_who_trashed_something_returns_null_user_who_trashed": 0.1454551460010407,
+    "tests/baserow/api/trash/test_trash_views.py::test_emptying_a_app_for_diff_group_returns_400": 0.06902873000217369,
+    "tests/baserow/api/trash/test_trash_views.py::test_emptying_a_non_existent_app_returns_404": 0.06312174699996831,
+    "tests/baserow/api/trash/test_trash_views.py::test_emptying_a_non_existent_group_returns_404": 0.06278058699899702,
+    "tests/baserow/api/trash/test_trash_views.py::test_emptying_a_trashed_app_marks_it_for_perm_deletion": 0.09275943600005121,
+    "tests/baserow/api/trash/test_trash_views.py::test_emptying_a_trashed_group_marks_it_for_perm_deletion": 0.0868952629971318,
+    "tests/baserow/api/trash/test_trash_views.py::test_getting_a_app_for_diff_group_returns_400": 0.06429758699960075,
+    "tests/baserow/api/trash/test_trash_views.py::test_getting_a_non_existent_app_returns_404": 0.06200900799740339,
+    "tests/baserow/api/trash/test_trash_views.py::test_getting_a_non_existent_group_returns_404": 0.05879779100359883,
+    "tests/baserow/api/trash/test_trash_views.py::test_restoring_an_item_which_doesnt_need_parent_id_with_one_returns_error": 0.07930594899880816,
+    "tests/baserow/api/trash/test_trash_views.py::test_user_cant_empty_trash_contents_for_group_they_are_not_a_member_of": 0.1365212029995746,
+    "tests/baserow/api/trash/test_trash_views.py::test_user_cant_get_trash_contents_for_group_they_are_not_a_member_of": 0.13619533100063563,
+    "tests/baserow/api/user_files/test_user_files_serializers.py::test_user_file_field": 0.06825027700324426,
+    "tests/baserow/api/user_files/test_user_files_views.py::test_upload_file": 0.09843332099626423,
+    "tests/baserow/api/user_files/test_user_files_views.py::test_upload_file_via_url": 0.07843205600147485,
+    "tests/baserow/api/user_files/test_user_files_views.py::test_upload_file_via_url_within_private_network": 0.06179113500547828,
+    "tests/baserow/api/users/test_token_auth.py::test_token_auth": 0.40702503899592557,
+    "tests/baserow/api/users/test_token_auth.py::test_token_refresh": 0.06361441300396109,
+    "tests/baserow/api/users/test_user_views.py::test_additional_user_data": 0.24153990400009206,
+    "tests/baserow/api/users/test_user_views.py::test_change_password": 0.42482345399912447,
+    "tests/baserow/api/users/test_user_views.py::test_create_user": 0.8124972599980538,
+    "tests/baserow/api/users/test_user_views.py::test_create_user_with_invitation": 0.13139000999581185,
+    "tests/baserow/api/users/test_user_views.py::test_create_user_with_template": 0.15704336899943883,
+    "tests/baserow/api/users/test_user_views.py::test_dashboard": 0.21875405199898523,
+    "tests/baserow/api/users/test_user_views.py::test_password_reset": 0.45837033900170354,
+    "tests/baserow/api/users/test_user_views.py::test_send_reset_password_email": 0.5758736329989915,
+    "tests/baserow/api/users/test_user_views.py::test_user_account": 0.07045094299610355,
+    "tests/baserow/contrib/database/api/export/test_export_views.py::test_exporting_csv_table_writes_file_to_storage": 0.1475635590031743,
+    "tests/baserow/contrib/database/api/export/test_export_views.py::test_exporting_csv_writes_file_to_storage": 0.26490028300031554,
+    "tests/baserow/contrib/database/api/export/test_export_views.py::test_exporting_missing_table_returns_error": 0.06254219900074531,
+    "tests/baserow/contrib/database/api/export/test_export_views.py::test_exporting_missing_view_returns_error": 0.07351541500247549,
+    "tests/baserow/contrib/database/api/export/test_export_views.py::test_exporting_table_without_permissions_returns_error": 0.13916019400130608,
+    "tests/baserow/contrib/database/api/export/test_export_views.py::test_exporting_view_which_isnt_for_table_returns_error": 0.09187659600138431,
+    "tests/baserow/contrib/database/api/export/test_export_views.py::test_getting_missing_export_job_returns_error": 0.06867379299728782,
+    "tests/baserow/contrib/database/api/export/test_export_views.py::test_getting_other_users_export_job_returns_error": 0.1406945069975336,
+    "tests/baserow/contrib/database/api/export/test_export_views.py::test_unknown_export_type_for_table_returns_error": 0.08280015499985893,
+    "tests/baserow/contrib/database/api/fields/dependencies/test_dependency_rebuilder.py::test_formula_fields_will_be_rebuilt_to_depend_on_each_other": 0.04199140799755696,
+    "tests/baserow/contrib/database/api/fields/dependencies/test_dependency_rebuilder.py::test_rebuilding_a_link_row_field_creates_dependencies_with_vias": 0.07181699300053879,
+    "tests/baserow/contrib/database/api/fields/dependencies/test_dependency_rebuilder.py::test_rebuilding_with_a_circular_ref_will_raise": 0.04362488100377959,
+    "tests/baserow/contrib/database/api/fields/dependencies/test_dependency_rebuilder.py::test_str_of_field_dependency_uniquely_identifies_it": 0.05699873800040223,
+    "tests/baserow/contrib/database/api/fields/dependencies/test_dependency_rebuilder.py::test_trashing_a_link_row_field_breaks_vias": 0.06546254599743406,
+    "tests/baserow/contrib/database/api/fields/dependencies/test_field_cache.py::test_can_add_model_with_fields_to_cache": 0.028044913000485394,
+    "tests/baserow/contrib/database/api/fields/dependencies/test_field_cache.py::test_can_get_model_via_cache": 0.02391596500092419,
+    "tests/baserow/contrib/database/api/fields/dependencies/test_field_cache.py::test_can_just_add_model_fields_to_cache": 0.03038870000455063,
+    "tests/baserow/contrib/database/api/fields/dependencies/test_field_cache.py::test_cannot_cache_trashed_field": 0.023679249996348517,
+    "tests/baserow/contrib/database/api/fields/dependencies/test_field_cache.py::test_field_cache_can_inherit_cache_from_another": 0.022658789002889534,
+    "tests/baserow/contrib/database/api/fields/dependencies/test_field_cache.py::test_field_cache_can_inherit_from_model": 0.02182538499982911,
+    "tests/baserow/contrib/database/api/fields/dependencies/test_field_cache.py::test_field_cache_does_no_database_lookup_for_cached_field": 0.020897279999189777,
+    "tests/baserow/contrib/database/api/fields/dependencies/test_field_cache.py::test_looking_up_field_by_name_not_in_cache_queries_to_get_specific_field": 0.022547369993844768,
+    "tests/baserow/contrib/database/api/fields/dependencies/test_field_cache.py::test_looking_up_missing_specific_field_does_query": 0.024398211000516312,
+    "tests/baserow/contrib/database/api/fields/dependencies/test_field_cache.py::test_looking_up_non_existent_field_returns_none_after_query": 0.025942121999833034,
+    "tests/baserow/contrib/database/api/fields/dependencies/test_field_cache.py::test_looking_up_specific_field_which_does_not_exist_returns_none": 0.03746312800285523,
+    "tests/baserow/contrib/database/api/fields/dependencies/test_field_dependency_handler.py::test_deep_circular_ref": 3.631787512993469,
+    "tests/baserow/contrib/database/api/fields/dependencies/test_field_dependency_handler.py::test_get_same_table_deps": 0.04581077900365926,
+    "tests/baserow/contrib/database/api/fields/dependencies/test_update_collector.py::test_can_add_fields_in_same_starting_table_with_row_filter": 0.02965537099953508,
+    "tests/baserow/contrib/database/api/fields/dependencies/test_update_collector.py::test_can_add_fields_with_update_statements_in_same_starting_table": 0.02821043700168957,
+    "tests/baserow/contrib/database/api/fields/dependencies/test_update_collector.py::test_can_only_trigger_update_for_rows_joined_to_a_starting_row_across_a_m2m": 0.19416962199829868,
+    "tests/baserow/contrib/database/api/fields/dependencies/test_update_collector.py::test_can_trigger_update_for_rows_joined_to_a_starting_row_across_a_m2m_and_back": 0.19686669899965636,
+    "tests/baserow/contrib/database/api/fields/dependencies/test_update_collector.py::test_update_statements_at_the_same_path_node_are_grouped_into_one": 0.19897947299614316,
+    "tests/baserow/contrib/database/api/fields/test_field_views.py::test_create_field": 0.1480092970014084,
+    "tests/baserow/contrib/database/api/fields/test_field_views.py::test_delete_field": 0.1856247819996497,
+    "tests/baserow/contrib/database/api/fields/test_field_views.py::test_get_field": 0.1564786169983563,
+    "tests/baserow/contrib/database/api/fields/test_field_views.py::test_list_fields": 0.15562909900108934,
+    "tests/baserow/contrib/database/api/fields/test_field_views.py::test_update_field": 0.3366920149928774,
+    "tests/baserow/contrib/database/api/fields/test_field_views_types.py::test_created_on_field_type": 0.13476659600200946,
+    "tests/baserow/contrib/database/api/fields/test_field_views_types.py::test_date_field_type": 0.14075946899538394,
+    "tests/baserow/contrib/database/api/fields/test_field_views_types.py::test_email_field_type": 0.16302842799996142,
+    "tests/baserow/contrib/database/api/fields/test_field_views_types.py::test_file_field_type": 0.3821038940004655,
+    "tests/baserow/contrib/database/api/fields/test_field_views_types.py::test_formula_field_type": 0.1440126439993037,
+    "tests/baserow/contrib/database/api/fields/test_field_views_types.py::test_last_modified_field_type": 0.2172387639984663,
+    "tests/baserow/contrib/database/api/fields/test_field_views_types.py::test_long_text_field_type": 0.17023809899910702,
+    "tests/baserow/contrib/database/api/fields/test_field_views_types.py::test_lookup_field_type": 0.5808620119969419,
+    "tests/baserow/contrib/database/api/fields/test_field_views_types.py::test_multiple_select_field_type": 0.4850003440005821,
+    "tests/baserow/contrib/database/api/fields/test_field_views_types.py::test_number_field_type": 0.20009806599409785,
+    "tests/baserow/contrib/database/api/fields/test_field_views_types.py::test_phone_number_field_type": 0.1590226070038625,
+    "tests/baserow/contrib/database/api/fields/test_field_views_types.py::test_text_field_type": 0.09298098300132551,
+    "tests/baserow/contrib/database/api/fields/test_field_views_types.py::test_url_field_type": 0.15982422600063728,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_altering_type_of_underlying_causes_type_update": 0.1628146459988784,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_altering_type_of_underlying_causes_type_update_nested": 0.22926719200404477,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_altering_value_of_referenced_field": 0.175672705998295,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_can_compare_date_and_text": 0.14620122800261015,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_can_set_number_of_decimal_places": 0.18296201600242057,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_can_type_a_valid_formula_field": 0.13454910700238543,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_can_type_an_invalid_formula_field": 0.125973055997747,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_cant_make_circular_reference": 0.1275375469995197,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_cant_make_self_reference": 0.08383525099998224,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_changing_name_of_referenced_field_by_formula": 0.1457219769981748,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_changing_type_of_reference_field_to_invalid_one_for_formula": 0.16212627200366114,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_changing_type_of_reference_field_to_valid_one_for_formula": 0.15590606899786508,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_deleting_underlying_causes_type_update_nested": 0.1954870769950503,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_deleting_underlying_causes_type_update_nested_after_update": 0.21761368800434866,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_referencing_single_select": 0.13943857599952025,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_trashing_child_field": 0.14949497900306596,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_trashing_creating_child_field": 0.21074864500042167,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_trashing_formula_field": 0.1467373969971959,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_trashing_renaming_child_field": 0.21886658400399028,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_trashing_restoring_child_field": 0.18458519800333306,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_trashing_row_changing_formula_restoring_row": 0.19343550199482706,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_type_endpoint_returns_error_for_bad_syntax": 0.1317748909968941,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_type_endpoint_returns_error_for_circular_reference": 0.12905616100033512,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_type_endpoint_returns_error_for_missing_field": 0.09792185100377537,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_type_endpoint_returns_error_for_missing_parameters": 0.12250422499710112,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_type_endpoint_returns_error_for_non_formula_field": 0.09061722999831545,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_type_endpoint_returns_error_for_self_reference": 0.10190203099773498,
+    "tests/baserow/contrib/database/api/fields/test_formula_views.py::test_type_endpoint_returns_error_if_not_permissioned_for_field": 0.1713761080027325,
+    "tests/baserow/contrib/database/api/rows/test_row_serializers.py::test_get_example_row_serializer_class": 0.004491002997383475,
+    "tests/baserow/contrib/database/api/rows/test_row_serializers.py::test_get_row_serializer_with_user_field_names": 2.441662647001067,
+    "tests/baserow/contrib/database/api/rows/test_row_serializers.py::test_get_table_serializer": 0.05116628499672515,
+    "tests/baserow/contrib/database/api/rows/test_row_views.py::test_create_empty_row_for_interesting_fields": 2.4490239119950274,
+    "tests/baserow/contrib/database/api/rows/test_row_views.py::test_create_row": 0.29529440099940985,
+    "tests/baserow/contrib/database/api/rows/test_row_views.py::test_delete_row": 0.17443420700146817,
+    "tests/baserow/contrib/database/api/rows/test_row_views.py::test_get_row": 0.141728389000491,
+    "tests/baserow/contrib/database/api/rows/test_row_views.py::test_list_rows": 0.3350494859951141,
+    "tests/baserow/contrib/database/api/rows/test_row_views.py::test_list_rows_returns_https_next_url": 0.16374159699989832,
+    "tests/baserow/contrib/database/api/rows/test_row_views.py::test_list_rows_with_attribute_names": 0.3217858050011273,
+    "tests/baserow/contrib/database/api/rows/test_row_views.py::test_move_row": 0.16662000799624366,
+    "tests/baserow/contrib/database/api/rows/test_row_views.py::test_update_row": 0.23137770999892382,
+    "tests/baserow/contrib/database/api/tables/test_table_views.py::test_create_table": 0.134581744998286,
+    "tests/baserow/contrib/database/api/tables/test_table_views.py::test_create_table_with_data": 0.2855748809961369,
+    "tests/baserow/contrib/database/api/tables/test_table_views.py::test_delete_table": 0.08686402400053339,
+    "tests/baserow/contrib/database/api/tables/test_table_views.py::test_get_database_application_with_tables": 0.08495705899986206,
+    "tests/baserow/contrib/database/api/tables/test_table_views.py::test_get_table": 0.09060510499330121,
+    "tests/baserow/contrib/database/api/tables/test_table_views.py::test_list_tables": 0.10171817599621136,
+    "tests/baserow/contrib/database/api/tables/test_table_views.py::test_order_tables": 0.09722899700136622,
+    "tests/baserow/contrib/database/api/tables/test_table_views.py::test_update_table": 0.08783515899995109,
+    "tests/baserow/contrib/database/api/tokens/test_token_views.py::test_create_token": 0.07867190500110155,
+    "tests/baserow/contrib/database/api/tokens/test_token_views.py::test_delete_token": 0.14079041600052733,
+    "tests/baserow/contrib/database/api/tokens/test_token_views.py::test_get_token": 0.1430730570027663,
+    "tests/baserow/contrib/database/api/tokens/test_token_views.py::test_list_tokens": 0.06720003300506505,
+    "tests/baserow/contrib/database/api/tokens/test_token_views.py::test_update_token": 0.1902480920034577,
+    "tests/baserow/contrib/database/api/views/form/test_form_view_views.py::test_create_form_view": 0.20258397699944908,
+    "tests/baserow/contrib/database/api/views/form/test_form_view_views.py::test_form_view_link_row_lookup_view": 0.2733425680016808,
+    "tests/baserow/contrib/database/api/views/form/test_form_view_views.py::test_meta_submit_form_view": 0.2692732080067799,
+    "tests/baserow/contrib/database/api/views/form/test_form_view_views.py::test_submit_form_view": 0.26396848899457837,
+    "tests/baserow/contrib/database/api/views/form/test_form_view_views.py::test_test_enable_form_view_file_field_options": 0.08749844599878998,
+    "tests/baserow/contrib/database/api/views/form/test_form_view_views.py::test_update_form_view": 0.210900057994877,
+    "tests/baserow/contrib/database/api/views/gallery/test_gallery_view_views.py::test_create_gallery_view": 0.0891224089973548,
+    "tests/baserow/contrib/database/api/views/gallery/test_gallery_view_views.py::test_create_gallery_view_invalid_card_card_cover_image_field": 0.10511221399792703,
+    "tests/baserow/contrib/database/api/views/gallery/test_gallery_view_views.py::test_list_rows": 0.16476365799826453,
+    "tests/baserow/contrib/database/api/views/gallery/test_gallery_view_views.py::test_list_rows_include_field_options": 0.10771367499910411,
+    "tests/baserow/contrib/database/api/views/gallery/test_gallery_view_views.py::test_patch_gallery_view_field_options": 0.09253393100152607,
+    "tests/baserow/contrib/database/api/views/gallery/test_gallery_view_views.py::test_update_gallery_view": 0.07893334800246521,
+    "tests/baserow/contrib/database/api/views/grid/test_grid_view_views.py::test_anon_user_cant_get_info_about_a_non_public_grid_view": 0.07515704900652054,
+    "tests/baserow/contrib/database/api/views/grid/test_grid_view_views.py::test_cannot_get_info_about_non_grid_view": 0.0775598850013921,
+    "tests/baserow/contrib/database/api/views/grid/test_grid_view_views.py::test_cannot_get_info_about_trashed_grid_view": 0.075971287998982,
+    "tests/baserow/contrib/database/api/views/grid/test_grid_view_views.py::test_create_grid_view": 0.10972058600236778,
+    "tests/baserow/contrib/database/api/views/grid/test_grid_view_views.py::test_get_public_grid_view": 0.09831430700069177,
+    "tests/baserow/contrib/database/api/views/grid/test_grid_view_views.py::test_grid_view_link_row_lookup_view": 0.7109714940015692,
+    "tests/baserow/contrib/database/api/views/grid/test_grid_view_views.py::test_list_filtered_rows": 0.14801164999880712,
+    "tests/baserow/contrib/database/api/views/grid/test_grid_view_views.py::test_list_rows": 0.2360160369935329,
+    "tests/baserow/contrib/database/api/views/grid/test_grid_view_views.py::test_list_rows_include_field_options": 0.10739521499999682,
+    "tests/baserow/contrib/database/api/views/grid/test_grid_view_views.py::test_list_rows_include_row_metadata": 0.10350224899957539,
+    "tests/baserow/contrib/database/api/views/grid/test_grid_view_views.py::test_list_rows_public_doesnt_show_hidden_columns": 0.10406807000254048,
+    "tests/baserow/contrib/database/api/views/grid/test_grid_view_views.py::test_list_rows_public_filters_by_visible_and_hidden_columns": 0.12023807599689462,
+    "tests/baserow/contrib/database/api/views/grid/test_grid_view_views.py::test_list_rows_public_only_searches_by_visible_columns": 0.11662993299614755,
+    "tests/baserow/contrib/database/api/views/grid/test_grid_view_views.py::test_list_rows_public_with_query_param_filter": 0.14344609799809405,
+    "tests/baserow/contrib/database/api/views/grid/test_grid_view_views.py::test_list_rows_public_with_query_param_order": 0.22428822200163268,
+    "tests/baserow/contrib/database/api/views/grid/test_grid_view_views.py::test_patch_grid_view_field_options": 0.15389443700041738,
+    "tests/baserow/contrib/database/api/views/grid/test_grid_view_views.py::test_update_grid_view": 0.20268017899797997,
+    "tests/baserow/contrib/database/api/views/grid/test_grid_view_views.py::test_user_in_same_group_can_get_info_about_a_non_public_grid_view": 0.08084305799638969,
+    "tests/baserow/contrib/database/api/views/grid/test_grid_view_views.py::test_user_in_wrong_group_cant_get_info_about_a_non_public_grid_view": 0.12456008899971494,
+    "tests/baserow/contrib/database/api/views/test_view_views.py::test_create_view_filter": 0.14537222699800623,
+    "tests/baserow/contrib/database/api/views/test_view_views.py::test_create_view_sort": 0.18325927299883915,
+    "tests/baserow/contrib/database/api/views/test_view_views.py::test_delete_view": 0.15172227699804353,
+    "tests/baserow/contrib/database/api/views/test_view_views.py::test_delete_view_filter": 0.10696290399937425,
+    "tests/baserow/contrib/database/api/views/test_view_views.py::test_delete_view_sort": 0.11403457599953981,
+    "tests/baserow/contrib/database/api/views/test_view_views.py::test_get_link_row_filter_type_preload_values": 0.16057079700112808,
+    "tests/baserow/contrib/database/api/views/test_view_views.py::test_get_view": 0.16730092799843987,
+    "tests/baserow/contrib/database/api/views/test_view_views.py::test_get_view_field_options": 0.09921593299804954,
+    "tests/baserow/contrib/database/api/views/test_view_views.py::test_get_view_filter": 0.11309163399710087,
+    "tests/baserow/contrib/database/api/views/test_view_views.py::test_get_view_sort": 0.11562721699738177,
+    "tests/baserow/contrib/database/api/views/test_view_views.py::test_list_view_filters": 0.11876866399688879,
+    "tests/baserow/contrib/database/api/views/test_view_views.py::test_list_view_sortings": 0.12259314099719631,
+    "tests/baserow/contrib/database/api/views/test_view_views.py::test_list_views": 0.12278038499789545,
+    "tests/baserow/contrib/database/api/views/test_view_views.py::test_list_views_including_filters": 0.126608128000953,
+    "tests/baserow/contrib/database/api/views/test_view_views.py::test_list_views_including_sortings": 0.11670814999888535,
+    "tests/baserow/contrib/database/api/views/test_view_views.py::test_order_views": 0.10444455799733987,
+    "tests/baserow/contrib/database/api/views/test_view_views.py::test_patch_view_field_options": 0.11464323900145246,
+    "tests/baserow/contrib/database/api/views/test_view_views.py::test_rotate_slug": 0.09620847800033516,
+    "tests/baserow/contrib/database/api/views/test_view_views.py::test_update_view_filter": 0.17680737499904353,
+    "tests/baserow/contrib/database/api/views/test_view_views.py::test_update_view_sort": 0.19296561699957238,
+    "tests/baserow/contrib/database/api/webhooks/test_webhook_serializers.py::test_invalid_urls[http://google.de:8a]": 0.0008866970019880682,
+    "tests/baserow/contrib/database/api/webhooks/test_webhook_serializers.py::test_invalid_urls[http://localhost:4000/endpoint]": 0.001069691999873612,
+    "tests/baserow/contrib/database/api/webhooks/test_webhook_serializers.py::test_invalid_urls[http://localhost]": 0.0017054639974958263,
+    "tests/baserow/contrib/database/api/webhooks/test_webhook_serializers.py::test_invalid_urls[https://192.168.172.1:4000]": 0.001939785997819854,
+    "tests/baserow/contrib/database/api/webhooks/test_webhook_serializers.py::test_valid_urls[http://google.de]": 0.040831563994288445,
+    "tests/baserow/contrib/database/api/webhooks/test_webhook_serializers.py::test_valid_urls[https://google.de]": 0.022984340001130477,
+    "tests/baserow/contrib/database/api/webhooks/test_webhook_serializers.py::test_valid_urls[https://heise.de/myendpoint]": 0.04889409800307476,
+    "tests/baserow/contrib/database/api/webhooks/test_webhook_views.py::test_create_webhooks": 1.2879868909985817,
+    "tests/baserow/contrib/database/api/webhooks/test_webhook_views.py::test_delete_webhook": 0.1737498170004983,
+    "tests/baserow/contrib/database/api/webhooks/test_webhook_views.py::test_get_webhook": 0.14007720600056928,
+    "tests/baserow/contrib/database/api/webhooks/test_webhook_views.py::test_list_webhooks": 0.15533950399549212,
+    "tests/baserow/contrib/database/api/webhooks/test_webhook_views.py::test_trigger_test_call": 0.14251925600183313,
+    "tests/baserow/contrib/database/api/webhooks/test_webhook_views.py::test_update_webhook": 0.29009156100073596,
+    "tests/baserow/contrib/database/db/test_db_schema.py::test_lenient_schema_editor": 0.004551785994408419,
+    "tests/baserow/contrib/database/export/test_export_handler.py::test_a_column_without_a_grid_view_option_has_an_option_made_and_is_exported": 0.10983220500202151,
+    "tests/baserow/contrib/database/export/test_export_handler.py::test_a_complete_export_job_which_has_expired_will_have_its_file_deleted": 0.579833221003355,
+    "tests/baserow/contrib/database/export/test_export_handler.py::test_a_pending_job_which_has_expired_will_be_cleaned_up": 0.17267014800017932,
+    "tests/baserow/contrib/database/export/test_export_handler.py::test_a_running_export_job_which_has_expired_will_be_stopped": 0.16619485699993675,
+    "tests/baserow/contrib/database/export/test_export_handler.py::test_adding_more_rows_doesnt_increase_number_of_queries_run": 0.3120753990006051,
+    "tests/baserow/contrib/database/export/test_export_handler.py::test_an_export_job_which_fails_will_be_marked_as_a_failed_job": 0.0742540610008291,
+    "tests/baserow/contrib/database/export/test_export_handler.py::test_attempting_to_export_a_table_for_a_type_which_doesnt_support_it_fails": 0.07688076999693294,
+    "tests/baserow/contrib/database/export/test_export_handler.py::test_attempting_to_export_a_view_for_a_type_which_doesnt_support_it_fails": 0.07160518299860996,
+    "tests/baserow/contrib/database/export/test_export_handler.py::test_can_export_csv_with_different_charsets": 8.76918447999924,
+    "tests/baserow/contrib/database/export/test_export_handler.py::test_can_export_csv_with_different_column_separators": 1.563400430000911,
+    "tests/baserow/contrib/database/export/test_export_handler.py::test_can_export_csv_without_header": 0.27060809600152425,
+    "tests/baserow/contrib/database/export/test_export_handler.py::test_can_export_every_interesting_different_field_to_csv": 2.377172832002543,
+    "tests/baserow/contrib/database/export/test_export_handler.py::test_columns_are_exported_by_order_then_field_id": 0.10840328999620397,
+    "tests/baserow/contrib/database/export/test_export_handler.py::test_creating_a_new_export_job_will_cancel_any_already_running_jobs_for_that_user": 0.12699116799922194,
+    "tests/baserow/contrib/database/export/test_export_handler.py::test_creating_job_with_view_that_is_not_in_the_table": 0.08320964399899822,
+    "tests/baserow/contrib/database/export/test_export_handler.py::test_csv_is_filtered_by_filters": 0.09953807700367179,
+    "tests/baserow/contrib/database/export/test_export_handler.py::test_csv_is_sorted_by_sorts": 0.1057687279972015,
+    "tests/baserow/contrib/database/export/test_export_handler.py::test_exporting_table_ignores_view_filters_sorts_hides": 0.09551877000194509,
+    "tests/baserow/contrib/database/export/test_export_handler.py::test_hidden_fields_are_excluded": 0.10250970199922449,
+    "tests/baserow/contrib/database/field/test_boolean_field_type.py::test_alter_boolean_field_column_type": 0.12137663600515225,
+    "tests/baserow/contrib/database/field/test_boolean_field_type.py::test_get_set_export_serialized_value_boolean_field": 0.024144502000126522,
+    "tests/baserow/contrib/database/field/test_created_on_field_type.py::test_created_on_field_type": 0.24812444300187053,
+    "tests/baserow/contrib/database/field/test_created_on_field_type.py::test_created_on_field_type_wrong_timezone": 0.07261885700063431,
+    "tests/baserow/contrib/database/field/test_created_on_field_type.py::test_import_export_last_modified_field": 0.1495540789946972,
+    "tests/baserow/contrib/database/field/test_date_field_type.py::test_converting_date_field_value": 0.6265088500003912,
+    "tests/baserow/contrib/database/field/test_date_field_type.py::test_date_field_type": 0.16364126499684062,
+    "tests/baserow/contrib/database/field/test_date_field_type.py::test_date_field_type_prepare_value": 0.02804522599763004,
+    "tests/baserow/contrib/database/field/test_date_field_type.py::test_get_set_export_serialized_value_date_field": 0.02986785100074485,
+    "tests/baserow/contrib/database/field/test_date_field_type.py::test_import_export_date_field": 0.02213132899851189,
+    "tests/baserow/contrib/database/field/test_date_field_type.py::test_negative_date_field_value": 0.13234241499958443,
+    "tests/baserow/contrib/database/field/test_field_converters.py::test_link_row_field_converter_applicable": 0.03300329500052612,
+    "tests/baserow/contrib/database/field/test_field_filters.py::test_building_filter_with_and_type_ands_all_provided_qs_together": 0.08177209099449101,
+    "tests/baserow/contrib/database/field/test_field_filters.py::test_building_filter_with_annotated_qs_annotates_prior_to_filter": 0.0819289259998186,
+    "tests/baserow/contrib/database/field/test_field_filters.py::test_building_filter_with_many_annotated_qs_merges_the_annotations": 0.0848865059997479,
+    "tests/baserow/contrib/database/field/test_field_filters.py::test_building_filter_with_or_type_ors_all_provided_qs_together": 0.08496238800216815,
+    "tests/baserow/contrib/database/field/test_field_filters.py::test_can_invert_an_annotated_q": 0.07781829900704906,
+    "tests/baserow/contrib/database/field/test_field_handler.py::test_can_convert_between_all_fields": 0.00021683700106223114,
+    "tests/baserow/contrib/database/field/test_field_handler.py::test_can_convert_formula_to_numeric_field": 0.10579274100018665,
+    "tests/baserow/contrib/database/field/test_field_handler.py::test_create_field": 0.19514646500101662,
+    "tests/baserow/contrib/database/field/test_field_handler.py::test_create_primary_field": 0.11009516000194708,
+    "tests/baserow/contrib/database/field/test_field_handler.py::test_delete_field": 0.1498028170026373,
+    "tests/baserow/contrib/database/field/test_field_handler.py::test_field_which_changes_its_underlying_type_will_have_alter_sql_run": 0.09431575999769848,
+    "tests/baserow/contrib/database/field/test_field_handler.py::test_find_next_free_field_name": 0.09337993999724858,
+    "tests/baserow/contrib/database/field/test_field_handler.py::test_find_next_free_field_name_returns_strings_with_max_length": 0.08598811599586043,
+    "tests/baserow/contrib/database/field/test_field_handler.py::test_get_field": 0.14203433299917378,
+    "tests/baserow/contrib/database/field/test_field_handler.py::test_just_changing_a_fields_name_will_not_run_alter_sql": 0.08866632200079039,
+    "tests/baserow/contrib/database/field/test_field_handler.py::test_update_field": 0.2711294740001904,
+    "tests/baserow/contrib/database/field/test_field_handler.py::test_update_field_failing": 0.0960010679991683,
+    "tests/baserow/contrib/database/field/test_field_handler.py::test_update_field_when_underlying_sql_type_doesnt_change": 0.09474686999965343,
+    "tests/baserow/contrib/database/field/test_field_handler.py::test_update_field_when_underlying_sql_type_doesnt_change_old_prep": 0.10109238799850573,
+    "tests/baserow/contrib/database/field/test_field_handler.py::test_update_field_when_underlying_sql_type_doesnt_change_with_vars": 0.10058151799967163,
+    "tests/baserow/contrib/database/field/test_field_handler.py::test_update_field_with_type_error_on_conversion_should_null_field": 0.09916723700007424,
+    "tests/baserow/contrib/database/field/test_field_handler.py::test_update_select_options": 0.1626256370000192,
+    "tests/baserow/contrib/database/field/test_field_handler.py::test_when_field_type_forces_same_type_alter_fields_alter_sql_is_run": 0.09917613599827746,
+    "tests/baserow/contrib/database/field/test_field_models.py::test_date_field_get_python_format": 0.00430670399509836,
+    "tests/baserow/contrib/database/field/test_field_models.py::test_link_row_field": 0.02406825999787543,
+    "tests/baserow/contrib/database/field/test_field_models.py::test_model_class_name": 0.029610636996949324,
+    "tests/baserow/contrib/database/field/test_field_types.py::test_email_field_type": 0.19724937800128828,
+    "tests/baserow/contrib/database/field/test_field_types.py::test_human_readable_values": 2.4816247329981707,
+    "tests/baserow/contrib/database/field/test_field_types.py::test_import_export_formula_field": 0.09371159299917053,
+    "tests/baserow/contrib/database/field/test_field_types.py::test_import_export_lookup_field": 0.25005603399768006,
+    "tests/baserow/contrib/database/field/test_field_types.py::test_import_export_text_field": 0.018126520000805613,
+    "tests/baserow/contrib/database/field/test_field_types.py::test_long_text_field_type": 0.1282892269991862,
+    "tests/baserow/contrib/database/field/test_field_types.py::test_phone_number_field_type": 0.23874165899906075,
+    "tests/baserow/contrib/database/field/test_field_types.py::test_valid_email": 0.2318102090030152,
+    "tests/baserow/contrib/database/field/test_field_types.py::test_valid_url": 0.27917843500108575,
+    "tests/baserow/contrib/database/field/test_file_field_type.py::test_file_field_type": 0.3630491420008184,
+    "tests/baserow/contrib/database/field/test_file_field_type.py::test_import_export_file_field": 0.14462564299901715,
+    "tests/baserow/contrib/database/field/test_formula_field_type.py::test_accessing_cached_internal_formula_second_time_does_no_queries": 0.10153150399855804,
+    "tests/baserow/contrib/database/field/test_formula_field_type.py::test_adding_a_formula_field_to_an_existing_table_populates_it_for_all_rows": 0.09579599299831898,
+    "tests/baserow/contrib/database/field/test_formula_field_type.py::test_all_functions_are_registered": 0.0039157699975476135,
+    "tests/baserow/contrib/database/field/test_formula_field_type.py::test_can_change_formula_type_breaking_other_fields": 0.14392171900180983,
+    "tests/baserow/contrib/database/field/test_formula_field_type.py::test_can_delete_double_link_lookup_field_value": 0.6320674550006515,
+    "tests/baserow/contrib/database/field/test_formula_field_type.py::test_can_delete_lookup_field_value": 0.34569244599697413,
+    "tests/baserow/contrib/database/field/test_formula_field_type.py::test_can_insert_and_update_rows_with_formula_referencing_single_select": 0.13613402400005725,
+    "tests/baserow/contrib/database/field/test_formula_field_type.py::test_can_rename_field_preserving_whitespace": 0.12186881999878096,
+    "tests/baserow/contrib/database/field/test_formula_field_type.py::test_can_still_insert_rows_with_an_invalid_but_previously_date_formula_field": 0.15406459500081837,
+    "tests/baserow/contrib/database/field/test_formula_field_type.py::test_can_update_lookup_field_value": 0.32714918200144893,
+    "tests/baserow/contrib/database/field/test_formula_field_type.py::test_can_use_complex_contains_filters_on_formula_field": 0.08978627500255243,
+    "tests/baserow/contrib/database/field/test_formula_field_type.py::test_can_use_complex_date_filters_on_formula_field": 0.08858395700008259,
+    "tests/baserow/contrib/database/field/test_formula_field_type.py::test_cannot_create_view_filter_or_sort_on_invalid_field": 0.4201982289996522,
+    "tests/baserow/contrib/database/field/test_formula_field_type.py::test_cant_change_the_value_of_a_formula_field_directly": 0.029709312999329995,
+    "tests/baserow/contrib/database/field/test_formula_field_type.py::test_changing_type_of_other_field_still_results_in_working_filter": 0.11439791700104252,
+    "tests/baserow/contrib/database/field/test_formula_field_type.py::test_creating_a_model_with_formula_field_immediately_populates_it": 0.027323898000759073,
+    "tests/baserow/contrib/database/field/test_formula_field_type.py::test_formula_with_row_id_is_populated_after_creating_row": 0.0940826410005684,
+    "tests/baserow/contrib/database/field/test_formula_field_type.py::test_get_set_export_serialized_value_formula_field": 0.027972527997917496,
+    "tests/baserow/contrib/database/field/test_formula_field_type.py::test_nested_lookup_with_formula": 0.41812684599790373,
+    "tests/baserow/contrib/database/field/test_formula_field_type.py::test_recalculate_formulas_according_to_version": 0.08361776099991403,
+    "tests/baserow/contrib/database/field/test_formula_field_type.py::test_recalculated_internal_type_with_incorrect_syntax_formula_sets_to_invalid": 0.1074197690031724,
+    "tests/baserow/contrib/database/field/test_formula_field_type.py::test_renaming_dependency_maintains_dependency_link": 0.12872540599710192,
+    "tests/baserow/contrib/database/field/test_formula_field_type.py::test_row_dependency_update_functions_do_no_row_updates_for_same_table": 0.11095411400674493,
+    "tests/baserow/contrib/database/field/test_formula_field_type.py::test_saving_after_properties_have_been_cached_does_recaclulation": 0.10173656799815944,
+    "tests/baserow/contrib/database/field/test_last_modified_field_type.py::test_import_export_last_modified_field": 0.1482895599983749,
+    "tests/baserow/contrib/database/field/test_last_modified_field_type.py::test_last_modified_field_type": 0.2690179360033653,
+    "tests/baserow/contrib/database/field/test_last_modified_field_type.py::test_last_modified_field_type_wrong_timezone": 0.07042218800052069,
+    "tests/baserow/contrib/database/field/test_link_row_field_type.py::test_call_apps_registry_pending_operations": 0.12751273899993976,
+    "tests/baserow/contrib/database/field/test_link_row_field_type.py::test_change_link_row_related_table_when_field_with_related_name_exists": 0.18322343299951172,
+    "tests/baserow/contrib/database/field/test_link_row_field_type.py::test_change_type_to_link_row_field_when_field_with_same_related_name_already_exists": 0.23182258199813077,
+    "tests/baserow/contrib/database/field/test_link_row_field_type.py::test_creating_a_linked_row_pointing_at_trashed_row_works_but_does_not_display": 0.2790179820040066,
+    "tests/baserow/contrib/database/field/test_link_row_field_type.py::test_import_export_link_row_field": 0.2848040260032576,
+    "tests/baserow/contrib/database/field/test_link_row_field_type.py::test_link_row_enhance_queryset": 0.2134044919985172,
+    "tests/baserow/contrib/database/field/test_link_row_field_type.py::test_link_row_field_type": 0.6140818189960555,
+    "tests/baserow/contrib/database/field/test_link_row_field_type.py::test_link_row_field_type_api_row_views": 0.5107156589947408,
+    "tests/baserow/contrib/database/field/test_link_row_field_type.py::test_link_row_field_type_api_views": 0.35717486900102813,
+    "tests/baserow/contrib/database/field/test_link_row_field_type.py::test_link_row_field_type_rows": 0.3503738559993508,
+    "tests/baserow/contrib/database/field/test_lookup_field_type.py::test_can_create_new_row_with_immediate_link_row_values_and_lookup_will_match": 0.26969507800095016,
+    "tests/baserow/contrib/database/field/test_lookup_field_type.py::test_can_lookup_single_select": 0.2894474149979942,
+    "tests/baserow/contrib/database/field/test_lookup_field_type.py::test_can_modify_row_containing_lookup": 0.415125123996404,
+    "tests/baserow/contrib/database/field/test_lookup_field_type.py::test_can_set_sub_type_options_for_lookup_field": 0.24699362800311064,
+    "tests/baserow/contrib/database/field/test_lookup_field_type.py::test_can_update_lookup_field_value": 0.31004207499790937,
+    "tests/baserow/contrib/database/field/test_lookup_field_type.py::test_converting_away_from_lookup_field_deletes_parent_formula_field": 0.3008462889956718,
+    "tests/baserow/contrib/database/field/test_lookup_field_type.py::test_deleting_related_link_row_field_dep_breaks_deps": 0.692901130001701,
+    "tests/baserow/contrib/database/field/test_lookup_field_type.py::test_deleting_related_link_row_field_still_lets_you_create_edit_rows": 0.4997819170021103,
+    "tests/baserow/contrib/database/field/test_lookup_field_type.py::test_deleting_related_table_still_lets_you_create_edit_rows": 0.5518457869984559,
+    "tests/baserow/contrib/database/field/test_lookup_field_type.py::test_deleting_restoring_lookup_target_works": 0.516468169997097,
+    "tests/baserow/contrib/database/field/test_lookup_field_type.py::test_deleting_table_with_dependants_works": 0.8865542860003188,
+    "tests/baserow/contrib/database/field/test_lookup_field_type.py::test_import_export_lookup_field_trashed_target_field": 0.2851856960041914,
+    "tests/baserow/contrib/database/field/test_lookup_field_type.py::test_import_export_lookup_field_when_through_field_trashed": 0.28283000500232447,
+    "tests/baserow/contrib/database/field/test_lookup_field_type.py::test_import_export_tables_with_lookup_fields": 0.4309415409989015,
+    "tests/baserow/contrib/database/field/test_lookup_field_type.py::test_moving_a_looked_up_row_updates_the_order": 0.4074311019976449,
+    "tests/baserow/contrib/database/field/test_multiple_select_field_type.py::test_call_apps_registry_pending_operations": 0.08815630100070848,
+    "tests/baserow/contrib/database/field/test_multiple_select_field_type.py::test_conversion_date_to_multiple_select_field": 0.8899391160011874,
+    "tests/baserow/contrib/database/field/test_multiple_select_field_type.py::test_conversion_email_to_multiple_select_field": 0.16493962600361556,
+    "tests/baserow/contrib/database/field/test_multiple_select_field_type.py::test_conversion_multiple_select_to_single_select_field": 0.24401307399966754,
+    "tests/baserow/contrib/database/field/test_multiple_select_field_type.py::test_conversion_number_to_multiple_select_field": 0.1677826209961495,
+    "tests/baserow/contrib/database/field/test_multiple_select_field_type.py::test_conversion_single_select_to_multiple_select_field": 0.17410404199836194,
+    "tests/baserow/contrib/database/field/test_multiple_select_field_type.py::test_conversion_to_multiple_select_field_with_select_options": 0.14145503300460405,
+    "tests/baserow/contrib/database/field/test_multiple_select_field_type.py::test_conversion_to_multiple_select_with_more_than_threshold_options_in_extraction": 0.18497807899257168,
+    "tests/baserow/contrib/database/field/test_multiple_select_field_type.py::test_conversion_to_multiple_select_with_more_than_threshold_options_provided": 0.17778510200150777,
+    "tests/baserow/contrib/database/field/test_multiple_select_field_type.py::test_conversion_to_multiple_select_with_option_value_too_large": 0.12871136899775593,
+    "tests/baserow/contrib/database/field/test_multiple_select_field_type.py::test_conversion_to_multiple_select_with_same_option_value_on_same_row": 0.12840830000277492,
+    "tests/baserow/contrib/database/field/test_multiple_select_field_type.py::test_convert_long_text_to_multiple_select": 0.12787734100493253,
+    "tests/baserow/contrib/database/field/test_multiple_select_field_type.py::test_convert_multiple_select_to_text": 0.15976367599796504,
+    "tests/baserow/contrib/database/field/test_multiple_select_field_type.py::test_convert_multiple_select_to_text_with_comma_and_quotes": 0.36620113200115156,
+    "tests/baserow/contrib/database/field/test_multiple_select_field_type.py::test_converting_multiple_select_field_value": 0.18431071499799145,
+    "tests/baserow/contrib/database/field/test_multiple_select_field_type.py::test_get_set_export_serialized_value_multiple_select_field": 0.18926347600427107,
+    "tests/baserow/contrib/database/field/test_multiple_select_field_type.py::test_import_export_multiple_select_field": 0.098541983999894,
+    "tests/baserow/contrib/database/field/test_multiple_select_field_type.py::test_multi_select_enhance_queryset": 0.13481401999888476,
+    "tests/baserow/contrib/database/field/test_multiple_select_field_type.py::test_multi_select_field_type": 0.1686954959986906,
+    "tests/baserow/contrib/database/field/test_multiple_select_field_type.py::test_multiple_select_field_type_deleting_select_option": 0.20396548900316702,
+    "tests/baserow/contrib/database/field/test_multiple_select_field_type.py::test_multiple_select_field_type_random_value": 0.12822240099922055,
+    "tests/baserow/contrib/database/field/test_multiple_select_field_type.py::test_multiple_select_field_type_rows": 0.31332344399925205,
+    "tests/baserow/contrib/database/field/test_multiple_select_field_type.py::test_multiple_select_field_type_sorting": 0.1885911820027104,
+    "tests/baserow/contrib/database/field/test_multiple_select_field_type.py::test_multiple_select_with_single_select_present": 0.12125386200204957,
+    "tests/baserow/contrib/database/field/test_number_field_type.py::test_alter_number_field_column_type[expected0-field_kwargs0]": 0.1142319230020803,
+    "tests/baserow/contrib/database/field/test_number_field_type.py::test_alter_number_field_column_type[expected1-field_kwargs1]": 0.10934832399652805,
+    "tests/baserow/contrib/database/field/test_number_field_type.py::test_alter_number_field_column_type[expected2-field_kwargs2]": 0.11313199500000337,
+    "tests/baserow/contrib/database/field/test_number_field_type.py::test_alter_number_field_column_type[expected3-field_kwargs3]": 0.10973676499997964,
+    "tests/baserow/contrib/database/field/test_number_field_type.py::test_alter_number_field_column_type_negative": 0.1140367860061815,
+    "tests/baserow/contrib/database/field/test_number_field_type.py::test_content_type_still_set_when_save_overridden": 0.0125199639951461,
+    "tests/baserow/contrib/database/field/test_number_field_type.py::test_import_export_number_field": 0.024261272003059275,
+    "tests/baserow/contrib/database/field/test_rating_field_type.py::test_field_creation": 0.13661165899975458,
+    "tests/baserow/contrib/database/field/test_rating_field_type.py::test_rating_field_modification": 0.37719987599848537,
+    "tests/baserow/contrib/database/field/test_rating_field_type.py::test_row_creation": 0.11954575200070394,
+    "tests/baserow/contrib/database/field/test_single_select_field_type.py::test_get_set_export_serialized_value_single_select_field": 0.11277724899991881,
+    "tests/baserow/contrib/database/field/test_single_select_field_type.py::test_import_export_single_select_field": 0.09259393200045452,
+    "tests/baserow/contrib/database/field/test_single_select_field_type.py::test_primary_single_select_field_with_link_row_field": 0.30158197099444806,
+    "tests/baserow/contrib/database/field/test_single_select_field_type.py::test_single_select_field_type": 0.16515628299748641,
+    "tests/baserow/contrib/database/field/test_single_select_field_type.py::test_single_select_field_type_api_row_views": 0.18490051399567164,
+    "tests/baserow/contrib/database/field/test_single_select_field_type.py::test_single_select_field_type_api_views": 0.2133135609983583,
+    "tests/baserow/contrib/database/field/test_single_select_field_type.py::test_single_select_field_type_get_order": 0.12853297599576763,
+    "tests/baserow/contrib/database/field/test_single_select_field_type.py::test_single_select_field_type_random_value": 0.11747650199686177,
+    "tests/baserow/contrib/database/field/test_single_select_field_type.py::test_single_select_field_type_rows": 0.30128350199811393,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas['a' + 2-ERROR_WITH_FORMULA-Error with formula: argument number 2 given to operator + was of type number but the only usable types for this argument are text,char.]": 0.08201323300454533,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas['a' < 1-ERROR_WITH_FORMULA-None]": 0.08076972400158411,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas['a' > 1-ERROR_WITH_FORMULA-None]": 0.0879280920016754,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas['t'/1-ERROR_WITH_FORMULA-None]": 0.07796206100101699,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[1/'t'-ERROR_WITH_FORMULA-None]": 0.07786832300189417,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[10/LOWER(1)-ERROR_WITH_FORMULA-None]": 0.08022280800287263,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[CONCAT('a')-ERROR_WITH_FORMULA-Error with formula: 1 argument was given to the function concat, it must instead be given more than 1 arguments.]": 0.09131320400047116,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[CONCAT('test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test')-ERROR_WITH_FORMULA-Error with formula: it exceeded the maximum formula size.]": 4.091613471995515,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[CONCAT()-ERROR_WITH_FORMULA-Error with formula: 0 arguments were given to the function concat, it must instead be given more than 1 arguments.]": 0.08824853400074062,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[LOWER('a', CONCAT())-ERROR_WITH_FORMULA-None]": 0.08390476999920793,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[LOWER('a','a')-ERROR_WITH_FORMULA-None]": 0.07685991800462944,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[LOWER()-ERROR_WITH_FORMULA-None]": 0.08320808899952681,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[LOWER(1)-ERROR_WITH_FORMULA-None]": 0.08432201200048439,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[LOWER(1,2)-ERROR_WITH_FORMULA-None]": 0.08332277699446422,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[UPPER('a','a')-ERROR_WITH_FORMULA-Error with formula: 2 arguments were given to the function upper, it must instead be given exactly 1 argument.]": 0.07582142499813926,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[UPPER('ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt')-ERROR_WITH_FORMULA-Error with formula: an embedded string in the formula over the maximum length of 10000 .]": 0.13463028399200994,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[UPPER()-ERROR_WITH_FORMULA-None]": 0.08495423199929064,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[UPPER(1)-ERROR_WITH_FORMULA-None]": 0.08191172200167784,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[UPPER(1,2)-ERROR_WITH_FORMULA-None]": 0.08261589799803915,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER('test'))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))-ERROR_WITH_FORMULA-Error with formula: it exceeded the maximum formula size.]": 0.15821069600133342,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[concat(upper(1), lower('a'))-ERROR_WITH_FORMULA-Error with formula: argument number 1 given to function upper was of type number but the only usable type for this argument is text.]": 0.08718186099940795,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[concat(upper(1), lower(2))-ERROR_WITH_FORMULA-Error with formula: argument number 1 given to function upper was of type number but the only usable type for this argument is text, argument number 1 given to function lower was of type number but the only usable type for this argument is text.]": 0.08318980500189355,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[date_interval('1 second') - todate('20210101', 'YYYYMMDD')-ERROR_WITH_FORMULA-Error with formula: argument number 2 given to operator - was of type date but the only usable type for this argument is date_interval.]": 0.08228327100005117,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[field(9999)-ERROR_WITH_FORMULA-None]": 0.07631486300306278,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[field_by_id(9999)-ERROR_WITH_FORMULA-None]": 0.07760962700194796,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[left(\"aa\", 2.0)-ERROR_WITH_FORMULA-Error with formula: argument number 2 given to function left was of type number but the only usable type for this argument is a whole number with no decimal places.]": 0.08826549600053113,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[test-ERROR_WITH_FORMULA-Error with formula: Invalid syntax at line 1, col 4: mismatched input 'the end of the formula' expecting '('.]": 0.07700468900657143,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[todate('20200101', 'YYYYMMDD') + todate('20210101', 'YYYYMMDD')-ERROR_WITH_FORMULA-Error with formula: argument number 2 given to operator + was of type date but the only usable type for this argument is date_interval.]": 0.08027843400122947,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[true + true-ERROR_WITH_FORMULA-Error with formula: argument number 2 given to operator + was of type boolean but there are no possible types usable here.]": 0.08577649899962125,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[true < 1-ERROR_WITH_FORMULA-None]": 0.0781028849996801,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[true < true-ERROR_WITH_FORMULA-None]": 0.07751027999984217,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[true > 1-ERROR_WITH_FORMULA-None]": 0.08784594700409798,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[true > true-ERROR_WITH_FORMULA-None]": 0.08255601399650914,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_invalid_formulas[upper(1)-ERROR_WITH_FORMULA-Error with formula: argument number 1 given to function upper was of type number but the only usable type for this argument is text.]": 0.08410495399948559,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_complex_formulas[Can compare a date field and text with formatting-table_setup5-field('date')='02/01/2020'-expected5]": 0.12743714400130557,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_complex_formulas[Can compare a datetime field and text with eu formatting-table_setup6-field('date')='01/02/2020 00:10'-expected6]": 0.12154822399679688,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_complex_formulas[Can compare a phone number and number column-table_setup4-field('pn')=field('num')-expected4]": 0.13421183699756511,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_complex_formulas[Can reference and add to a integer column-table_setup0-field('number')+1-expected0]": 0.12443297700156108,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_complex_formulas[Can reference and add to a integer column-table_setup1-formula1-expected1]": 0.16069794099530554,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_complex_formulas[Can reference and if a phone number column-table_setup3-if(field('pn')='01772', field('pn'), 'no')-expected3]": 0.13931113299986464,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_complex_formulas[Can reference and if a text column-table_setup2-if(field('text')='a', field('text'), 'no')-expected2]": 0.13067427800342557,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_complex_formulas[Can use a boolean field in an if-table_setup8-if(field('boolean'), 'true', 'false')-expected8]": 0.1216375540025183,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_complex_formulas[Can use datediff on fields-table_setup7-date_diff('dd', field('date1'), field('date2'))-expected7]": 0.13383440800316748,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas['a' != 'a'-False]": 0.1062882019978133,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas['a' != 'b'-True]": 0.10903012700146064,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas['a' + 'b'-ab]": 0.1067711700052314,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas['a' = 'a'-True]": 0.11368777099778526,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas['https://\\u0909\\u0926\\u093e\\u0939\\u0930\\u0923.\\u092a\\u0930\\u0940\\u0915\\u094d\\u0937\\u093e'-https://\\u0909\\u0926\\u093e\\u0939\\u0930\\u0923.\\u092a\\u0930\\u0940\\u0915\\u094d\\u0937\\u093e]": 0.12104071100111469,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas['test'-test]": 0.11210431500148843,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[(10+2)/3-4.00000]": 0.10908921800364624,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[1 != '1'-False]": 0.11507346500366111,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[1 < 1-False]": 0.10402749199420214,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[1 <= 1-True]": 0.10682173399982275,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[1 = '1'-True]": 0.11593784999786294,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[1 > 1-False]": 0.11208833400087315,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[1 >= 1-True]": 0.10831602499456494,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[1+1-2]": 0.10988701799942646,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[1.2 * 2-2.4]": 0.11465475799923297,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[1/0-NaN]": 0.1133969229995273,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[10+10/2-15.00000]": 0.11450348400103394,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[10/3-3.33333]": 0.11177391299497685,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999+1-NaN]": 0.11298072000136017,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[CONCAT('\\ntest', '\\n')-\\ntest\\n]": 0.11598091199994087,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[CONCAT('a',2)-a2]": 0.11336335099622374,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[CONCAT('https://\\u0909\\u0926\\u093e\\u0939\\u0930\\u0923.\\u092a\\u0930\\u0940\\u0915\\u094d\\u0937\\u093e', '/api')-https://\\u0909\\u0926\\u093e\\u0939\\u0930\\u0923.\\u092a\\u0930\\u0940\\u0915\\u094d\\u0937\\u093e/api]": 0.11935978299879935,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[CONCAT('test', ' ', 'works')-test works]": 0.1190215359965805,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[CONCAT('test', ' ', UPPER('works'))-test WORKS]": 0.12155885599713656,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[CONCAT(1,2)-12]": 0.11216460900323,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[IF('a' = 'a', 'a', 'b')-a]": 0.11073115399995004,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[IF('a' = 'a', 1, 'b')-1]": 0.11894079299963778,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[IF('a' = 'b', 'a', 'b')-b]": 0.12077074400076526,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[IF('a' = 'b', 1, 'b')-b]": 0.1187796719968901,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[LOWER('HTTPS://\\u0909\\u0926\\u093e\\u0939\\u0930\\u0923.\\u092a\\u0930\\u0940\\u0915\\u094d\\u0937\\u093e')-https://\\u0909\\u0926\\u093e\\u0939\\u0930\\u0923.\\u092a\\u0930\\u0940\\u0915\\u094d\\u0937\\u093e]": 0.12034835100712371,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[LOWER('TEST')-test]": 0.11419117599871242,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[LOWER(UPPER('test'))-test0]": 0.11505560200021137,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[LOWER(UPPER('test'))-test1]": 0.11276711000027717,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[UPPER('https://\\u0909\\u0926\\u093e\\u0939\\u0930\\u0923.\\u092a\\u0930\\u0940\\u0915\\u094d\\u0937\\u093e')-HTTPS://\\u0909\\u0926\\u093e\\u0939\\u0930\\u0923.\\u092a\\u0930\\u0940\\u0915\\u094d\\u0937\\u093e]": 0.12067559799834271,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[UPPER('test')-TEST]": 0.10989955900367931,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[UPPER('tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt')-TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT]": 0.25287549199856585,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER(UPPER('test'))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))-TEST]": 0.2082099359977292,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[and(false, false)-False]": 0.10378225300155464,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[and(false, true)-False]": 0.10665248700024677,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[and(true, false)-False]": 0.10745526399841765,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[and(true, true)-True]": 0.22854292599731707,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[contains('a', '')-True]": 0.10984974700113526,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[contains('a', 'a')-True]": 0.10923289699712768,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[contains('a', 'x')-False]": 0.10868266200486687,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[date_diff('incorrect thingy', todate('20200101', 'YYYYMMDD'), todate('20100101', 'YYYYMMDD'))-NaN]": 0.11771761400086689,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[date_diff('yy', todate('20200101', 'YYYYMMDD'), todate('20100101', 'YYYYMMDD'))--10]": 0.12757109599988325,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[date_interval('1 invalid')-None]": 0.10157239699765341,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[date_interval('1 year') + todate('20200101', 'YYYYMMDD')-2021-01-01]": 0.10603540799638722,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[date_interval('1 year') - date_interval('1 day')-364 00:00:00]": 0.1057595099991886,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[date_interval('1 year') > date_interval('1 day')-True]": 0.1042274979990907,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[date_interval('1 year')-365 00:00:00]": 0.10298462200080394,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[day(todate('20170103','YYYYMMDD'))-3]": 0.11253356100132805,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[false-False]": 0.1018244520018925,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[if(1=1, todate('20200101', 'YYYYMMDD'), 'other')-2020-01-01]": 0.11342093999701319,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[isblank(' ')-False]": 0.10739556400221772,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[isblank('')-True]": 0.11607571999775246,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[isblank(1)-False]": 0.10387523700046586,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[left('a', 2)-a]": 0.11078108799847541,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[left('abc', 2)-ab]": 0.10756220700204722,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[length('')-0]": 0.11168174899648875,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[length('aaa')-3]": 0.11397990000114078,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[month(todate('20200601', 'YYYYMMDD') + (   todate('20200601', 'YYYYMMDD')    - todate('20100601', 'YYYYMMDD')))-6]": 0.11475207900366513,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[month(todate('20200601', 'YYYYMMDD') - date_interval('1 year'))-6]": 0.11823849500069628,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[not(false)-True]": 0.1051166489996831,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[not(isblank('')) != false-False]": 0.10985311300100875,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[not(isblank(tonumber('x')))-True]": 0.11019155899703037,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[not(true)-False]": 0.11035125899798004,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[or(false, false)-False]": 0.10709749400120927,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[or(false, true)-True]": 0.10417946799861966,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[or(true, false)-True]": 0.12151641399759683,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[or(true, true)-True]": 0.10284679299365962,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[replace('test test', 'test', 'a')-a a]": 0.10865276700133109,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[reverse('abc')-cba]": 0.1063330569959362,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[search('a', 'test')-0]": 0.115229568000359,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[search('test test', 'test')-1]": 0.10516063200338976,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[t('aaaa')-aaaa]": 0.10914124499686295,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[t(10)-]": 0.11277913200319745,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[todate('20170103','YYYYMMDD')-2017-01-03]": 0.10424006200264557,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[todate('20200101', 'YYYYMMDD') + date_interval('1 second')-2020-01-01]": 0.111843475002388,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[todate('20200101', 'YYYYMMDD') + date_interval('1 year')-2021-01-01]": 0.10473916999762878,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[todate('20200101', 'YYYYMMDD') - date_interval('1 year')-2019-01-01]": 0.11581243299588095,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[todate('20200101', 'YYYYMMDD') - todate('20210101', 'YYYYMMDD')--366 00:00:00]": 0.10784475899708923,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[todate('blah', 'YYYY')-None]": 0.10603165800057468,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[tonumber('-12.12345')--12.12345]": 0.10617485900002066,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[tonumber('1')-1.00000]": 0.10467058199719759,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[tonumber('9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999')+1-NaN]": 0.11670924200370791,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[tonumber('a')-NaN]": 0.1153073269961169,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[totext(1)-1]": 0.11517395399641828,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[totext(date_interval('1 year'))-1 year]": 0.11136929199710721,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[totext(todate('20200101', 'YYYYMMDD'))-2020-01-01]": 0.10935914499714272,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[totext(true)-true]": 0.1172862029998214,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[true != false-True]": 0.12019277800209238,
+    "tests/baserow/contrib/database/formula/test_baserow_formula_results.py::test_valid_formulas[true-True]": 0.10275806700155954,
+    "tests/baserow/contrib/database/formula/test_rename_field_references.py::test_can_replace_multiple_different_field_references": 0.001647215998673346,
+    "tests/baserow/contrib/database/formula/test_rename_field_references.py::test_doesnt_replace_unknown_field": 0.0017137809954874683,
+    "tests/baserow/contrib/database/formula/test_rename_field_references.py::test_leaves_unknown_field_references_along": 0.0010523679993639234,
+    "tests/baserow/contrib/database/formula/test_rename_field_references.py::test_raises_with_field_names_for_invalid_syntax": 0.002293820998602314,
+    "tests/baserow/contrib/database/formula/test_rename_field_references.py::test_replace_binary_op_keeping_whitespace_and_comments": 0.0016060899979493115,
+    "tests/baserow/contrib/database/formula/test_rename_field_references.py::test_replace_double_quote_field_ref_containing_double_quotes": 0.0011282510022283532,
+    "tests/baserow/contrib/database/formula/test_rename_field_references.py::test_replace_double_quote_field_ref_containing_single_quotes": 0.0012293309991946444,
+    "tests/baserow/contrib/database/formula/test_rename_field_references.py::test_replace_double_quoted_field_ref": 0.001569961998029612,
+    "tests/baserow/contrib/database/formula/test_rename_field_references.py::test_replace_field_reference_keeping_whitespace": 0.0013439150025078561,
+    "tests/baserow/contrib/database/formula/test_rename_field_references.py::test_replace_field_reference_keeping_whitespace_and_comments": 0.003069377999054268,
+    "tests/baserow/contrib/database/formula/test_rename_field_references.py::test_replace_field_reference_preserving_case": 0.002361950999329565,
+    "tests/baserow/contrib/database/formula/test_rename_field_references.py::test_replace_function_call_keeping_whitespace_and_comments": 0.002520005000405945,
+    "tests/baserow/contrib/database/formula/test_rename_field_references.py::test_replace_single_quoted_field_ref": 0.0012374360012472607,
+    "tests/baserow/contrib/database/formula/test_rename_field_references.py::test_replaces_field_with_double_quotes_with_id": 0.0011474460006866138,
+    "tests/baserow/contrib/database/formula/test_rename_field_references.py::test_replaces_field_with_field_by_id": 0.001015320001897635,
+    "tests/baserow/contrib/database/formula/test_rename_field_references.py::test_replaces_field_with_single_quotes_with_id": 0.00107702399691334,
+    "tests/baserow/contrib/database/formula/test_rename_field_references.py::test_replaces_functions_preserving_case": 0.0016700990017852746,
+    "tests/baserow/contrib/database/formula/test_rename_field_references.py::test_replaces_known_field_by_id": 0.0016032340026868042,
+    "tests/baserow/contrib/database/formula/test_rename_field_references.py::test_replaces_known_field_by_id_double_quotes": 0.0011712220002664253,
+    "tests/baserow/contrib/database/formula/test_rename_field_references.py::test_replaces_known_field_by_id_single_quotes": 0.0010206580045633018,
+    "tests/baserow/contrib/database/formula/test_rename_field_references.py::test_replaces_lookup": 0.0013575820012192708,
+    "tests/baserow/contrib/database/formula/test_rename_field_references.py::test_replaces_lookup_when_via_changes": 0.0016018900059862062,
+    "tests/baserow/contrib/database/formula/test_rename_field_references.py::test_replaces_unknown_field_by_id_with_field": 0.0010275710010319017,
+    "tests/baserow/contrib/database/formula/test_rename_field_references.py::test_replaces_unknown_field_by_id_with_field_multiple": 0.0016595489978499245,
+    "tests/baserow/contrib/database/management/test_copy_tables.py::test_a_batch_size_one_more_than_the_number_of_tables_runs_two_batches": 0.0008161240002664272,
+    "tests/baserow/contrib/database/management/test_copy_tables.py::test_a_batch_size_the_same_as_the_number_of_tables_runs_one_batch": 0.0009660159994382411,
+    "tests/baserow/contrib/database/management/test_copy_tables.py::test_a_batch_with_some_tables_ignored_wont_merge_with_the_next_batch": 0.0009234880017174874,
+    "tests/baserow/contrib/database/management/test_copy_tables.py::test_a_table_already_in_the_target_db_is_not_in_the_command": 0.0011664720041153487,
+    "tests/baserow/contrib/database/management/test_copy_tables.py::test_the_final_batch_includes_all_remaining_tables": 0.0010268910009472165,
+    "tests/baserow/contrib/database/management/test_fill_table.py::test_fill_table_fields": 0.2998870849951345,
+    "tests/baserow/contrib/database/management/test_fill_table.py::test_fill_table_fields_with_add_all_fields": 0.713565963000292,
+    "tests/baserow/contrib/database/management/test_fill_table.py::test_fill_table_rows_empty_table[10]": 0.0964451600011671,
+    "tests/baserow/contrib/database/management/test_fill_table.py::test_fill_table_rows_empty_table[5]": 0.1014231170011044,
+    "tests/baserow/contrib/database/management/test_fill_table.py::test_fill_table_rows_no_empty_table[10]": 0.10293895499853534,
+    "tests/baserow/contrib/database/management/test_fill_table.py::test_fill_table_rows_no_empty_table[5]": 0.09829056799935643,
+    "tests/baserow/contrib/database/management/test_fill_table.py::test_fill_table_rows_no_table": 0.008522109001205536,
+    "tests/baserow/contrib/database/migrations/test_add_and_move_public_flags.py::test_backwards_migration": 3.1577742480039888,
+    "tests/baserow/contrib/database/migrations/test_add_and_move_public_flags.py::test_forwards_migration": 2.8628256830015744,
+    "tests/baserow/contrib/database/migrations/test_add_and_move_public_flags.py::test_multi_batch_forwards_migration": 2.9341845120034122,
+    "tests/baserow/contrib/database/migrations/test_field_dependencies_migration.py::test_backwards_migration": 4.245335350002279,
+    "tests/baserow/contrib/database/migrations/test_field_dependencies_migration.py::test_forwards_migration": 4.306943578998471,
+    "tests/baserow/contrib/database/migrations/test_fix_hanging_formula_fields_migration.py::test_forwards_migration": 0.9581023899991123,
+    "tests/baserow/contrib/database/migrations/test_fixed_trashed_field_dependencies_migration.py::test_forwards_migration": 2.4234628300037,
+    "tests/baserow/contrib/database/migrations/test_remove_field_by_id_migration.py::test_backwards_migration": 5.444408576997375,
+    "tests/baserow/contrib/database/migrations/test_remove_field_by_id_migration.py::test_forwards_migration": 3.445366104999266,
+    "tests/baserow/contrib/database/migrations/test_remove_multiselect_missing_options.py::test_forwards_migration": 3.1921899219996703,
+    "tests/baserow/contrib/database/migrations/test_unique_field_names_migration.py::test_backwards_migration_restores_field_names": 6.176184419997298,
+    "tests/baserow/contrib/database/migrations/test_unique_field_names_migration.py::test_migration_fixes_duplicate_field_names": 6.594768871000269,
+    "tests/baserow/contrib/database/migrations/test_unique_field_names_migration.py::test_migration_fixes_duplicate_field_names_and_reserved_names": 6.420055753998895,
+    "tests/baserow/contrib/database/migrations/test_unique_field_names_migration.py::test_migration_handles_existing_fields_with_underscore_number": 6.339773437000986,
+    "tests/baserow/contrib/database/rows/test_row_metadata_registry.py::test_merges_together_row_metadata_by_type_and_row_id": 0.0008679029997438192,
+    "tests/baserow/contrib/database/rows/test_row_metadata_registry.py::test_nothing_registered_returns_empty_even_when_rows_provided": 0.000804121998953633,
+    "tests/baserow/contrib/database/rows/test_row_webhook_event_types.py::test_row_created_event_type": 0.08264526299899444,
+    "tests/baserow/contrib/database/rows/test_row_webhook_event_types.py::test_row_deleted_event_type": 0.08038528300312464,
+    "tests/baserow/contrib/database/rows/test_row_webhook_event_types.py::test_row_updated_event_type": 0.08047714499844005,
+    "tests/baserow/contrib/database/rows/test_rows_handler.py::test_create_row": 0.22676620500715217,
+    "tests/baserow/contrib/database/rows/test_rows_handler.py::test_delete_row": 0.15482597499794792,
+    "tests/baserow/contrib/database/rows/test_rows_handler.py::test_extract_field_ids_from_string": 0.0008105529959721025,
+    "tests/baserow/contrib/database/rows/test_rows_handler.py::test_extract_manytomany_values": 0.005149810996954329,
+    "tests/baserow/contrib/database/rows/test_rows_handler.py::test_get_field_ids_from_dict": 0.0008451880057691596,
+    "tests/baserow/contrib/database/rows/test_rows_handler.py::test_get_include_exclude_fields": 0.039844130998972105,
+    "tests/baserow/contrib/database/rows/test_rows_handler.py::test_get_include_exclude_fields_with_user_field_names": 0.04050452400042559,
+    "tests/baserow/contrib/database/rows/test_rows_handler.py::test_get_row": 0.15074964200539398,
+    "tests/baserow/contrib/database/rows/test_rows_handler.py::test_has_row": 0.14967846799845574,
+    "tests/baserow/contrib/database/rows/test_rows_handler.py::test_move_row": 0.14469994999672053,
+    "tests/baserow/contrib/database/rows/test_rows_handler.py::test_restore_row": 0.11673740199694294,
+    "tests/baserow/contrib/database/rows/test_rows_handler.py::test_update_row": 0.1610925219974888,
+    "tests/baserow/contrib/database/table/test_table_handler.py::test_create_database_table": 0.14213519999975688,
+    "tests/baserow/contrib/database/table/test_table_handler.py::test_delete_database_table": 0.12141560500094783,
+    "tests/baserow/contrib/database/table/test_table_handler.py::test_deleting_a_table_breaks_dependant_fields_and_sends_updates_for_them": 0.23267239599954337,
+    "tests/baserow/contrib/database/table/test_table_handler.py::test_deleting_table_trashes_all_fields_and_any_related_links": 0.4298572179977782,
+    "tests/baserow/contrib/database/table/test_table_handler.py::test_fill_example_table_data": 0.12220887600051356,
+    "tests/baserow/contrib/database/table/test_table_handler.py::test_fill_table_with_initial_data": 0.20778561899714987,
+    "tests/baserow/contrib/database/table/test_table_handler.py::test_get_database_table": 0.09148263200040674,
+    "tests/baserow/contrib/database/table/test_table_handler.py::test_order_tables": 0.14100845199936884,
+    "tests/baserow/contrib/database/table/test_table_handler.py::test_restoring_a_table_restores_fields_and_related_fields": 0.27646440700118546,
+    "tests/baserow/contrib/database/table/test_table_handler.py::test_restoring_table_with_a_previously_trashed_field_leaves_the_field_trashed": 0.28070958700118354,
+    "tests/baserow/contrib/database/table/test_table_handler.py::test_update_database_table": 0.11693661699609947,
+    "tests/baserow/contrib/database/table/test_table_models.py::test_enhance_by_fields_queryset": 0.025518204001855338,
+    "tests/baserow/contrib/database/table/test_table_models.py::test_filter_by_fields_object_queryset": 0.05008161600198946,
+    "tests/baserow/contrib/database/table/test_table_models.py::test_get_table_model": 0.059990449000906665,
+    "tests/baserow/contrib/database/table/test_table_models.py::test_get_table_model_to_str": 0.0344297949995962,
+    "tests/baserow/contrib/database/table/test_table_models.py::test_group_user_get_next_order": 0.026181412002188154,
+    "tests/baserow/contrib/database/table/test_table_models.py::test_order_by_fields_string_queryset": 0.1170088120015862,
+    "tests/baserow/contrib/database/table/test_table_models.py::test_order_by_fields_string_queryset_with_user_field_names": 0.07260285500160535,
+    "tests/baserow/contrib/database/table/test_table_models.py::test_search_all_fields_queryset": 0.10530895199917722,
+    "tests/baserow/contrib/database/table/test_table_models.py::test_table_model_fields_requiring_refresh_after_update": 0.0297694959990622,
+    "tests/baserow/contrib/database/table/test_table_models.py::test_table_model_fields_requiring_refresh_on_insert": 0.03742265000255429,
+    "tests/baserow/contrib/database/test_database_application_type.py::test_import_export_database": 0.11238028699881397,
+    "tests/baserow/contrib/database/tokens/test_token_handler.py::test_check_table_permissions": 0.30097156299234484,
+    "tests/baserow/contrib/database/tokens/test_token_handler.py::test_create_token": 0.12326924700391828,
+    "tests/baserow/contrib/database/tokens/test_token_handler.py::test_delete_token": 0.12920054599817377,
+    "tests/baserow/contrib/database/tokens/test_token_handler.py::test_generate_token": 0.09770301499884226,
+    "tests/baserow/contrib/database/tokens/test_token_handler.py::test_get_by_key": 0.11236546300642658,
+    "tests/baserow/contrib/database/tokens/test_token_handler.py::test_get_token": 0.12579134000043268,
+    "tests/baserow/contrib/database/tokens/test_token_handler.py::test_has_table_permission": 0.3343288210016908,
+    "tests/baserow/contrib/database/tokens/test_token_handler.py::test_rotate_token_key": 0.1184437390002131,
+    "tests/baserow/contrib/database/tokens/test_token_handler.py::test_update_token": 0.11541600900090998,
+    "tests/baserow/contrib/database/tokens/test_token_handler.py::test_update_token_permission": 0.13706440900205052,
+    "tests/baserow/contrib/database/tokens/test_token_handler.py::test_update_token_usage": 0.08018560899654403,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_a_parent_id_must_be_provided_when_trashing_or_restoring_a_row": 0.09285493100469466,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_a_parent_id_must_not_be_provided_when_trashing_or_restoring_an_app": 0.06718578300569789,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_a_restored_field_will_have_its_name_changed_to_ensure_it_is_unique": 0.42537707800147473,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_a_trashed_linked_row_pointing_at_a_trashed_row_is_restored_correctly": 0.32061351199808996,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_can_delete_applications_and_rows_in_the_same_perm_delete_batch": 0.14902877699933015,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_can_delete_fields_and_rows_in_the_same_perm_delete_batch": 0.16786849900017842,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_can_delete_tables_and_rows_in_the_same_perm_delete_batch": 0.1534726900026726,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_can_perm_delete_tables": 0.7289579179996508,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_can_trash_row_with_blank_primary_file_field": 0.08432986000116216,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_can_trash_row_with_blank_primary_single_select": 0.08373118199961027,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_cant_delete_row_perm_without_tableid": 0.0977955269991071,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_delete_row": 0.09474416200464475,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_delete_row_perm": 0.0997067700009211,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_perm_delete_field": 0.09878361500159372,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_perm_delete_link_row_field": 0.21709899300185498,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_perm_delete_lookup_row_field": 0.3758315589984704,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_perm_delete_related_link_row_field": 0.2054349390018615,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_perm_delete_table": 0.08311656799924094,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_perm_delete_table_and_related_link_row_field": 0.27435808700101916,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_perm_deleting_many_rows_at_once_only_looks_up_the_model_once": 0.12027008099903469,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_restoring_a_trashed_link_field_restores_the_opposing_field_also": 0.21864359700339264,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_trashed_row_entry_extra_description_is_unnamed_when_no_value_pk": 0.08541731299919775,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_trashed_row_entry_includes_the_rows_primary_key_value_as_an_extra_description": 0.08891813199807075,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_trashing_a_field_with_a_filter_trashes_the_filter": 0.12962901299761143,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_trashing_a_field_with_a_sort_trashes_the_sort": 0.12813068699688301,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_trashing_a_row_hides_it_from_a_link_row_field_pointing_at_it": 0.2680312769989541,
+    "tests/baserow/contrib/database/trash/test_database_trash_types.py::test_trashing_a_table_with_link_fields_pointing_at_it_also_trashes_those_fields": 0.23726034899664228,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_boolean_filter_type": 0.09314264400018146,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_can_mix_field_types_and_callables_in_compatible_field_types": 0.03465879499708535,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_can_use_a_callable_in_compatible_field_types": 0.039806060995033477,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_contains_filter_type": 0.2006056910031475,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_contains_not_filter_type": 0.17195546099901549,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_date_after_filter_type": 0.0821279189985944,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_date_before_filter_type": 0.0921225649981352,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_date_day_month_year_filter_type": 0.11131056300655473,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_date_equal_filter_type": 0.10212339400095516,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_date_equals_day_of_month_filter_type": 0.12242770699958783,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_date_not_equal_filter_type": 0.10831390800012741,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_date_parser_mixin": 0.000857010996696772,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_empty_filter_type": 0.3042519769987848,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_equal_filter_type": 0.11842489399714395,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_filename_contains_filter_type": 0.09886952799934079,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_has_file_type": 0.08774609100146336,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_higher_than_filter_type": 0.10722797799826367,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_last_modified_date_equal_filter_type": 0.12883017000422115,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_last_modified_day_filter_type": 0.2059596950057312,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_last_modified_month_filter_type": 0.1608664079940354,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_last_modified_year_filter_type": 0.15300500099692727,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_length_is_lower_than_filter_type": 0.10620522400131449,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_link_row_has_filter_type": 0.206618914999126,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_link_row_has_not_filter_type": 0.22501945000112755,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_link_row_preload_values": 0.18105953199847136,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_lower_than_filter_type": 0.10472267699879012,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_multiple_select_has_filter_type": 0.14634874900002615,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_multiple_select_has_filter_type_export_import": 0.003970462999859592,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_multiple_select_has_not_filter_type": 0.15416503000233206,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_not_empty_filter_type": 0.30021176199807087,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_not_equal_filter_type": 0.13237587500043446,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_single_select_equal_filter_type": 0.0846742340036144,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_single_select_equal_filter_type_export_import": 0.0039250379959412385,
+    "tests/baserow/contrib/database/view/test_view_filters.py::test_single_select_not_equal_filter_type": 0.08896216400171397,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_apply_filters": 0.10788073499861639,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_apply_sortings": 0.11461946000054013,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_create_filter": 0.14262885700372863,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_create_form_view": 0.19531868299964117,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_create_grid_view": 0.13857273399844416,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_create_sort": 0.17232833099842537,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_delete_filter": 0.1036397730022145,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_delete_form_view": 0.09064433600724442,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_delete_grid_view": 0.12280264199944213,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_delete_sort": 0.09816297799625318,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_delete_view": 0.13421997200202895,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_enable_form_view_file_field": 0.07605773999966914,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_field_type_changed": 0.16467625699806376,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_get_filter": 0.13425086999632185,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_get_public_view_by_slug": 0.13742334299968206,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_get_public_views_which_include_row": 0.11014196299947798,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_get_sort": 0.1465922879979189,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_get_view": 0.14284267000402906,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_order_views": 0.1408833470013633,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_public_view_row_checker_caches_when_only_unfiltered_fields_updated": 0.08762302800096222,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_public_view_row_checker_does_not_cache_when_any_filtered_fields_updated": 0.09490771100172424,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_public_view_row_checker_includes_public_views_with_no_filters_with_no_queries": 0.09638960500524263,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_public_view_row_checker_runs_expected_queries_on_init": 0.09439595900039421,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_public_view_row_checker_runs_expected_queries_when_checking_rows": 0.09254271499958122,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_rotate_view_slug": 0.13327188000039314,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_submit_form_view": 0.05547137499524979,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_trashed_fields_are_not_included_in_grid_view_field_options": 0.08752861100219889,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_update_field_options": 0.171099420003884,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_update_filter": 0.1496533800054749,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_update_form_view": 0.18754136500137975,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_update_grid_view": 0.1290181240037782,
+    "tests/baserow/contrib/database/view/test_view_handler.py::test_update_sort": 0.1787991029996192,
+    "tests/baserow/contrib/database/view/test_view_models.py::test_rotate_view_slug": 0.020555585997499293,
+    "tests/baserow/contrib/database/view/test_view_models.py::test_view_get_field_options": 0.05497197400109144,
+    "tests/baserow/contrib/database/view/test_view_types.py::test_convert_card_cover_image_field_deleted": 0.08921796600407106,
+    "tests/baserow/contrib/database/view/test_view_types.py::test_convert_card_cover_image_field_to_another": 0.1021778060021461,
+    "tests/baserow/contrib/database/view/test_view_types.py::test_import_export_form_view": 0.08287754699995276,
+    "tests/baserow/contrib/database/view/test_view_types.py::test_import_export_gallery_view": 0.08687492100216332,
+    "tests/baserow/contrib/database/view/test_view_types.py::test_import_export_grid_view": 0.03848212999946554,
+    "tests/baserow/contrib/database/view/test_view_types.py::test_newly_created_gallery_view": 0.0951085279994004,
+    "tests/baserow/contrib/database/webhooks/test_webhook_handler.py::test_clean_webhook_calls": 0.02669710999907693,
+    "tests/baserow/contrib/database/webhooks/test_webhook_handler.py::test_create_webhook": 0.657179163001274,
+    "tests/baserow/contrib/database/webhooks/test_webhook_handler.py::test_delete_webhook": 0.12621436600238667,
+    "tests/baserow/contrib/database/webhooks/test_webhook_handler.py::test_find_webhooks_to_call": 0.04044353700373904,
+    "tests/baserow/contrib/database/webhooks/test_webhook_handler.py::test_get_all_table_webhooks": 0.1380431370016595,
+    "tests/baserow/contrib/database/webhooks/test_webhook_handler.py::test_get_webhook": 0.12239641899941489,
+    "tests/baserow/contrib/database/webhooks/test_webhook_handler.py::test_trigger_test_call": 0.1278186689960421,
+    "tests/baserow/contrib/database/webhooks/test_webhook_handler.py::test_update_webhook": 0.6982647259974328,
+    "tests/baserow/contrib/database/webhooks/test_webhook_models.py::test_header_validation": 0.5372012249972613,
+    "tests/baserow/contrib/database/webhooks/test_webhook_registries.py::test_signal_listener": 0.5854930930036062,
+    "tests/baserow/contrib/database/webhooks/test_webhook_tasks.py::test_call_webhook": 0.6144145339967508,
+    "tests/baserow/contrib/database/ws/public/test_public_ws_fields_signals.py::test_when_field_created_public_views_are_sent_field_created_with_restricted_related": 0.6984492399969895,
+    "tests/baserow/contrib/database/ws/public/test_public_ws_fields_signals.py::test_when_field_deleted_public_views_are_field_deleted_with_restricted_related": 0.6820015349985624,
+    "tests/baserow/contrib/database/ws/public/test_public_ws_fields_signals.py::test_when_field_restored_public_views_sent_event_with_restricted_related_fields": 0.7191184389994305,
+    "tests/baserow/contrib/database/ws/public/test_public_ws_fields_signals.py::test_when_field_updated_public_views_are_sent_event_with_restricted_related": 0.7352352119996794,
+    "tests/baserow/contrib/database/ws/public/test_public_ws_rows_signals.py::test_given_row_invisible_in_public_view_when_moved_no_update_sent": 0.6547399340015545,
+    "tests/baserow/contrib/database/ws/public/test_public_ws_rows_signals.py::test_given_row_not_visible_in_public_view_when_updated_to_be_visible_event_sent": 0.6668575709991273,
+    "tests/baserow/contrib/database/ws/public/test_public_ws_rows_signals.py::test_given_row_visible_in_public_view_when_moved_row_updated_sent": 0.5904162459955842,
+    "tests/baserow/contrib/database/ws/public/test_public_ws_rows_signals.py::test_given_row_visible_in_public_view_when_updated_to_be_not_visible_event_sent": 0.6374463799984369,
+    "tests/baserow/contrib/database/ws/public/test_public_ws_rows_signals.py::test_given_row_visible_in_public_view_when_updated_to_still_be_visible_event_sent": 0.6773236419976456,
+    "tests/baserow/contrib/database/ws/public/test_public_ws_rows_signals.py::test_when_row_created_public_views_receive_restricted_row_created_ws_event": 0.5929559100040933,
+    "tests/baserow/contrib/database/ws/public/test_public_ws_rows_signals.py::test_when_row_created_public_views_receive_row_created_only_when_filters_match": 0.6889783089973207,
+    "tests/baserow/contrib/database/ws/public/test_public_ws_rows_signals.py::test_when_row_deleted_public_views_receive_restricted_row_deleted_ws_event": 0.6233556069964834,
+    "tests/baserow/contrib/database/ws/public/test_public_ws_rows_signals.py::test_when_row_deleted_public_views_receive_row_deleted_only_when_filters_match": 0.6621182020026026,
+    "tests/baserow/contrib/database/ws/public/test_public_ws_rows_signals.py::test_when_row_restored_public_views_receive_restricted_row_created_ws_event": 0.6161719039992022,
+    "tests/baserow/contrib/database/ws/public/test_public_ws_rows_signals.py::test_when_row_restored_public_views_receive_row_created_only_when_filters_match": 0.7080331929973909,
+    "tests/baserow/contrib/database/ws/public/test_public_ws_view_signals.py::test_when_field_hidden_in_public_view_field_force_refresh_sent": 0.5828077940022922,
+    "tests/baserow/contrib/database/ws/public/test_public_ws_view_signals.py::test_when_field_unhidden_in_public_view_force_refresh_sent": 0.6459413560005487,
+    "tests/baserow/contrib/database/ws/public/test_public_ws_view_signals.py::test_when_only_field_options_updated_in_public_grid_view_force_refresh_sent": 0.6040824100018654,
+    "tests/baserow/contrib/database/ws/public/test_public_ws_view_signals.py::test_when_view_filter_created_for_public_view_force_refresh_sent": 0.5983676199975889,
+    "tests/baserow/contrib/database/ws/public/test_public_ws_view_signals.py::test_when_view_filter_deleted_for_public_view_force_refresh_event_sent": 0.646215270000539,
+    "tests/baserow/contrib/database/ws/public/test_public_ws_view_signals.py::test_when_view_filter_updated_for_public_view_force_refresh_event_sent": 0.6044446720006817,
+    "tests/baserow/contrib/database/ws/test_ws_fields_signals.py::test_field_created": 0.5536125540020294,
+    "tests/baserow/contrib/database/ws/test_ws_fields_signals.py::test_field_deleted": 0.6439217840015772,
+    "tests/baserow/contrib/database/ws/test_ws_fields_signals.py::test_field_restored": 0.6830584630042722,
+    "tests/baserow/contrib/database/ws/test_ws_fields_signals.py::test_field_restored_doesnt_do_n_plus_some_queries": 0.9676993550019688,
+    "tests/baserow/contrib/database/ws/test_ws_fields_signals.py::test_field_updated": 0.603592823001236,
+    "tests/baserow/contrib/database/ws/test_ws_rows_signals.py::test_populates_with_row_id_metadata": 0.0008048630006669555,
+    "tests/baserow/contrib/database/ws/test_ws_rows_signals.py::test_row_created": 0.5925468830027967,
+    "tests/baserow/contrib/database/ws/test_ws_rows_signals.py::test_row_created_with_metadata": 0.644433545996435,
+    "tests/baserow/contrib/database/ws/test_ws_rows_signals.py::test_row_deleted": 0.6248354689996631,
+    "tests/baserow/contrib/database/ws/test_ws_rows_signals.py::test_row_updated": 0.5936943989981955,
+    "tests/baserow/contrib/database/ws/test_ws_rows_signals.py::test_row_updated_with_metadata": 0.628945954998926,
+    "tests/baserow/contrib/database/ws/test_ws_table_signals.py::test_table_created": 0.5707974309989368,
+    "tests/baserow/contrib/database/ws/test_ws_table_signals.py::test_table_deleted": 0.6099812510001357,
+    "tests/baserow/contrib/database/ws/test_ws_table_signals.py::test_table_updated": 0.6306453399993188,
+    "tests/baserow/contrib/database/ws/test_ws_table_signals.py::test_tables_reordered": 0.5430184890028613,
+    "tests/baserow/contrib/database/ws/test_ws_view_signals.py::test_view_created": 0.6102939270022034,
+    "tests/baserow/contrib/database/ws/test_ws_view_signals.py::test_view_deleted": 0.6588476860051742,
+    "tests/baserow/contrib/database/ws/test_ws_view_signals.py::test_view_field_options_updated": 0.590165915000398,
+    "tests/baserow/contrib/database/ws/test_ws_view_signals.py::test_view_filter_created": 0.6346027579966176,
+    "tests/baserow/contrib/database/ws/test_ws_view_signals.py::test_view_filter_deleted": 0.5932950750029704,
+    "tests/baserow/contrib/database/ws/test_ws_view_signals.py::test_view_filter_updated": 0.5990396960005455,
+    "tests/baserow/contrib/database/ws/test_ws_view_signals.py::test_view_sort_created": 0.6455343229972641,
+    "tests/baserow/contrib/database/ws/test_ws_view_signals.py::test_view_sort_deleted": 0.6418277150005451,
+    "tests/baserow/contrib/database/ws/test_ws_view_signals.py::test_view_sort_updated": 0.5508354509984201,
+    "tests/baserow/contrib/database/ws/test_ws_view_signals.py::test_view_updated": 0.5854573760007042,
+    "tests/baserow/contrib/database/ws/test_ws_view_signals.py::test_views_reordered": 0.5566093139968871,
+    "tests/baserow/core/management/test_backup_runner.py::test_backup_baserow_does_no_table_batches_when_no_user_tables_found": 0.026912584002275253,
+    "tests/baserow/core/management/test_backup_runner.py::test_backup_baserow_dumps_database_in_batches": 0.11053236099905916,
+    "tests/baserow/core/management/test_backup_runner.py::test_backup_baserow_includes_all_tables_when_batch_size_matches_num_tables": 0.0258023360001971,
+    "tests/baserow/core/management/test_backup_runner.py::test_backup_baserow_table_batches_includes_all_tables_when_final_batch_small": 0.025930197996785864,
+    "tests/baserow/core/management/test_backup_runner.py::test_can_backup_and_restore_baserow_reverting_changes": 15.969413112001348,
+    "tests/baserow/core/management/test_backup_runner.py::test_can_change_num_jobs_and_insert_extra_args_for_baserow_backup": 0.02541104100237135,
+    "tests/baserow/core/management/test_backup_runner.py::test_restore_baserow_only_does_first_restore_if_no_user_tables": 0.010179372995480662,
+    "tests/baserow/core/management/test_backup_runner.py::test_restore_baserow_passes_extra_args_to_all_pg_restores_and_can_set_jobs": 0.013506477003829787,
+    "tests/baserow/core/management/test_backup_runner.py::test_restore_baserow_raises_exception_if_sub_folder_not_found_after_extract": 0.010046233994216891,
+    "tests/baserow/core/management/test_backup_runner.py::test_restore_baserow_restores_contained_dumps_in_batches": 0.010871413000131724,
+    "tests/baserow/core/migrations/test_fix_trash_constraint.py::test_migration_doesnt_fail_if_duplicate_entries_present_with_parent_id": 1.1343691219954053,
+    "tests/baserow/core/migrations/test_fix_trash_constraint.py::test_migration_doesnt_fail_if_duplicate_entries_present_without_parent_id": 1.3474722999999358,
+    "tests/baserow/core/test_core_applications.py::test_application_get_api_urls": 0.0007785529960528947,
+    "tests/baserow/core/test_core_applications.py::test_application_registry_get": 0.0008205009980883915,
+    "tests/baserow/core/test_core_applications.py::test_application_registry_register": 0.0008148909982992336,
+    "tests/baserow/core/test_core_db.py::test_locked_atomic_transaction": 0.0044997980003245175,
+    "tests/baserow/core/test_core_emails.py::test_base_email_message": 0.009651500000472879,
+    "tests/baserow/core/test_core_handler.py::test_accept_group_invitation": 0.26923468700260855,
+    "tests/baserow/core/test_core_handler.py::test_create_database_application": 0.12208251699848915,
+    "tests/baserow/core/test_core_handler.py::test_create_group": 0.06290209300277638,
+    "tests/baserow/core/test_core_handler.py::test_create_group_invitation": 0.17493936900064,
+    "tests/baserow/core/test_core_handler.py::test_delete_database_application": 0.12432106699998258,
+    "tests/baserow/core/test_core_handler.py::test_delete_group": 0.1314402189964312,
+    "tests/baserow/core/test_core_handler.py::test_delete_group_invitation": 0.11103900000307476,
+    "tests/baserow/core/test_core_handler.py::test_delete_group_user": 0.1636536639998667,
+    "tests/baserow/core/test_core_handler.py::test_export_import_group_application": 0.029664207002497278,
+    "tests/baserow/core/test_core_handler.py::test_get_application": 0.11117617799754953,
+    "tests/baserow/core/test_core_handler.py::test_get_group": 0.10985382199942251,
+    "tests/baserow/core/test_core_handler.py::test_get_group_invitation": 0.21192762300051982,
+    "tests/baserow/core/test_core_handler.py::test_get_group_invitation_by_token": 0.11346787599904928,
+    "tests/baserow/core/test_core_handler.py::test_get_group_user": 0.11610425300386851,
+    "tests/baserow/core/test_core_handler.py::test_get_settings": 0.004139058997679967,
+    "tests/baserow/core/test_core_handler.py::test_get_template": 0.06087272600416327,
+    "tests/baserow/core/test_core_handler.py::test_install_template": 0.3849930400028825,
+    "tests/baserow/core/test_core_handler.py::test_leave_group": 0.22125879099985468,
+    "tests/baserow/core/test_core_handler.py::test_order_applications": 0.12732515100287856,
+    "tests/baserow/core/test_core_handler.py::test_order_groups": 0.07089557599829277,
+    "tests/baserow/core/test_core_handler.py::test_reject_group_invitation": 0.16486689699740964,
+    "tests/baserow/core/test_core_handler.py::test_restore_application": 0.0667716130046756,
+    "tests/baserow/core/test_core_handler.py::test_restore_group": 0.06962363599814125,
+    "tests/baserow/core/test_core_handler.py::test_send_group_invitation_email": 0.5898950240007252,
+    "tests/baserow/core/test_core_handler.py::test_send_group_invitation_email_in_different_language": 0.6119825779969688,
+    "tests/baserow/core/test_core_handler.py::test_sync_and_install_all_templates": 58.52753264500279,
+    "tests/baserow/core/test_core_handler.py::test_sync_templates": 0.32755387899669586,
+    "tests/baserow/core/test_core_handler.py::test_update_database_application": 0.11374096999861649,
+    "tests/baserow/core/test_core_handler.py::test_update_group": 0.11242015699463082,
+    "tests/baserow/core/test_core_handler.py::test_update_group_invitation": 0.11909680599637795,
+    "tests/baserow/core/test_core_handler.py::test_update_group_user": 0.1623596940007701,
+    "tests/baserow/core/test_core_handler.py::test_update_settings": 0.11464017899925238,
+    "tests/baserow/core/test_core_mixins.py::test_cant_define_model_with_multiple_parents_with_poly_mixin": 0.006630734002101235,
+    "tests/baserow/core/test_core_mixins.py::test_get_all_parents_and_self_with_one_level_of_inheritance": 0.008566881995648146,
+    "tests/baserow/core/test_core_mixins.py::test_get_all_parents_and_self_with_single_model": 0.006856656000309158,
+    "tests/baserow/core/test_core_mixins.py::test_get_all_parents_and_self_with_two_levels_of_inheritance": 0.009020644996780902,
+    "tests/baserow/core/test_core_models.py::test_application_content_type_init": 0.009985417997086188,
+    "tests/baserow/core/test_core_models.py::test_created_and_updated_on_mixin": 0.03647177199673024,
+    "tests/baserow/core/test_core_models.py::test_group_has_user": 0.22278663999532,
+    "tests/baserow/core/test_core_models.py::test_group_user_get_next_order": 0.16515225800321787,
+    "tests/baserow/core/test_core_registry.py::test_api_exceptions_api_mixins": 0.0012554089989862405,
+    "tests/baserow/core/test_core_registry.py::test_get_serializer": 0.008793659999355441,
+    "tests/baserow/core/test_core_registry.py::test_registry": 0.0008723200007807463,
+    "tests/baserow/core/test_core_registry.py::test_registry_get": 0.000930599999264814,
+    "tests/baserow/core/test_core_registry.py::test_registry_get_by_model_returns_the_most_specific_value": 0.0011881730024470016,
+    "tests/baserow/core/test_core_registry.py::test_registry_register": 0.0008451280009467155,
+    "tests/baserow/core/test_core_utils.py::test_dict_to_object": 0.0008740329976717476,
+    "tests/baserow/core/test_core_utils.py::test_extract_allowed": 0.0008481440017931163,
+    "tests/baserow/core/test_core_utils.py::test_random_string": 0.0020111810008529574,
+    "tests/baserow/core/test_core_utils.py::test_remove_special_characters": 0.0008807549966149963,
+    "tests/baserow/core/test_core_utils.py::test_set_allowed_attrs": 0.0007922499971755315,
+    "tests/baserow/core/test_core_utils.py::test_sha256_hash": 0.0007909760024631396,
+    "tests/baserow/core/test_core_utils.py::test_split_comma_separated_string": 0.0007767889983369969,
+    "tests/baserow/core/test_core_utils.py::test_stream_size": 0.0007655289955437183,
+    "tests/baserow/core/test_core_utils.py::test_to_pascal_case": 0.0007740940018265974,
+    "tests/baserow/core/test_core_utils.py::test_to_snake_case": 0.0007694369960518088,
+    "tests/baserow/core/test_core_utils.py::test_truncate_middle": 0.0007917080001789145,
+    "tests/baserow/core/test_core_validators.py::test_max_length_validator_help_text": 0.0007631539956491906,
+    "tests/baserow/core/test_core_validators.py::test_max_length_validator_validate": 0.0008273240018752404,
+    "tests/baserow/core/trash/test_trash_handler.py::test_a_group_marked_for_perm_deletion_no_longer_shows_up_in_trash_structure": 0.07342177399914362,
+    "tests/baserow/core/trash/test_trash_handler.py::test_a_group_marked_for_perm_deletion_raises_a_404_when_asked_for_trash_contents": 0.08054747500136727,
+    "tests/baserow/core/trash/test_trash_handler.py::test_a_trash_entry_marked_for_permanent_deletion_gets_deleted_by_task": 0.09964143599790987,
+    "tests/baserow/core/trash/test_trash_handler.py::test_a_trash_entry_older_than_setting_gets_marked_for_permanent_deletion": 0.09916717399755726,
+    "tests/baserow/core/trash/test_trash_handler.py::test_a_trashed_app_shows_up_in_trash_structure": 0.08422898700155201,
+    "tests/baserow/core/trash/test_trash_handler.py::test_an_app_marked_for_perm_deletion_no_longer_shows_up_in_trash_structure": 0.0859317869944789,
+    "tests/baserow/core/trash/test_trash_handler.py::test_an_app_marked_for_perm_deletion_raises_a_404_when_asked_for_trash_contents": 0.07857910800157697,
+    "tests/baserow/core/trash/test_trash_handler.py::test_cannot_restore_a_child_before_the_parent": 0.1171903900030884,
+    "tests/baserow/core/trash/test_trash_handler.py::test_cant_trash_same_item_twice": 0.06745011900056852,
+    "tests/baserow/core/trash/test_trash_handler.py::test_cant_trash_same_row_twice": 0.08567831100299372,
+    "tests/baserow/core/trash/test_trash_handler.py::test_deleting_a_user_who_trashed_items_should_still_leave_those_items_trashed": 0.08632056799979182,
+    "tests/baserow/core/trash/test_trash_handler.py::test_perm_deleting_a_parent_with_a_trashed_child_also_cleans_up_the_child_entry": 0.1491440989993862,
+    "tests/baserow/core/trash/test_trash_handler.py::test_perm_deleting_a_table_with_a_trashed_row_also_cleans_up_the_row_entry": 0.15335945499828085,
+    "tests/baserow/core/trash/test_trash_handler.py::test_perm_deleting_one_group_should_not_effect_another_trashed_group": 0.08494473100290634,
+    "tests/baserow/core/trash/test_trash_handler.py::test_restoring_a_trashed_item_unmarks_it_as_trashed_and_deletes_the_entry": 0.06291215999954147,
+    "tests/baserow/core/trash/test_trash_handler.py::test_trash_contents_are_ordered_from_newest_to_oldest_entries": 0.10014789699926041,
+    "tests/baserow/core/trash/test_trash_handler.py::test_trashing_an_item_creates_a_trash_entry_in_the_db_and_marks_it_as_trashed": 0.0772075379936723,
+    "tests/baserow/core/trash/test_trash_handler.py::test_trashing_two_rows_in_different_tables_works_as_expected": 0.1333387330014375,
+    "tests/baserow/core/trash/test_trash_types.py::test_perm_delete_application": 0.08250658999895677,
+    "tests/baserow/core/trash/test_trash_types.py::test_perm_delete_group": 0.14601884600051562,
+    "tests/baserow/core/user/test_user_handler.py::test_change_password": 0.30597370699979365,
+    "tests/baserow/core/user/test_user_handler.py::test_change_password_invalid_new_password[984kds]": 0.15931809500034433,
+    "tests/baserow/core/user/test_user_handler.py::test_change_password_invalid_new_password[Bgvmt95en6HGJZ9Xz0F8xysQ6eYgo2Y54YzRPxxv10b5n16F4rZ6YH4ulonocwiFK6970KiAxoYhULYA3JFDPIQGj5gMZZl25M46sO810Zd3nyBg699a2TDMJdHG7hAAi0YeDnuHuabyBawnb4962OQ1OOf1MxzFyNWG7NR2X6MZQL5G1V61x56lQTXbvK1AG1IPM87bQ3YAtIBtGT2vK3Wd83q3he5ezMtUfzK2ibj0WWhf86DyQB4EHRUJjYcBiI78iEJv5hcu33X2I345YosO66cTBWK45SqJEDudrCOq]": 0.16538515700085554,
+    "tests/baserow/core/user/test_user_handler.py::test_change_password_invalid_new_password[]": 0.17130859999815584,
+    "tests/baserow/core/user/test_user_handler.py::test_change_password_invalid_new_password[a]": 0.16327080100381863,
+    "tests/baserow/core/user/test_user_handler.py::test_change_password_invalid_new_password[ab]": 0.16011766500014346,
+    "tests/baserow/core/user/test_user_handler.py::test_change_password_invalid_new_password[ask]": 0.15353751099974033,
+    "tests/baserow/core/user/test_user_handler.py::test_change_password_invalid_new_password[dsfkjh4]": 0.16148864400020102,
+    "tests/baserow/core/user/test_user_handler.py::test_change_password_invalid_new_password[dsj43]": 0.165707490996283,
+    "tests/baserow/core/user/test_user_handler.py::test_change_password_invalid_new_password[oiue]": 0.15400979499827372,
+    "tests/baserow/core/user/test_user_handler.py::test_create_user": 0.3695227909993264,
+    "tests/baserow/core/user/test_user_handler.py::test_create_user_invalid_password[984kds]": 0.005099795002024621,
+    "tests/baserow/core/user/test_user_handler.py::test_create_user_invalid_password[Bgvmt95en6HGJZ9Xz0F8xysQ6eYgo2Y54YzRPxxv10b5n16F4rZ6YH4ulonocwiFK6970KiAxoYhULYA3JFDPIQGj5gMZZl25M46sO810Zd3nyBg699a2TDMJdHG7hAAi0YeDnuHuabyBawnb4962OQ1OOf1MxzFyNWG7NR2X6MZQL5G1V61x56lQTXbvK1AG1IPM87bQ3YAtIBtGT2vK3Wd83q3he5ezMtUfzK2ibj0WWhf86DyQB4EHRUJjYcBiI78iEJv5hcu33X2I345YosO66cTBWK45SqJEDudrCOq]": 0.0064423190015077125,
+    "tests/baserow/core/user/test_user_handler.py::test_create_user_invalid_password[]": 0.009890920995530905,
+    "tests/baserow/core/user/test_user_handler.py::test_create_user_invalid_password[a]": 0.007471804001397686,
+    "tests/baserow/core/user/test_user_handler.py::test_create_user_invalid_password[ab]": 0.005542679002246587,
+    "tests/baserow/core/user/test_user_handler.py::test_create_user_invalid_password[ask]": 0.006674274998658802,
+    "tests/baserow/core/user/test_user_handler.py::test_create_user_invalid_password[dsfkjh4]": 0.004871738005022053,
+    "tests/baserow/core/user/test_user_handler.py::test_create_user_invalid_password[dsj43]": 0.004943190997437341,
+    "tests/baserow/core/user/test_user_handler.py::test_create_user_invalid_password[oiue]": 0.005029031995945843,
+    "tests/baserow/core/user/test_user_handler.py::test_create_user_with_invitation": 0.129768922997755,
+    "tests/baserow/core/user/test_user_handler.py::test_create_user_with_template": 0.15071183699910762,
+    "tests/baserow/core/user/test_user_handler.py::test_first_ever_created_user_is_staff": 0.3643979799999215,
+    "tests/baserow/core/user/test_user_handler.py::test_get_user": 0.060511234998557484,
+    "tests/baserow/core/user/test_user_handler.py::test_reset_password": 0.22714536099738325,
+    "tests/baserow/core/user/test_user_handler.py::test_reset_password_invalid_new_password[984kds]": 0.053738406000775285,
+    "tests/baserow/core/user/test_user_handler.py::test_reset_password_invalid_new_password[Bgvmt95en6HGJZ9Xz0F8xysQ6eYgo2Y54YzRPxxv10b5n16F4rZ6YH4ulonocwiFK6970KiAxoYhULYA3JFDPIQGj5gMZZl25M46sO810Zd3nyBg699a2TDMJdHG7hAAi0YeDnuHuabyBawnb4962OQ1OOf1MxzFyNWG7NR2X6MZQL5G1V61x56lQTXbvK1AG1IPM87bQ3YAtIBtGT2vK3Wd83q3he5ezMtUfzK2ibj0WWhf86DyQB4EHRUJjYcBiI78iEJv5hcu33X2I345YosO66cTBWK45SqJEDudrCOq]": 0.054227115000685444,
+    "tests/baserow/core/user/test_user_handler.py::test_reset_password_invalid_new_password[]": 0.06267809900236898,
+    "tests/baserow/core/user/test_user_handler.py::test_reset_password_invalid_new_password[a]": 0.06220668499736348,
+    "tests/baserow/core/user/test_user_handler.py::test_reset_password_invalid_new_password[ab]": 0.05995601300310227,
+    "tests/baserow/core/user/test_user_handler.py::test_reset_password_invalid_new_password[ask]": 0.05594563500199001,
+    "tests/baserow/core/user/test_user_handler.py::test_reset_password_invalid_new_password[dsfkjh4]": 0.05438919000152964,
+    "tests/baserow/core/user/test_user_handler.py::test_reset_password_invalid_new_password[dsj43]": 0.05403116600064095,
+    "tests/baserow/core/user/test_user_handler.py::test_reset_password_invalid_new_password[oiue]": 0.053548771003988804,
+    "tests/baserow/core/user/test_user_handler.py::test_send_reset_password_email": 0.789474060995417,
+    "tests/baserow/core/user/test_user_handler.py::test_send_reset_password_email_in_different_language": 0.5705998240046029,
+    "tests/baserow/core/user/test_user_handler.py::test_update_user": 0.057621055995696224,
+    "tests/baserow/core/user/test_user_utils.py::test_normalize_email_address": 0.0008570210047764704,
+    "tests/baserow/core/user_file/test_user_file_handler.py::test_generate_unique": 0.0796520439980668,
+    "tests/baserow/core/user_file/test_user_file_handler.py::test_upload_user_file": 0.49836105599752045,
+    "tests/baserow/core/user_file/test_user_file_handler.py::test_upload_user_file_by_url": 0.07465597199916374,
+    "tests/baserow/core/user_file/test_user_file_handler.py::test_upload_user_file_by_url_within_private_network": 0.0566709480008285,
+    "tests/baserow/core/user_file/test_user_file_handler.py::test_user_file_path": 0.06277800799216493,
+    "tests/baserow/core/user_file/test_user_file_handler.py::test_user_file_thumbnail_path": 0.05770440000560484,
+    "tests/baserow/core/user_file/test_user_file_managers.py::test_user_file_name": 0.1611323640026967,
+    "tests/baserow/core/user_file/test_user_file_models.py::test_serialize_user_file": 0.004540232996077975,
+    "tests/baserow/core/user_file/test_user_file_models.py::test_user_file_deconstruct_name": 0.005688883000402711,
+    "tests/baserow/core/user_file/test_user_file_models.py::test_user_file_name": 0.004567424999549985,
+    "tests/baserow/performance/test_formula_performance.py::test_adding_a_formula_field_compared_to_normal_field_isnt_slow": 0.00026241299929097295,
+    "tests/baserow/performance/test_formula_performance.py::test_altering_very_nested_formula_field": 0.00025552000079187565,
+    "tests/baserow/performance/test_formula_performance.py::test_creating_very_nested_formula_field": 0.0002566330040281173,
+    "tests/baserow/performance/test_formula_performance.py::test_fanout": 0.00025046099835890345,
+    "tests/baserow/performance/test_formula_performance.py::test_fanout_one_off": 0.00025357699996675365,
+    "tests/baserow/performance/test_formula_performance.py::test_getting_data_from_a_very_nested_formula_field": 0.000262633002421353,
+    "tests/baserow/performance/test_formula_performance.py::test_getting_data_from_normal_table": 0.0002520930029277224,
+    "tests/baserow/performance/test_formula_performance.py::test_very_nested_formula_field_change": 0.0002024609966611024,
+    "tests/baserow/performance/test_public_sharing_performance.py::test_creating_many_rows_in_public_filtered_views": 0.0002650679962243885,
+    "tests/baserow/performance/test_public_sharing_performance.py::test_updating_many_rows_in_public_filtered_views": 0.00026566900123725645,
+    "tests/baserow/performance/test_trash_performance.py::test_deleting_many_of_rows_is_fast": 0.0001645600023039151,
+    "tests/baserow/ws/test_ws_auth.py::test_get_user": 4.366128376997949,
+    "tests/baserow/ws/test_ws_auth.py::test_token_auth_middleware": 0.5682379379977647,
+    "tests/baserow/ws/test_ws_pages.py::test_join_page": 0.6582801769982325,
+    "tests/baserow/ws/test_ws_pages.py::test_join_page_as_anonymous_user": 0.5738481730040803,
+    "tests/baserow/ws/test_ws_registries.py::test_broadcast": 0.0012520839991339017,
+    "tests/baserow/ws/test_ws_signals.py::test_application_created": 0.6160604870019597,
+    "tests/baserow/ws/test_ws_signals.py::test_application_deleted": 0.6069545940008538,
+    "tests/baserow/ws/test_ws_signals.py::test_application_updated": 0.5305949130015506,
+    "tests/baserow/ws/test_ws_signals.py::test_applications_reordered": 0.5600783979971311,
+    "tests/baserow/ws/test_ws_signals.py::test_group_created": 0.5511975169974903,
+    "tests/baserow/ws/test_ws_signals.py::test_group_deleted": 0.6141822999961732,
+    "tests/baserow/ws/test_ws_signals.py::test_group_restored": 0.750764825999795,
+    "tests/baserow/ws/test_ws_signals.py::test_group_updated": 0.52879944700544,
+    "tests/baserow/ws/test_ws_signals.py::test_group_user_deleted": 0.6194850059982855,
+    "tests/baserow/ws/test_ws_signals.py::test_group_user_updated": 0.6187444249990222,
+    "tests/baserow/ws/test_ws_tasks.py::test_broadcast_to_channel_group": 1.6304658590051986,
+    "tests/baserow/ws/test_ws_tasks.py::test_broadcast_to_group": 1.2785801499994704,
+    "tests/baserow/ws/test_ws_tasks.py::test_broadcast_to_users": 0.8749475379991054
+}
\ No newline at end of file
diff --git a/backend/Dockerfile b/backend/Dockerfile
index 3a2a6de0a..26061326c 100644
--- a/backend/Dockerfile
+++ b/backend/Dockerfile
@@ -1,4 +1,4 @@
-FROM python:3.7-slim-buster
+FROM python:3.7-slim-buster as base
 
 ARG UID
 ENV UID=${UID:-9999}
@@ -19,6 +19,7 @@ RUN apt-get update && \
     dos2unix \
     tini \
     postgresql-client \
+    gettext \
     && apt-get autoclean \
     && apt-get clean \
     && apt-get autoremove \
@@ -26,13 +27,27 @@ RUN apt-get update && \
 
 USER $UID:$GID
 
-COPY --chown=$UID:$GID ./backend/requirements/base.txt /baserow/requirements/
-# Disable the path warn as we set the correct path in the entrypoint when it is easy
-# to know the users $HOME/.local/bin location. Changing path in the docker image does
-# not work as we do not know where $HOME when using an ENV command.
-RUN pip3 install --no-warn-script-location -r /baserow/requirements/base.txt
+# In slim docker images, mime.types is removed and we need it for mimetypes guessing
+COPY --chown=$UID:$GID ./backend/docker/mime.types /etc/
 
+# Install non-dev base dependencies into a virtual env.
+COPY --chown=$UID:$GID ./backend/requirements/base.txt /baserow/requirements/
+RUN python3 -m venv /baserow/venv
+RUN . /baserow/venv/bin/activate && pip3 install -r /baserow/requirements/base.txt
+
+# Build a dev_deps stage which also has the dev dependencies for use by the dev layer.
+FROM base as dev_deps
+
+COPY ./backend/requirements/dev.txt /baserow/requirements/
+RUN . /baserow/venv/bin/activate && pip3 install -r /baserow/requirements/dev.txt
+
+# The core stage contains all of Baserows source code and sets up the entrypoint
+FROM base as core
+
+# Copy over backend code.
 COPY --chown=$UID:$GID ./docs /baserow/docs
+# TODO - This copy also re-copies the requirements above, meaning this will be re-run
+#        and not cached even though we already have separate layers above.
 COPY --chown=$UID:$GID ./backend /baserow/backend
 COPY --chown=$UID:$GID ./premium/backend /baserow/premium/backend
 
@@ -42,10 +57,24 @@ WORKDIR /baserow/backend
 # the application rather than buffering it.
 ENV PYTHONUNBUFFERED 1
 ENV PYTHONPATH $PYTHONPATH:/baserow/backend/src:/baserow/premium/backend/src
-ENV DJANGO_SETTINGS_MODULE='baserow.config.settings.base'
+ENTRYPOINT ["/usr/bin/tini", "--", "/bin/bash", "/baserow/backend/docker/docker-entrypoint.sh"]
+EXPOSE 8000
 
 RUN dos2unix /baserow/backend/docker/docker-entrypoint.sh && \
     chmod a+x /baserow/backend/docker/docker-entrypoint.sh
 
-ENTRYPOINT ["/usr/bin/tini", "--", "/bin/bash", "/baserow/backend/docker/docker-entrypoint.sh"]
+
+FROM core as dev
+
+# Override virtualenv with one containing dev dependencies.
+COPY --chown=$UID:$GID --from=dev_deps /baserow/venv /baserow/venv
+
+# Override env variables and initial cmd to start up in dev mode.
+ENV DJANGO_SETTINGS_MODULE='baserow.config.settings.dev'
+CMD ["dev"]
+
+FROM core as local
+
+ENV DJANGO_SETTINGS_MODULE='baserow.config.settings.base'
 CMD ["local"]
+
diff --git a/backend/Makefile b/backend/Makefile
index 0308b1eb6..1f4708679 100644
--- a/backend/Makefile
+++ b/backend/Makefile
@@ -16,5 +16,37 @@ format:
 test:
 	pytest tests ../premium/backend/tests || exit;
 
+test-regenerate-ci-durations:
+	pytest tests ../premium/backend/tests --store-durations || exit;
+
 test-parallel:
 	pytest tests ../premium/backend/tests -n 10 || exit;
+
+PYTEST_SPLITS:=1
+PYTEST_SPLIT_GROUP:=1
+ci-test-python:
+	mkdir reports/ -p; \
+	cd ..; \
+	COVERAGE_FILE=backend/reports/.coverage.$(PYTEST_SPLIT_GROUP) \
+	coverage run \
+	    --rcfile=backend/.coveragerc \
+	    -m pytest \
+	    --durations-path=backend/.test_durations \
+	    --splits $(PYTEST_SPLITS) \
+	    --group $(PYTEST_SPLIT_GROUP) \
+	    --junitxml=backend/reports/report.xml \
+	    backend/tests \
+	    premium/backend/tests;
+
+generate-html-coverage-report:
+	mkdir html_coverage/ -p; \
+	cd ..; \
+	coverage run --rcfile=backend/.coveragerc -m pytest \
+	    backend/tests \
+	    premium/backend/tests; \
+	coverage html -d html_coverage/;
+
+ci-check-startup-python:
+	timeout --preserve-status 10s \
+	    gunicorn --workers=1 -b 0.0.0.0:8002 \
+	        -k uvicorn.workers.UvicornWorker baserow.config.asgi:application;
diff --git a/backend/docker/Dockerfile.dev b/backend/docker/Dockerfile.dev
deleted file mode 100644
index 1c2677d47..000000000
--- a/backend/docker/Dockerfile.dev
+++ /dev/null
@@ -1,55 +0,0 @@
-FROM python:3.7-slim-buster
-
-# Default to 1000 as this is probably the running users UID.
-ARG UID
-ENV UID=${UID:-1000}
-ARG GID
-ENV GID=${GID:-1000}
-
-# We might be running as a user which already exists in this image. In that situation
-# Everything is OK and we should just continue on.
-RUN groupadd -g $GID baserow_docker_group || exit 0
-RUN useradd --shell /bin/bash -u $UID -g $GID -o -c "" -m baserow_docker_user || exit 0
-
-RUN apt-get update && \
-    apt-get install -y --no-install-recommends \
-    build-essential \
-    curl \
-    gnupg2 \
-    libpq-dev \
-    dos2unix \
-    tini \
-    postgresql-client \
-    gettext \
-    && apt-get autoclean \
-    && apt-get clean \
-    && apt-get autoremove \
-    && rm -rf /var/lib/apt/lists/*
-
-USER $UID:$GID
-
-COPY --chown=$UID:$GID ./backend/requirements /baserow/requirements
-# In slim docker images, mime.types is removed and we need it for mimetypes guessing
-COPY --chown=$UID:$GID ./backend/docker/mime.types /etc/
-# Disable the path warn as we set the correct path in the entrypoint when it is easy
-# to know the users $HOME/.local/bin location. Changing path in the docker image does
-# not work as we do not know where $HOME when using an ENV command.
-RUN pip3 install --no-warn-script-location -r /baserow/requirements/base.txt -r /baserow/requirements/dev.txt
-
-COPY --chown=$UID:$GID ./docs /baserow/docs
-COPY --chown=$UID:$GID ./backend /baserow/backend
-COPY --chown=$UID:$GID ./premium/backend /baserow/premium/backend
-
-WORKDIR /baserow/backend
-
-# Ensure that Python outputs everything that's printed inside
-# the application rather than buffering it.
-ENV PYTHONUNBUFFERED 1
-ENV PYTHONPATH $PYTHONPATH:/baserow/backend/src:/baserow/premium/backend/src
-ENV DJANGO_SETTINGS_MODULE='baserow.config.settings.dev'
-
-RUN dos2unix /baserow/backend/docker/docker-entrypoint.sh && \
-    chmod a+x /baserow/backend/docker/docker-entrypoint.sh
-
-ENTRYPOINT ["/usr/bin/tini", "--", "/bin/bash", "/baserow/backend/docker/docker-entrypoint.sh"]
-CMD ["dev"]
diff --git a/backend/docker/docker-entrypoint.sh b/backend/docker/docker-entrypoint.sh
index 380ff8520..4a61b3f60 100644
--- a/backend/docker/docker-entrypoint.sh
+++ b/backend/docker/docker-entrypoint.sh
@@ -9,8 +9,7 @@ DATABASE_USER="${DATABASE_USER:-postgres}"
 DATABASE_HOST="${DATABASE_HOST:-db}"
 DATABASE_PORT="${DATABASE_PORT:-5432}"
 
-# Ensure the installed python dependencies are on the path and available.
-export PATH="$PATH:$HOME/.local/bin"
+source "/baserow/venv/bin/activate"
 
 postgres_ready() {
 python << END
@@ -43,18 +42,24 @@ done
 show_help() {
 # If you change this please update ./docs/reference/baserow-docker-api.md
     echo """
-Usage: docker run <imagename> COMMAND
+Usage: docker run [-T] baserow_backend[_dev] COMMAND
 Commands
-local     : Start django using a prod ready gunicorn server
-dev       : Start a normal Django development server
-bash      : Start a bash shell
-manage    : Start manage.py
-python    : Run a python command
-shell     : Start a Django Python shell
-celery    : Run celery
-celery-dev: Run a hot-reloading dev version of celery
-lint:     : Run the linting
-help      : Show this message
+local           : Start django using a prod ready gunicorn server
+dev             : Start a normal Django development server
+exec            : Exec a command directly
+bash            : Start a bash shell
+manage          : Start manage.py
+setup           : Runs all setup commands (migrate, update_formulas, sync_templates)
+python          : Run a python command
+shell           : Start a Django Python shell
+celery          : Run celery
+celery-dev:     : Run a hot-reloading dev version of celery
+lint:           : Run the linting (only available if using dev target)
+lint-exit       : Run the linting and exit (only available if using dev target)
+test:           : Run the tests (only available if using dev target)
+ci-test:        : Run the tests for ci including various reports (dev only)
+ci-check-startup: Start up a single gunicorn and timeout after 10 seconds for ci (dev).
+help            : Show this message
 """
 }
 
@@ -87,6 +92,9 @@ case "$1" in
         run_setup_commands_if_configured
         exec gunicorn --workers=3 -b 0.0.0.0:"${PORT}" -k uvicorn.workers.UvicornWorker baserow.config.asgi:application
     ;;
+    exec)
+        exec "${@:2}"
+    ;;
     bash)
         exec /bin/bash "${@:2}"
     ;;
@@ -96,14 +104,31 @@ case "$1" in
     python)
         exec python "${@:2}"
     ;;
+    setup)
+      echo "python /baserow/backend/src/baserow/manage.py migrate"
+      python /baserow/backend/src/baserow/manage.py migrate
+      echo "python /baserow/backend/src/baserow/manage.py update_formulas"
+      python /baserow/backend/src/baserow/manage.py update_formulas
+      echo "python /baserow/backend/src/baserow/manage.py sync_templates"
+      python /baserow/backend/src/baserow/manage.py sync_templates
+    ;;
     shell)
         exec python /baserow/backend/src/baserow/manage.py shell
     ;;
-    lint)
+    lint-shell)
         CMD="make lint-python"
         echo "$CMD"
         exec bash --init-file <(echo "history -s $CMD; $CMD")
     ;;
+    lint)
+        exec make lint-python
+    ;;
+    ci-test)
+        exec make ci-test-python PYTEST_SPLITS="${PYTEST_SPLITS:-1}" PYTEST_SPLIT_GROUP="${PYTEST_SPLIT_GROUP:-1}"
+    ;;
+    ci-check-startup)
+        exec make ci-check-startup-python
+    ;;
     celery)
         exec celery -A baserow "${@:2}"
     ;;
@@ -123,7 +148,8 @@ case "$1" in
         exec bash --init-file <(echo "history -s $CMD; $CMD")
     ;;
     *)
+        echo "${@:2}"
         show_help
         exit 1
     ;;
-esac
\ No newline at end of file
+esac
diff --git a/backend/requirements/dev.txt b/backend/requirements/dev.txt
index 387e7ffac..ac9f44a86 100644
--- a/backend/requirements/dev.txt
+++ b/backend/requirements/dev.txt
@@ -18,3 +18,6 @@ django-silk==4.2.0
 django-extensions==3.1.5
 snoop==0.4.1
 openapi-spec-validator==0.4.0
+pytest-html==3.1.1
+coverage==6.2
+pytest-split==0.6.0
diff --git a/changelog.md b/changelog.md
index 8825d3c54..c55c6d7c8 100644
--- a/changelog.md
+++ b/changelog.md
@@ -28,6 +28,7 @@
 * Fix Django's default index naming scheme causing index name collisions.
 * Workaround bug in Django's schema editor sometimes causing incorrect transaction 
   rollbacks resulting in the connection to the database becoming unusable.
+* Rework Baserow docker images so they can be built and tested by gitlab CI.
 
 ## Released (2022-01-13 1.8.2)
 
diff --git a/dev.sh b/dev.sh
index b8c694e9e..77d8a3adb 100755
--- a/dev.sh
+++ b/dev.sh
@@ -232,6 +232,10 @@ else
   echo "./dev.sh Using the already set value for the env variable SYNC_TEMPLATES_ON_STARTUP = $SYNC_TEMPLATES_ON_STARTUP"
 fi
 
+# Enable buildkit for faster builds with better caching.
+export COMPOSE_DOCKER_CLI_BUILD=1
+export DOCKER_BUILDKIT=1
+
 echo "./dev.sh running docker-compose commands:
 ------------------------------------------------
 "
@@ -274,5 +278,5 @@ if [ "$dont_attach" != true ] && [ "$up" = true ] ; then
           "/bin/bash /baserow/web-frontend/docker/docker-entrypoint.sh lint-fix"
   launch_tab_and_exec "backend lint" \
           "backend" \
-          "/bin/bash /baserow/backend/docker/docker-entrypoint.sh lint"
+          "/bin/bash /baserow/backend/docker/docker-entrypoint.sh lint-shell"
 fi
diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml
index 1d34d389c..3d1cdbff1 100644
--- a/docker-compose.dev.yml
+++ b/docker-compose.dev.yml
@@ -1,4 +1,4 @@
-version: "3"
+version: "3.4"
 
 services:
 
@@ -8,8 +8,7 @@ services:
 
   backend:
     build:
-      context: .
-      dockerfile: ./backend/docker/Dockerfile.dev
+      target: dev
       args:
         # We allow configuring the UID/GID here so you can run as the dev's actual user
         # reducing the chance the containers screw up the bind mounted folders.
@@ -26,8 +25,7 @@ services:
   celery:
     image: baserow_backend_dev:latest
     build:
-      context: .
-      dockerfile: ./backend/docker/Dockerfile.dev
+      target: dev
       args:
         # We allow configuring the UID/GID here so you can run as the dev's actual user
         # reducing the chance the containers screw up the bind mounted folders.
@@ -44,8 +42,7 @@ services:
   celery-export-worker:
     image: baserow_backend_dev:latest
     build:
-      context: .
-      dockerfile: ./backend/docker/Dockerfile.dev
+      target: dev
       args:
         # We allow configuring the UID/GID here so you can run as the dev's actual user
         # reducing the chance the containers screw up the bind mounted folders.
@@ -62,8 +59,7 @@ services:
   celery-beat-worker:
     image: baserow_backend_dev:latest
     build:
-      context: .
-      dockerfile: ./backend/docker/Dockerfile.dev
+      target: dev
       args:
         # We allow configuring the UID/GID here so you can run as the dev's actual user
         # reducing the chance the containers screw up the bind mounted folders.
@@ -79,8 +75,7 @@ services:
 
   web-frontend:
     build:
-      context: .
-      dockerfile: ./web-frontend/docker/Dockerfile.dev
+      target: dev
       args:
         # We allow configuring the UID/GID here so you can run as the dev's actual user
         # reducing the chance the containers screw up the bind mounted folders.
diff --git a/docker-compose.yml b/docker-compose.yml
index 44b1caca9..2bab33fae 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,4 +1,4 @@
-version: "3"
+version: "3.4"
 
 services:
   db:
@@ -63,6 +63,9 @@ services:
 
   celery:
     image: baserow_backend:latest
+    build:
+      dockerfile: ./backend/Dockerfile
+      context: .
     environment:
       - ADDITIONAL_APPS
       - EMAIL_SMTP
@@ -73,9 +76,6 @@ services:
       - EMAIL_SMTP_PASSWORD
       - FROM_EMAIL
       - DISABLE_ANONYMOUS_PUBLIC_VIEW_WS_CONNECTIONS
-    build:
-      dockerfile: ./backend/Dockerfile
-      context: .
     command: celery worker -l INFO -Q celery
     depends_on:
       - backend
diff --git a/docs/development/directory-structure.md b/docs/development/directory-structure.md
index eb0548636..6779a48e4 100644
--- a/docs/development/directory-structure.md
+++ b/docs/development/directory-structure.md
@@ -23,10 +23,8 @@ This whole directory is also added to the backend container.
   source directory. This file is registered as a command via the `setup.py`. When 
   someone adds Baserow as a dependency they can use the command `baserow migrate` which
   is the same as `python src/baserow/manage.py migrate`.
-* `Dockerfile`: the dockerfile that is used to build the image of the 
-  backend for running baserow on your local machine.
-* `docker/Dockerfile.dev`: the dockerfile that is used to build the development image 
-  of the backend.
+* `Dockerfile`: Builds an image containing just the backend service, build with 
+   `--target dev` to instead get a dev ready image.
 * `Makefile`: contains a few commands to install the dependencies, run the linter and
   run the tests.
 * `pytest.ini`: pytest configuration when running the tests.
@@ -85,10 +83,8 @@ web frontend. This whole directory is also added to the web-frontend container.
 * `.eslintrc.js`: the configuration for the eslint linter.
 * `.prettierrc`: configuration for prettier.
 * `.stylelintrc`: configuration for stylelint which lints the scss code.
-* `Dockerfile`: the dockerfile that is used to build the image of the
-  web-frontend for running baserow on your local machine.
-* `docker/Dockerfile.dev`: the dockerfile that is used to build the development image
-  of the web-frontend.
+* `Dockerfile`:  Builds an image containing just the web-frontend service, build with
+  `--target dev` to instead get a dev ready image.
 * `intellij-idea.webpack.config.js` a webpack config file that can be used by Intellij
   iDEA. It adds the correct aliases for the editor.
 * `jest.config.js`: config file for running the tests with JEST.
diff --git a/docs/reference/baserow-docker-api.md b/docs/reference/baserow-docker-api.md
index bee43be81..e17f86158 100644
--- a/docs/reference/baserow-docker-api.md
+++ b/docs/reference/baserow-docker-api.md
@@ -12,9 +12,9 @@ Below are the files used by our docker setup and what they are responsible for:
 
 - `docker-compose.yml`: A compose file which starts Baserow in local mode with no
   development features enabled.
-- `./backend/Dockerfile`: The backend's Dockerfile for local mode. See below for
+- `./backend/Dockerfile`: The backend's Dockerfile. See below for
   supported command line arguments. Also used to run the celery worker.
-- `./web-frontend/Dockerfile`: The web-frontend's Dockerfile for local mode. See below
+- `./web-frontend/Dockerfile`: The web-frontend's Dockerfile. See below
   for supported command line arguments.
 - `./media/Dockerfile`: A simple nginx image used to serve uploaded user files only.
 
@@ -22,34 +22,41 @@ Below are the files used by our docker setup and what they are responsible for:
 
 - `docker-compose.dev.yml`: A compose file which overrides parts of `docker-compose.yml`
   to enable development features, do not use this in production.
-- `./backend/docker/Dockerfile.dev`: The backends's Dockerfile for dev mode.
-- `./web-frontend/docker/Dockerfile.dev`: The web-frontend's Dockerfile for dev mode.
+- `./backend/docker/Dockerfile`: Build with `--target dev` to get the dev version.
+- `./web-frontend/docker/Dockerfile`: Build with `--target dev` to get the dev version. 
 
 ### For Both Envs
 
-- `./backend/docker/docker-entrypoint.sh`: The entrypoint script used for both of the
-  backend images.
-- `./web-frontend/docker/docker-entrypoint.sh`: The entrypoint script used for both of
-  the web-frontend images.
+- `./backend/docker/docker-entrypoint.sh`: The entrypoint script used by the backend
+  Dockerfile, provides a set of commonly used commands for working with baserow.
+- `./web-frontend/docker/docker-entrypoint.sh`: The entrypoint script used by the 
+   web-frontend Dockerfile, provides a set of commonly used commands for working
+  with Baserow.
 
 ## Backend Image CLI
 
 The `baserow_backend` and `baserow_backend_dev` images provide various commands used to
 change what process is started inside the container.
 
-```bash
-Usage: docker run <imagename> COMMAND
+```txt
+Usage: docker run [-T] baserow_backend[_dev] COMMAND
 Commands
-local     : Start django using a prod ready gunicorn server
-dev       : Start a normal Django development server
-bash      : Start a bash shell
-manage    : Start manage.py
-python    : Run a python command
-shell     : Start a Django Python shell
-celery    : Run celery
-celery-dev: Run a hot-reloading dev version of celery
-lint:     : Run the linting
-help      : Show this message
+local           : Start django using a prod ready gunicorn server
+dev             : Start a normal Django development server
+exec            : Exec a command directly.
+bash            : Start a bash shell
+manage          : Start manage.py
+setup           : Runs all setup commands (migrate, update_formulas, sync_templates)
+python          : Run a python command
+shell           : Start a Django Python shell
+celery          : Run celery
+celery-dev:     : Run a hot-reloading dev version of celery
+lint:           : Run the linting (only available if using dev target)
+lint-exit       : Run the linting and exit (only available if using dev target)
+test:           : Run the tests (only available if using dev target)
+ci-test:        : Run the tests for ci including various reports (dev only)
+ci-check-startup: Start up a single gunicorn and timeout after 10 seconds for ci (dev).
+help            : Show this message
 ```
 
 You can run one of these as a one off command like so:
@@ -66,13 +73,18 @@ $ ./dev.sh run backend COMMAND
 The `baserow_web-frontend` and `baserow_web-frontend_dev` images provide various
 commands used to change what process is started inside the container.
 
-```bash
-Usage: docker run <imagename> COMMAND
+```txt
+Usage: docker run [-T] baserow_web-frontend[_dev] COMMAND
 Commands
 dev      : Start a normal nuxt development server
 local    : Start a non-dev prod ready nuxt server
-lint     : Run the linting
+lint     : Run all the linting
 lint-fix : Run eslint fix
+stylelint: Run stylelint
+eslint   : Run eslint
+test     : Run jest tests
+ci-test  : Run ci tests with reporting
+exec     : Exec a command directly.
 bash     : Start a bash shell
 help     : Show this message
 ```
diff --git a/web-frontend/Dockerfile b/web-frontend/Dockerfile
index c2d486dc5..108680e08 100644
--- a/web-frontend/Dockerfile
+++ b/web-frontend/Dockerfile
@@ -1,4 +1,4 @@
-FROM node:12-buster
+FROM node:12-buster as base
 
 ARG UID
 ENV UID=${UID:-9999}
@@ -38,7 +38,6 @@ RUN yarn install
 COPY --chown=$UID:$GID ./web-frontend /baserow/web-frontend/
 COPY --chown=$UID:$GID ./premium/web-frontend /baserow/premium/web-frontend/
 
-RUN yarn run build-local
 
 RUN dos2unix /baserow/web-frontend/docker/docker-entrypoint.sh && \
     chmod a+x /baserow/web-frontend/docker/docker-entrypoint.sh
@@ -46,5 +45,16 @@ RUN dos2unix /baserow/web-frontend/docker/docker-entrypoint.sh && \
 # tini installed above protects us from zombie processes and ensures the default signal
 # handlers work, see https://github.com/krallin/tini.
 ENTRYPOINT ["/usr/bin/tini", "--", "/bin/bash", "/baserow/web-frontend/docker/docker-entrypoint.sh"]
+EXPOSE 3000
+
+FROM base as dev
+
+# We don't bother running build-local in dev mode as it pre-compiles nuxt which won't
+# be used when running the nuxt dev server.
+CMD ["dev"]
+
+FROM base as local
+
+RUN yarn run build-local
 CMD ["local"]
 
diff --git a/web-frontend/Makefile b/web-frontend/Makefile
index 63f03b38f..9631d53dd 100644
--- a/web-frontend/Makefile
+++ b/web-frontend/Makefile
@@ -12,9 +12,15 @@ lint: eslint stylelint
 lint-javascript: lint
 
 jest:
-	yarn run jest || exit;
+	npx jest || exit;
 
 test: jest
 
+unit-test:
+	npx jest --selectProjects unit --selectProjects premium || exit;
+
+ci-test-javascript:
+	JEST_JUNIT_OUTPUT_DIR=../reports/ npx jest --ci --collectCoverage --coverageDirectory="./reports/coverage/" || exit;
+
 unit-test-watch:
-	yarn run jest test/unit --watch || exit;
+	npx jest test/unit --watch || exit;
diff --git a/web-frontend/docker/Dockerfile.dev b/web-frontend/docker/Dockerfile.dev
deleted file mode 100644
index d32db3e0b..000000000
--- a/web-frontend/docker/Dockerfile.dev
+++ /dev/null
@@ -1,47 +0,0 @@
-FROM node:12-buster
-
-ARG UID
-ENV UID=${UID:-1000}
-ARG GID
-ENV GID=${GID:-1000}
-
-# Perform all OS package installation and cleanup in one single command to reduce the
-# size of the created layer.
-RUN apt-get update && \
-    apt-get install -y --no-install-recommends \
-    build-essential \
-    curl \
-    gnupg2 \
-    dos2unix \
-    tini \
-    && apt-get autoclean \
-    && apt-get clean \
-    && apt-get autoremove \
-    && rm -rf /var/lib/apt/lists/*
-
-# The node image already creates a non-root user to run as, update its ids so they
-# match the provided UID and GID we wish to build and run this image with.
-# If GID or UID already exist that's OK no need to stop the build.
-RUN groupmod -g ${GID} node || exit 0
-RUN usermod -u ${UID} -g ${GID} node || exit 0
-
-USER $UID:$GID
-
-# Create and install the dependencies in separate COPY commands
-COPY --chown=$UID:$GID ./web-frontend/package.json ./web-frontend/yarn.lock /baserow/web-frontend/
-
-WORKDIR /baserow/web-frontend
-
-RUN yarn install
-
-COPY --chown=$UID:$GID ./web-frontend /baserow/web-frontend/
-COPY --chown=$UID:$GID ./premium/web-frontend /baserow/premium/web-frontend/
-
-RUN dos2unix /baserow/web-frontend/docker/docker-entrypoint.sh && \
-    chmod a+x /baserow/web-frontend/docker/docker-entrypoint.sh
-
-# tini installed above protects us from zombie processes and ensures the default signal
-# handlers work, see https://github.com/krallin/tini.
-ENTRYPOINT ["/usr/bin/tini", "--", "/bin/bash", "/baserow/web-frontend/docker/docker-entrypoint.sh"]
-CMD ["dev"]
-
diff --git a/web-frontend/docker/docker-entrypoint.sh b/web-frontend/docker/docker-entrypoint.sh
index 701119d8a..05ca758da 100644
--- a/web-frontend/docker/docker-entrypoint.sh
+++ b/web-frontend/docker/docker-entrypoint.sh
@@ -6,13 +6,18 @@ set -euo pipefail
 show_help() {
 # If you change this please update ./docs/reference/baserow-docker-api.md
     echo """
-Usage: docker run <imagename> COMMAND
+Usage: docker run [-T] baserow_web-frontend[_dev] COMMAND
 Commands
 dev      : Start a normal nuxt development server
 local    : Start a non-dev prod ready nuxt server
-lint     : Run the linting
+lint     : Run all the linting
 lint-fix : Run eslint fix
+stylelint: Run stylelint
+eslint   : Run eslint
+test     : Run jest tests
+ci-test  : Run ci tests with reporting
 bash     : Start a bash shell
+exec     : Exec a command directly
 help     : Show this message
 """
 }
@@ -38,11 +43,27 @@ case "$1" in
       echo "$CMD"
       exec bash --init-file <(echo "history -s $CMD; $CMD")
     ;;
+    eslint)
+      exec make eslint
+    ;;
+    stylelint)
+      exec make eslint
+    ;;
+    test)
+      exec make jest
+    ;;
+    ci-test)
+      exec make ci-test-javascript
+    ;;
+    exec)
+        exec "${@:2}"
+    ;;
     bash)
       exec /bin/bash "${@:2}"
     ;;
     *)
+      echo "${@:2}"
       show_help
       exit 1
     ;;
-esac
\ No newline at end of file
+esac
diff --git a/web-frontend/jest.config.js b/web-frontend/jest.config.js
index e10a635af..a8af17e68 100644
--- a/web-frontend/jest.config.js
+++ b/web-frontend/jest.config.js
@@ -1,9 +1,11 @@
-// The main jest config file used to run all of our tests.
+// Setting reporters on the command line does not work so enable via this env variable
+// we have to set anyway when using the junit reporter in CI.
+const junitReporterConfig = process.env.JEST_JUNIT_OUTPUT_DIR
+  ? {
+      reporters: ['default', '<rootDir>/web-frontend/node_modules/jest-junit'],
+    }
+  : {}
 module.exports = {
-  // The rootDir used by jest must be the root of the repository so the premium tests
-  // and frontend code are contained within jest's rootDir. This is because:
-  // - Jest cannot collect coverage for files outside of its rootDir
-  // - Jest struggles to run tests which are outside of its rootDir.
   rootDir: '..',
   roots: ['<rootDir>/web-frontend/', '<rootDir>/premium/web-frontend'],
   moduleDirectories: ['<rootDir>/web-frontend/node_modules/'],
@@ -13,4 +15,18 @@ module.exports = {
     '<rootDir>/premium/web-frontend/test/unit',
     '<rootDir>/web-frontend/test/server',
   ],
+  coverageReporters: [
+    'text-summary',
+    ['cobertura', { projectRoot: '/baserow/' }],
+  ],
+  collectCoverageFrom: [
+    '<rootDir>/premium/web-frontend/modules/**/*.{js,Vue,vue}',
+    '<rootDir>/web-frontend/modules/**/*.{js,Vue,vue}',
+    '!**/node_modules/**',
+    '!**/.nuxt/**',
+    '!**/reports/**',
+    '!**/test/**',
+    '!**/generated/**',
+  ],
+  ...junitReporterConfig,
 }
diff --git a/web-frontend/package.json b/web-frontend/package.json
index cb0523165..5cb1b6eb9 100644
--- a/web-frontend/package.json
+++ b/web-frontend/package.json
@@ -64,6 +64,7 @@
     "eslint-plugin-vue": "^7.14.0",
     "flush-promises": "^1.0.2",
     "jest": "^26.6.3",
+    "jest-junit": "^13.0.0",
     "jest-serializer-vue": "^2.0.2",
     "jsdom": "^16.6.0",
     "jsdom-global": "^3.0.2",
diff --git a/web-frontend/yarn.lock b/web-frontend/yarn.lock
index ff8a3cd71..eaf2347e4 100644
--- a/web-frontend/yarn.lock
+++ b/web-frontend/yarn.lock
@@ -2423,6 +2423,11 @@ ansi-regex@^5.0.0:
   resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
   integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
 
+ansi-regex@^5.0.1:
+  version "5.0.1"
+  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
+  integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
+
 ansi-styles@^2.2.1:
   version "2.2.1"
   resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
@@ -6925,6 +6930,16 @@ jest-jasmine2@^26.6.3:
     pretty-format "^26.6.2"
     throat "^5.0.0"
 
+jest-junit@^13.0.0:
+  version "13.0.0"
+  resolved "https://registry.yarnpkg.com/jest-junit/-/jest-junit-13.0.0.tgz#479be347457aad98ae8a5983a23d7c3ec526c9a3"
+  integrity sha512-JSHR+Dhb32FGJaiKkqsB7AR3OqWKtldLd6ZH2+FJ8D4tsweb8Id8zEVReU4+OlrRO1ZluqJLQEETm+Q6/KilBg==
+  dependencies:
+    mkdirp "^1.0.4"
+    strip-ansi "^6.0.1"
+    uuid "^8.3.2"
+    xml "^1.0.1"
+
 jest-leak-detector@^26.6.2:
   version "26.6.2"
   resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz#7717cf118b92238f2eba65054c8a0c9c653a91af"
@@ -11117,6 +11132,13 @@ strip-ansi@^6.0.0:
   dependencies:
     ansi-regex "^5.0.0"
 
+strip-ansi@^6.0.1:
+  version "6.0.1"
+  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
+  integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
+  dependencies:
+    ansi-regex "^5.0.1"
+
 strip-bom@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
@@ -12033,7 +12055,7 @@ uuid@^3.3.2:
   resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
   integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
 
-uuid@^8.3.0:
+uuid@^8.3.0, uuid@^8.3.2:
   version "8.3.2"
   resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
   integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
@@ -12534,6 +12556,11 @@ xml-name-validator@^3.0.0:
   resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
   integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
 
+xml@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5"
+  integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=
+
 xmlchars@^2.2.0:
   version "2.2.0"
   resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"