{
  "schema": 1,
  "sqlstate": "55P03",
  "condition_name": "lock_not_available",
  "runner": "scripts/verify_cases.py",
  "targets": {
    "latest": {
      "binary": "Homebrew PostgreSQL 18.6",
      "required": true
    },
    "pg10": {
      "image": "postgres:10",
      "required": true
    }
  },
  "cases": [
    {
      "id": "nowait_row_lock",
      "versions": [
        "10",
        "18"
      ],
      "preconditions": [
        "Two runner-owned sessions target one row.",
        "The blocker acquires its lock before the NOWAIT statement is sent."
      ],
      "trigger": "Hold a row lock in one explicit transaction, issue SELECT FOR UPDATE NOWAIT from a second session, then release and retry.",
      "assertions": [
        "SQLSTATE is 55P03 with ERROR severity",
        "The diagnostic identifies a row lock that cannot be obtained immediately",
        "The blocker is INTRANS and the NOWAIT contender remains IDLE after its error",
        "After blocker rollback the same contender updates and reads the row"
      ],
      "repair": "Use a bounded NOWAIT failure as a signal, release or resolve the blocker, then retry according to the application’s lock policy; this case does not treat sleeping as synchronization.",
      "cleanup": "Close all runner connections and drop the case schema with an owner connection."
    }
  ],
  "evidence_status": "authored",
  "snippets": [
    {
      "id": "nowait_row_lock",
      "case_id": "nowait_row_lock",
      "language": "sql",
      "statements": {
        "create": "CREATE TABLE nowait_rows(id integer PRIMARY KEY, marker text NOT NULL)",
        "seed": "INSERT INTO nowait_rows VALUES (1, 'seed')",
        "begin": "BEGIN",
        "lock": "SELECT id FROM nowait_rows WHERE id = 1 FOR UPDATE",
        "trigger": "SELECT id FROM nowait_rows WHERE id = 1 FOR UPDATE NOWAIT",
        "rollback": "ROLLBACK",
        "repair": "UPDATE nowait_rows SET marker = 'repaired' WHERE id = 1 RETURNING marker",
        "verify": "SELECT marker FROM nowait_rows WHERE id = 1"
      }
    }
  ],
  "runtime": [
    {
      "id": "runtime.ops-55p03-latest-1.latest",
      "run_id": "ops-55p03-latest-1",
      "target": "latest",
      "status": "passed",
      "server_version": "18.6 (Homebrew)",
      "server_version_num": 180006,
      "summary_sha256": "576dcff7c4675c49e88c193bcf8c82e833c8c2003896aed9920ffe8b4fb539b2",
      "raw_sha256": "a12c4e0f493890f79eb7640b62bf7529fd105106a999383d444992a091ddfb99",
      "case_manifest": {
        "id": "manifest.55P03",
        "kind": "local_artifact",
        "source_role": "case_manifest"
      },
      "snippet_registry": {
        "id": "snippet-registry.55P03",
        "kind": "local_artifact",
        "source_role": "snippet_registry",
        "sha256": "b38eb524cc6b4080a80b9ea231fe06bd87b27061c810b0b94992bbb18a172f91"
      },
      "environment": {
        "server_version": "18.6 (Homebrew)",
        "server_version_num": "180006",
        "current_user": "runner",
        "connection_scope": "runner-owned localhost port",
        "log_destination": "csvlog,jsonlog",
        "log_error_verbosity": "verbose",
        "psycopg_version": "3.3.5",
        "libpq_version": "18.6",
        "target_kind": "latest"
      },
      "cases": [
        "nowait_row_lock"
      ],
      "observed": {
        "connections_autocommit": {
          "blocker": true,
          "contender": true
        },
        "diagnostic": {
          "column_name": null,
          "constraint_name": null,
          "context": null,
          "datatype_name": null,
          "exception_type": "LockNotAvailable",
          "internal_position": null,
          "internal_query": null,
          "message_detail": null,
          "message_hint": null,
          "message_primary": "could not obtain lock on row in relation \"nowait_rows\"",
          "schema_name": null,
          "severity": "ERROR",
          "severity_nonlocalized": "ERROR",
          "source_file": "heapam.c",
          "source_function": "heap_lock_tuple",
          "source_line": "5235",
          "sqlstate": "55P03",
          "statement_position": null,
          "table_name": null,
          "text": "could not obtain lock on row in relation \"nowait_rows\""
        },
        "repair_marker": "repaired",
        "statuses": {
          "blocker_after_lock": "INTRANS",
          "blocker_after_release": "IDLE",
          "contender_after_nowait": "IDLE",
          "contender_after_repair": "IDLE"
        },
        "synchronization": "The blocker acquired SELECT FOR UPDATE before the contender issued SELECT FOR UPDATE NOWAIT; no timing sleep is used.",
        "table": "\"c55p03_nowait_row_lock\".\"nowait_rows\""
      },
      "assertions": [
        {
          "expected": "55P03",
          "name": "55P03 SQLSTATE",
          "observed": "55P03",
          "passed": true
        },
        {
          "expected": "ERROR",
          "name": "55P03 ERROR severity",
          "observed": "ERROR",
          "passed": true
        },
        {
          "expected": "could not obtain lock ... in relation nowait_rows",
          "name": "NOWAIT reports lock-not-available",
          "observed": "could not obtain lock on row in relation \"nowait_rows\"",
          "passed": true
        },
        {
          "expected": "INTRANS",
          "name": "blocker holds the explicit transaction",
          "observed": "INTRANS",
          "passed": true
        },
        {
          "expected": "IDLE",
          "name": "NOWAIT failure leaves contender usable",
          "observed": "IDLE",
          "passed": true
        },
        {
          "expected": "IDLE",
          "name": "rollback releases blocker",
          "observed": "IDLE",
          "passed": true
        },
        {
          "expected": {
            "marker": "repaired",
            "status": "IDLE"
          },
          "name": "same contender retries after release",
          "observed": {
            "status": "IDLE",
            "updated": "repaired",
            "verified": "repaired"
          },
          "passed": true
        }
      ],
      "cleanup": {
        "errors": [],
        "passed": true
      },
      "result": {
        "status": "passed",
        "environment": {
          "TimeZone": "Asia/Shanghai",
          "backend_pid": 43916,
          "binary": {
            "bindir": "/opt/homebrew/Cellar/postgresql@18/18.6/bin",
            "pg_config": "/opt/homebrew/bin/pg_config",
            "pg_config_version": "PostgreSQL 18.6 (Homebrew)",
            "postgres": "/opt/homebrew/Cellar/postgresql@18/18.6/bin/postgres"
          },
          "connection_scope": "runner-owned localhost port",
          "current_user": "runner",
          "docker": {},
          "lc_messages": "C",
          "libpq_version": "18.6",
          "locale": "C.UTF-8",
          "log_destination": "csvlog,jsonlog",
          "log_error_verbosity": "verbose",
          "log_min_error_statement": "error",
          "log_min_messages": "error",
          "logging_collector": "on",
          "machine": "arm64",
          "max_connections": "100",
          "platform": "macOS-26.6.2-arm64-arm-64bit-Mach-O",
          "psycopg_version": "3.3.5",
          "python_version": "3.14.6 (main, Jun 10 2026, 10:03:53) [Clang 21.0.0 (clang-2100.0.123.102)]",
          "server_encoding": "UTF8",
          "server_version": "18.6 (Homebrew)",
          "server_version_num": "180006",
          "target_kind": "latest",
          "wal_level": "logical"
        },
        "cases": [
          {
            "assertions": [
              {
                "expected": "55P03",
                "name": "55P03 SQLSTATE",
                "observed": "55P03",
                "passed": true
              },
              {
                "expected": "ERROR",
                "name": "55P03 ERROR severity",
                "observed": "ERROR",
                "passed": true
              },
              {
                "expected": "could not obtain lock ... in relation nowait_rows",
                "name": "NOWAIT reports lock-not-available",
                "observed": "could not obtain lock on row in relation \"nowait_rows\"",
                "passed": true
              },
              {
                "expected": "INTRANS",
                "name": "blocker holds the explicit transaction",
                "observed": "INTRANS",
                "passed": true
              },
              {
                "expected": "IDLE",
                "name": "NOWAIT failure leaves contender usable",
                "observed": "IDLE",
                "passed": true
              },
              {
                "expected": "IDLE",
                "name": "rollback releases blocker",
                "observed": "IDLE",
                "passed": true
              },
              {
                "expected": {
                  "marker": "repaired",
                  "status": "IDLE"
                },
                "name": "same contender retries after release",
                "observed": {
                  "status": "IDLE",
                  "updated": "repaired",
                  "verified": "repaired"
                },
                "passed": true
              }
            ],
            "case_id": "nowait_row_lock",
            "cleanup": {
              "errors": [],
              "passed": true
            },
            "elapsed_seconds": 0.013,
            "observed": {
              "connections_autocommit": {
                "blocker": true,
                "contender": true
              },
              "diagnostic": {
                "column_name": null,
                "constraint_name": null,
                "context": null,
                "datatype_name": null,
                "exception_type": "LockNotAvailable",
                "internal_position": null,
                "internal_query": null,
                "message_detail": null,
                "message_hint": null,
                "message_primary": "could not obtain lock on row in relation \"nowait_rows\"",
                "schema_name": null,
                "severity": "ERROR",
                "severity_nonlocalized": "ERROR",
                "source_file": "heapam.c",
                "source_function": "heap_lock_tuple",
                "source_line": "5235",
                "sqlstate": "55P03",
                "statement_position": null,
                "table_name": null,
                "text": "could not obtain lock on row in relation \"nowait_rows\""
              },
              "repair_marker": "repaired",
              "statuses": {
                "blocker_after_lock": "INTRANS",
                "blocker_after_release": "IDLE",
                "contender_after_nowait": "IDLE",
                "contender_after_repair": "IDLE"
              },
              "synchronization": "The blocker acquired SELECT FOR UPDATE before the contender issued SELECT FOR UPDATE NOWAIT; no timing sleep is used.",
              "table": "\"c55p03_nowait_row_lock\".\"nowait_rows\""
            },
            "schema": "c55p03_nowait_row_lock",
            "status": "passed"
          }
        ]
      }
    },
    {
      "id": "runtime.ops-55p03-pg10-1.pg10",
      "run_id": "ops-55p03-pg10-1",
      "target": "pg10",
      "status": "passed",
      "server_version": "10.21 (Debian 10.21-1.pgdg90+1)",
      "server_version_num": 100021,
      "summary_sha256": "1b9030d8f33edeff84d946df3d347805e7d41f54048d2eed7f1ebc01fe075d8b",
      "raw_sha256": "4e45d18e453e859fa01887db2097443e6cdc7bcc83830d14cd97db023ce2817e",
      "case_manifest": {
        "id": "manifest.55P03",
        "kind": "local_artifact",
        "source_role": "case_manifest"
      },
      "snippet_registry": {
        "id": "snippet-registry.55P03",
        "kind": "local_artifact",
        "source_role": "snippet_registry",
        "sha256": "b38eb524cc6b4080a80b9ea231fe06bd87b27061c810b0b94992bbb18a172f91"
      },
      "environment": {
        "server_version": "10.21 (Debian 10.21-1.pgdg90+1)",
        "server_version_num": "100021",
        "current_user": "postgres",
        "connection_scope": "runner-owned localhost port",
        "log_destination": "csvlog",
        "log_error_verbosity": "verbose",
        "psycopg_version": "3.3.5",
        "libpq_version": "18.6",
        "target_kind": "pg10"
      },
      "cases": [
        "nowait_row_lock"
      ],
      "observed": {
        "connections_autocommit": {
          "blocker": true,
          "contender": true
        },
        "diagnostic": {
          "column_name": null,
          "constraint_name": null,
          "context": null,
          "datatype_name": null,
          "exception_type": "LockNotAvailable",
          "internal_position": null,
          "internal_query": null,
          "message_detail": null,
          "message_hint": null,
          "message_primary": "could not obtain lock on row in relation \"nowait_rows\"",
          "schema_name": null,
          "severity": "ERROR",
          "severity_nonlocalized": "ERROR",
          "source_file": "heapam.c",
          "source_function": "heap_lock_tuple",
          "source_line": "5074",
          "sqlstate": "55P03",
          "statement_position": null,
          "table_name": null,
          "text": "could not obtain lock on row in relation \"nowait_rows\""
        },
        "repair_marker": "repaired",
        "statuses": {
          "blocker_after_lock": "INTRANS",
          "blocker_after_release": "IDLE",
          "contender_after_nowait": "IDLE",
          "contender_after_repair": "IDLE"
        },
        "synchronization": "The blocker acquired SELECT FOR UPDATE before the contender issued SELECT FOR UPDATE NOWAIT; no timing sleep is used.",
        "table": "\"c55p03_nowait_row_lock\".\"nowait_rows\""
      },
      "assertions": [
        {
          "expected": "55P03",
          "name": "55P03 SQLSTATE",
          "observed": "55P03",
          "passed": true
        },
        {
          "expected": "ERROR",
          "name": "55P03 ERROR severity",
          "observed": "ERROR",
          "passed": true
        },
        {
          "expected": "could not obtain lock ... in relation nowait_rows",
          "name": "NOWAIT reports lock-not-available",
          "observed": "could not obtain lock on row in relation \"nowait_rows\"",
          "passed": true
        },
        {
          "expected": "INTRANS",
          "name": "blocker holds the explicit transaction",
          "observed": "INTRANS",
          "passed": true
        },
        {
          "expected": "IDLE",
          "name": "NOWAIT failure leaves contender usable",
          "observed": "IDLE",
          "passed": true
        },
        {
          "expected": "IDLE",
          "name": "rollback releases blocker",
          "observed": "IDLE",
          "passed": true
        },
        {
          "expected": {
            "marker": "repaired",
            "status": "IDLE"
          },
          "name": "same contender retries after release",
          "observed": {
            "status": "IDLE",
            "updated": "repaired",
            "verified": "repaired"
          },
          "passed": true
        }
      ],
      "cleanup": {
        "errors": [],
        "passed": true
      },
      "result": {
        "status": "passed",
        "environment": {
          "TimeZone": "Etc/UTC",
          "backend_pid": 79,
          "binary": {},
          "connection_scope": "runner-owned localhost port",
          "current_user": "postgres",
          "docker": {
            "architecture": "arm64",
            "command": "/usr/local/bin/docker",
            "digest": "sha256:b2baf8998630663d21370da06387c950e587071bdd307ee34e661cdcc7442bcc",
            "id": "sha256:b2baf8998630663d21370da06387c950e587071bdd307ee34e661cdcc7442bcc",
            "image": "postgres:10",
            "image_created": "2022-06-23T09:11:18.374607054Z",
            "image_ref": "postgres@sha256:b2baf8998630663d21370da06387c950e587071bdd307ee34e661cdcc7442bcc",
            "log_destination": "csvlog",
            "os": "linux",
            "repo_digests": [
              "postgres@sha256:b2baf8998630663d21370da06387c950e587071bdd307ee34e661cdcc7442bcc"
            ]
          },
          "lc_messages": "en_US.utf8",
          "libpq_version": "18.6",
          "locale": "C.UTF-8",
          "log_destination": "csvlog",
          "log_error_verbosity": "verbose",
          "log_min_error_statement": "error",
          "log_min_messages": "error",
          "logging_collector": "on",
          "machine": "arm64",
          "max_connections": "100",
          "platform": "macOS-26.6.2-arm64-arm-64bit-Mach-O",
          "psycopg_version": "3.3.5",
          "python_version": "3.14.6 (main, Jun 10 2026, 10:03:53) [Clang 21.0.0 (clang-2100.0.123.102)]",
          "server_encoding": "UTF8",
          "server_version": "10.21 (Debian 10.21-1.pgdg90+1)",
          "server_version_num": "100021",
          "target_kind": "pg10",
          "wal_level": "logical"
        },
        "cases": [
          {
            "assertions": [
              {
                "expected": "55P03",
                "name": "55P03 SQLSTATE",
                "observed": "55P03",
                "passed": true
              },
              {
                "expected": "ERROR",
                "name": "55P03 ERROR severity",
                "observed": "ERROR",
                "passed": true
              },
              {
                "expected": "could not obtain lock ... in relation nowait_rows",
                "name": "NOWAIT reports lock-not-available",
                "observed": "could not obtain lock on row in relation \"nowait_rows\"",
                "passed": true
              },
              {
                "expected": "INTRANS",
                "name": "blocker holds the explicit transaction",
                "observed": "INTRANS",
                "passed": true
              },
              {
                "expected": "IDLE",
                "name": "NOWAIT failure leaves contender usable",
                "observed": "IDLE",
                "passed": true
              },
              {
                "expected": "IDLE",
                "name": "rollback releases blocker",
                "observed": "IDLE",
                "passed": true
              },
              {
                "expected": {
                  "marker": "repaired",
                  "status": "IDLE"
                },
                "name": "same contender retries after release",
                "observed": {
                  "status": "IDLE",
                  "updated": "repaired",
                  "verified": "repaired"
                },
                "passed": true
              }
            ],
            "case_id": "nowait_row_lock",
            "cleanup": {
              "errors": [],
              "passed": true
            },
            "elapsed_seconds": 0.024,
            "observed": {
              "connections_autocommit": {
                "blocker": true,
                "contender": true
              },
              "diagnostic": {
                "column_name": null,
                "constraint_name": null,
                "context": null,
                "datatype_name": null,
                "exception_type": "LockNotAvailable",
                "internal_position": null,
                "internal_query": null,
                "message_detail": null,
                "message_hint": null,
                "message_primary": "could not obtain lock on row in relation \"nowait_rows\"",
                "schema_name": null,
                "severity": "ERROR",
                "severity_nonlocalized": "ERROR",
                "source_file": "heapam.c",
                "source_function": "heap_lock_tuple",
                "source_line": "5074",
                "sqlstate": "55P03",
                "statement_position": null,
                "table_name": null,
                "text": "could not obtain lock on row in relation \"nowait_rows\""
              },
              "repair_marker": "repaired",
              "statuses": {
                "blocker_after_lock": "INTRANS",
                "blocker_after_release": "IDLE",
                "contender_after_nowait": "IDLE",
                "contender_after_repair": "IDLE"
              },
              "synchronization": "The blocker acquired SELECT FOR UPDATE before the contender issued SELECT FOR UPDATE NOWAIT; no timing sleep is used.",
              "table": "\"c55p03_nowait_row_lock\".\"nowait_rows\""
            },
            "schema": "c55p03_nowait_row_lock",
            "status": "passed"
          }
        ]
      }
    }
  ]
}
