↑↓ select↵ open⌫ change scopeOpen full search

PG.CENTER connects PostgreSQL documentation, reference, and ecosystem knowledge. Maintained by Pigsty.

Wiki / SQLSTATE

2201W — invalid_row_count_in_limit_clause

A LIMIT or FETCH row count fails a form-specific guard. Fixed paths report LIMIT must not be negative; the parser separately rejects a literal NULL row count in FETCH FIRST ... WITH TIES.

English manual coverage begins with PostgreSQL 8.1. Source history and runtime observations have their own recorded version boundaries.

Reading PG 18·Select a recorded version

aliases
Unknown
class name
Data Exception
condition name
invalid_row_count_in_limit_clause
lang
en
sqlstate
2201W

Definition PG 18

2201W

At a glance {#at-a-glance}

A LIMIT or FETCH row count fails a form-specific guard. Fixed paths report LIMIT must not be negative; the parser separately rejects a literal NULL row count in FETCH FIRST ... WITH TIES.

Representative messages {#messages}

The representative guards use these primary texts:

| Path | Primary | | --- | --- | | ordinary LIMIT with a negative count | LIMIT must not be negative | | literal NULL in FETCH FIRST ... WITH TIES | row count cannot be null in FETCH FIRST ... WITH TIES clause |

Meaning {#meaning}

The executor evaluates an ordinary LIMIT count: NULL is interpreted as no count (LIMIT ALL), zero is valid and returns no rows, and a negative value emits 2201W. The parser has a separate guard for an unadorned NULL constant in FETCH FIRST ... WITH TIES; it is not a blanket rule that every nullable LIMIT expression has the same behavior. OFFSET is handled by 2201X.

Diagnosis {#diagnosis}

Identify whether the message came from an ordinary LIMIT evaluation or the WITH TIES parser rule, then inspect the evaluated expression and its type. Keep NULL-without-ties, literal NULL-with-ties, zero, and negative values separate. A hidden expression can pass the parser’s narrow A_Const check, so classify the resulting behavior from the actual statement and message.

Response {#response}

For ordinary LIMIT, use a non-negative count or NULL when an unlimited result is intended. For WITH TIES, provide a non-NULL row count accepted by that syntax. If the negative-count or parser ERROR occurred inside an explicit transaction, roll back or roll back to the existing savepoint before retrying; autocommit can retry the corrected statement.

Versions {#versions}

The locked catalogue records this condition from 8.4.0; the fixed source paths here are PostgreSQL 18.6. No natural runtime observation is claimed for this page.

Related {#related}

2201X, 22012

Sources {#sources}

The executor NULL/zero/negative handling is in src/backend/executor/nodeLimit.c#L347-405, and the literal WITH TIES NULL guard is in src/backend/parser/parse_clause.c#L1890-1907. The structured evidence record retains both primary roles; no natural runtime was run.

Compare versions

SQLSTATE evidence and recorded runtime versions

claims · identity
{
  "claim_id": "identity",
  "limits": "",
  "method": "Read the fixed errcodes row and macro.",
  "position": 0,
  "runtime": [],
  "sources": [
    "src.errcodes.18.6"
  ],
  "statement": "2201W is invalid_row_count_in_limit_clause in SQLSTATE Class 22"
}
claims · resolved-path
{
  "claim_id": "resolved-path",
  "limits": "Source confirmation is not a natural runtime observation.",
  "method": "Read complete source contexts for the representative guards.",
  "position": 1,
  "runtime": [],
  "sources": [
    "src.nodeLimit.limit",
    "src.parse_clause.with_ties"
  ],
  "statement": "Fixed PostgreSQL 18.6 executor and parser paths distinguish ordinary LIMIT NULL/zero/negative values from the narrow literal NULL WITH TIES guard."
}
claims · history
{
  "claim_id": "history",
  "limits": "",
  "method": "Use catalogue presence and history boundaries.",
  "position": 2,
  "runtime": [],
  "sources": [
    "src.errcodes.18.6"
  ],
  "statement": "The locked catalogue records 2201W from 8.4.0 without proving an exact implementation introduction date."
}
messages · message.limit-negative
{
  "limits": "",
  "message_id": "message.limit-negative",
  "path": "",
  "position": 0,
  "raw": {
    "id": "message.limit-negative",
    "primary_template": "LIMIT must not be negative",
    "severity_source": "ERROR",
    "sources": [
      "src.nodeLimit.limit"
    ],
    "sqlstate": "2201W"
  },
  "severity": "ERROR",
  "sources": [
    "src.nodeLimit.limit"
  ],
  "templates": [
    {
      "kind": "primary",
      "literal": "LIMIT must not be negative",
      "position": 0,
      "role": "",
      "template": "LIMIT must not be negative"
    }
  ]
}
messages · message.with-ties-null
{
  "limits": "",
  "message_id": "message.with-ties-null",
  "path": "",
  "position": 1,
  "raw": {
    "id": "message.with-ties-null",
    "primary_template": "row count cannot be null in FETCH FIRST ... WITH TIES clause",
    "severity_source": "ERROR",
    "sources": [
      "src.parse_clause.with_ties"
    ],
    "sqlstate": "2201W"
  },
  "severity": "ERROR",
  "sources": [
    "src.parse_clause.with_ties"
  ],
  "templates": [
    {
      "kind": "primary",
      "literal": "row count cannot be null in FETCH FIRST ... WITH TIES clause",
      "position": 0,
      "role": "",
      "template": "row count cannot be null in FETCH FIRST ... WITH TIES clause"
    }
  ]
}
sources · src.errcodes.18.6
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/backend/utils/errcodes.txt",
  "position": 0,
  "sha256": "6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba",
  "source_id": "src.errcodes.18.6",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/errcodes.txt#L188"
}
sources · src.nodeLimit.limit
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/backend/executor/nodeLimit.c",
  "position": 1,
  "sha256": "f4c202d7182d66c6bef222fa50439831691dd99bfa5fd6b4de7f9142635dc305",
  "source_id": "src.nodeLimit.limit",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/executor/nodeLimit.c#L347"
}
sources · src.parse_clause.with_ties
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/backend/parser/parse_clause.c",
  "position": 2,
  "sha256": "fd3fb69d6ea2ed0c220eba1d4479c0b79d8713b39a28c62cc4bf1428491e8ebd",
  "source_id": "src.parse_clause.with_ties",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/parser/parse_clause.c#L1890"
}

Source references

Full definition and evidence JSON

Definition sources

center · PostgreSQL 18 · english-manuals:9d84276424ed0f558b65ebfa5004431a9daeb46776fb838831a06eb86e41ef68

Text language: en · english-manuals:9d84276424ed0f558b65ebfa5004431a9daeb46776fb838831a06eb86e41ef68